Write container images as NixOS machines
warning: this project is no longer maintained
With this project you can
To build a Docker image named hello
that runs hello
.
lib.makeImage (
{ pkgs, ... }: {
config.image = {
name = "hello";
entryPoint = [ "${pkgs.hello}/bin/hello" ];
};
})
To build an empty image from CLI,
nix-build -E 'with import ./default.nix{}; lib.makeImage{ config.image.name = "empty"; }'
To use lib.makeImage
in your project, add overlay.nix
to your
nixpkgs overlay list.
The image
module section for more information.
The s6 module can be used to build an image with an init
system. The s6 init system is
used to run defined s6.services
.
lib.makeImage ({ pkgs, ... }: {
config = {
image.name = "s6";
s6.services.nginx = {
execStart = ''${pkgs.nginx}/bin/nginx -g "daemon off;"'';
};
};
})
Some goals of using an init system in a container are
See s6 module for details.
Some NixOS modules can be used, such as users
, etc
.
lib.makeImage ({ pkgs, ... }: {
config = {
image.name = "nixos";
environment.systemPackages = [ pkgs.coreutils ];
users.users.alice = {
isNormalUser = true;
};
};
})
See also supported NixOS modules.
It is possible to run some NixOS modules defining systemd services thanks to a partial systemd implementation with s6.
Note this implementation is fragile, experimental and partial!
lib.makeImage ({ pkgs, ... }: {
config = {
image.name = "nginx";
# Yeah! It is the NixOS module!
services.nginx.enable = true;
};
})
These images can be built with nix-build -A dockerImages
.
More configurations and images are also available in the tests directory.
image
The image
module defines common Docker image attributes, such as the
image name, the environment variables, etc. Please refer to
the image
options documentation.
s6
This module allows you to easily create services, managed by the s6 init system. Three types of services can be defined:
oneshot-pre
services are exectued sequentially at container start
time and must terminate. They can be ordered thanks to the after
option.long-run
services are for daemons and are managed by s6
. There
is no notion of dependency for long-run
services.oneshot-post
services are executed sequentially once all long-run
services have been started. They can also be ordered (after
option). They are generally used to provision started services.Options are described in this
generated s6
options documentation.
By default, if a s6 service fails, the s6-svcscan
(PID 1 in a
container) process is terminated. A long-run
service can set the
restartOnFailure
option to true
to restart the service when it
fails.
If the S6_DONT_TERMINATE_ON_ERROR
environment variable is set,
s6-svscan
is not terminated on service failure. This can be used to
debug a failing service interactively.
users
: create users and groupsnix
: configure Nixenvironment.etc
: create files in /etc
systemd
: a small subset of the systemd module is implemented with s6
nginx
: see its test
Important: only a small subset of NixOS modules is supported. See the tests directory for supported (and tested) features.
A subset of the NixOS systemd services interface is supported and implemented with the s6 init system.
There are several differences with the NixOS systemd implementation. The main one is the service dependency model:
simple
become long-run
s6 services and dependencies are ignored.oneshot
become onehost-pre
s6 services except
if they have an after
dependency to a simple
service. In this
case, they become oneshot-post
. Dependencies between oneshot
services are respected.nix-build -A dockerImages.example-systemd.init
./result S6-STATE-DIR
nix-build -A tests.dockerImages.nginx.image
nix-instantiate --eval -A tests.dockerImages.nginx.image.config
nix-instantiate --eval -A tests.s6.path.config.systemd
Contributions to nix-container-images through PRs are always welcome. All PRs will be automatically tested by the Hydra CI server.