#+TITLE: NixOS modules in OCI container * Idea Nix makes it easy to build small oci containers (docker/podman) using its package set, which will contain nothing that isn't absolutely necessary. However, this only applies to packages, not the NixOS module system that is usually used to generate config files from the Nix language, which are then wrapped into systemd module files. Unfortunately, systemd cannot run in docker (and would present a lot of unnecessary overhead). This is an experiment at redefining the NixOS module responsible for generating the systemd unit files to generate simple shell scripts that can serve as an entrypoint for the OCI containers instead that run the same services as they would on NixOS. * Running There's an example running a grafana server in ~example.nix~. Build it with: #+begin_src sh docker load < $(nix-build example.nix) #+end_src Then run the image name that docker prints out: #+begin_src sh docker run -p 3000:3000 -t grafana:ib6aahrmhqbzk444b8nq384zrg86fzdm #+end_src The full image is about 66MB, compared to 204MB for the official ~grafana/grafana~ image. To use this with other modules than grafana, you will have to import them manually (and hope that these work). A list of all modules can be found in ~nixpkgs/nixos/modules/module-list.nix~. * Caveats Currently there is only support for: - systemd.services - users.users..home - assertions Everything that cannot be reduced to just these will fail on build, and some of the things that do may still fail at runtime, since even the majority of these suboptions will be ignored / have different semantics than they usually do. * Still Todo: - [ ] safe shutdown: currently, containers will have to be killed and ignore ~docker stop~ - [ ] handle systemd tmpdirs - [ ] make the images multi-layered: one layer for base packages, one for config files (to avoid redefining the entire container for each config change)