Replacing the bootStage2

I’m trying to create a Linux Container (LXC) that starts up, performs a task, and then immediately shuts itself down.

This is already working fairly nicely with nixos-generators and the configuration at:

However, systemd seems rather overkill here. It seems neater if I could overwrite system.build.bootStage2 myself, do just the minimal initialization needed for the script (enabling networking), performing the task and shutting down again.

Naively setting system.build.bootStage2 in configuration.nix doesn’t seem to work, though. Is this possible? How would I do it?

This sounds like a case for not using NixOS: NixOS is quite tightly coupled with systemd, but you can make your container’s store contain just your init script and replace nixos with it, something like

{ nixpkgs ? <nixpkgs> }:
let
  pkgs = import nixpkgs {}; 
  initScript = pkgs.writeScript "init" ''
    ${pkgs.dhcp}/bin/dhclient -v eth0
    exec ${mastodon-bot-hack42}/bin/mastodon-bot # or some lightweight service manager
  '';
in import (nixpkgs + "/nixos/lib/make-system-tarball.nix") {
  contents = [
    { source = initScript; target = "/init"; }
  ];
  extraArgs = "--owner=0";
  extraCommands = "mkdir -p proc sys dev";
}

That will get you a tarball containing a symlink at /init to the init script defined there (the make-system-tarball part of this is mostly copied from the lxc generator itself at https://github.com/nix-community/nixos-generators/blob/229d236d4de23d1cea77f1ebfdaa223f7ca74c27/formats/lxc.nix).

1 Like

Thanks for that, I’ll be sure to look into that further!

Do you mean “using Nix but not NixOS”? That indeed perhaps could be interesting. I wouldn’t want to give up Nix - right now even if it means pulling in systemd it’s worth it IMHO :smiley: .

1 Like

Yes, exactly — Nix without NixOS :slight_smile: systemd will probably be pulled in as a dependency because the dhcp client will (maybe transitively) depend on udev or whatever, but you can avoid running it as PID1 in this way.

1 Like