NixOS on exe.dev
exe.dev can boot a NixOS VM from a Docker image. Build NixOS as a container image and set its CMD to the system's init. exe.dev starts it as PID 1 and NixOS brings up systemd. You don't need an SSH server in the image because exe.dev provides one.
The NixOS module:
# exe.dev provides the kernel.
boot.isContainer = true;
# The kernel's ip= argument already configures eth0.
networking.useDHCP = false;
# exe-init sets the hostname from the kernel's ip= argument.
networking.hostName = "";
# exe.dev's DNS resolver.
networking.nameservers = [ "169.254.169.254" ];
# exe.dev runs its own sshd on port 22.
services.openssh.enable = false;
# console=hvc0 makes systemd wait for a getty on a device that never
# appears without udev, so boot stays in "starting" forever.
systemd.units."serial-getty@hvc0.service".enable = false;
# The user exe.dev's sshd logs in as, named by the image's
# exe.dev/login-user label.
users.users.exedev = {
isNormalUser = true;
uid = 1000;
extraGroups = [ "wheel" ];
};
# Passwordless sudo for that user, as on exe.dev's default image.
security.sudo.wheelNeedsPassword = false;
Pack it with dockerTools.streamLayeredImage like so:
# The NixOS system built from the module above.
toplevel = nixos.config.system.build.toplevel;
# A Docker image holding the system. Booting it runs NixOS's init, which
# sets up /etc and starts systemd.
image = pkgs.dockerTools.streamLayeredImage {
name = "nixos";
tag = "latest";
config = {
Cmd = [ "${toplevel}/init" ];
# The user exe.dev's SSH logs you in as.
Labels."exe.dev/login-user" = "exedev";
};
};
To keep the image private, run a registry on another VM as in
https://hub.exe.dev/docs/private-image#run-a-registry-on-an-exedev-vm.
To push a Nix-built image from your own machine, tunnel to that registry:
ssh -f -N -L 15000:localhost:8000 myregistry.exe.xyz
nix build .#image && ./result > image.tar
skopeo copy --dest-tls-verify=false docker-archive:image.tar docker://localhost:15000/nixos:v1
ssh exe.dev new --name=mynixos --image=myregistry.exe.xyz/nixos:v1
One gotcha: exe.dev's sshd runs its own /exe.dev/bin/sh, not the login
shell from /etc/passwd. Interactive logins get the NixOS PATH;
ssh vm cmd does not. Run commands through a login shell instead:
ssh mynixos.exe.xyz '/run/current-system/sw/bin/bash -lc "systemctl status"'
0 Comments
No comments yet.