Nixos-container update --flake fails

I’ve tried to create a minimal nixos-container flake file to test out some things:

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";

  outputs = { self, nixpkgs }: {

    nixosConfigurations.container = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        {
          services.nginx.enable = true;

          system.configurationRevision = nixpkgs.lib.mkIf (self ? rev) self.rev;

          system.stateVersion = "22.11";

          boot.isContainer = true;
          networking.useDHCP = false;
          networking.firewall.allowedTCPPorts = [ 80 ];
          networking.hostName = "nginx";
        }
      ];
    };

  };
}

It’s sole purpose is to start nginx.

Things work fine with sudo nixos-container create nginx --flake .#container and sudo nixos-container start nginx, but when I try sudo nixos-container update nginx --flake .#container, I get the following error:

reloading container...
Job for container@nginx.service failed.
See "systemctl status container@nginx.service" and "journalctl -xeu container@nginx.service" for details.
/run/current-system/sw/bin/nixos-container: failed to reload container

The output from journalctl is a bit more helpful:

Aug 04 09:36:49 church systemd[1]: Reloading Container 'nginx'...
Aug 04 09:36:49 church container nginx[114190]: /nix/store/idgaxv0lwc2xiqcidz653ir05mh3sima-nixos-container/bin/nixos-container: container ‘nginx’ does not exist
Aug 04 09:36:49 church systemd[1]: container@nginx.service: Control process exited, code=exited, status=2/INVALIDARGUMENT
Aug 04 09:36:49 church systemd[1]: Reload failed for Container 'nginx'.

Does anyone know what I have to do to fix this error?

Instead of running nixos-container update, I can reproduce the error by just running sudo systemctl reload container@nginx.service.

It seems like there are two different nixos-container’s in play here. When I run sudo nixos-container list I see the nginx container, but if I run sudo /nix/store/idgaxv0lwc2xiqcidz653ir05mh3sima-nixos-container/bin/nixos-container list there is nothing. readlink $(which nixos-container) confirms my suspicion by reporting /nix/store/9agb0q7mxy2fz3ng5nq3f60668zilal4-nixos-container/bin/nixos-container.

So I guess the question is, why does systemctl use a different nixos-container, and why do they not share the list of containers?

Apparently, those to nixos-container binaries expect the container configurations to reside in different places: /etc/containers vs. /etc/nixos-containers. Why? And why does the installed systemctl service file use a different nixos-containers?

Declarative containers (the ones specified in your NixOS configurations) switched over to /etc/nixos-containers to improve compatibility with OCI containers as of system.stateVersion = 22.05.

If you upgraded from 21.11 or older, and did not bump your stateVersion, the globally installed nixos-container would still refer to /etc/containers, due to:

and

however the systemd units refer to bare pkgs.nixos-container, independent of stateVersion (and as such, using the new default /etc/nixos-containers:

I am not sure whether this is a bug in Nixpkgs - at the first look, I would expect both of those to use the same nixos-container, but maybe there’s something I’m missing. You could try filing an issue.

1 Like

Thank you for your reply! I also figured that might be the issue. I submitted an issue here and I believe I identified a bug in nixpkgs which I’ve attempted to fix here.

Regarding manually changing the stateVersion, I was under the impression that that is not generally considered safe?

It’s not, but that’s a rule of thumb. All stateVersion is is a number to check against if a module wants to make a potentially backwards-incompatible change.

E.g., want to change the runtime directory of your service? Gate it behind stateVersion so your users’ data doesn’t disappear from underneath them.

Those backwards-compatibility checks probably will disappear over time, and then show up in the NixOS release notes as breaking changes. The gating is mostly so they trickle through a little less rapidly, especially for those who follow unstable.

You can manually update that value, as long as you make sure you’re aware of all these tiny checks and know what their effects will be. This is nontrivial, so it’s best avoided, but in a cinch you can still do so.

2 Likes

Thank you for the explanation.