With this project you can
- make your image composable (thanks to the NixOS modules system)
- integrate the s6 init system in your images
- reuse some NixOS modules in a container... without relying on systemd
- make a Nix a Docker image, built by Nix
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, addoverlay.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
- Proper PID 1 (no zombie processes)
- Run several services in one container
- Processes debugging (if the process is killed or died, the container is not necessarily killed)
- Execute initialization tasks
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;
};
})
- nix: basic single user installation
These images can be built with nix-build -A dockerImages
.
More configurations and images are also available in the tests directory.
The image
module defines common Docker image attributes, such as the
image name, the environment variables, etc. Please refer to
the image
options documentation.
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 terminates. They can be ordered thanks to theafter
option.long-run
services are for daemons and are managed bys6
. There is no dependencies notion on long run services.oneshot-post
services are executed sequentially once all long run services have been started. They can also be order (after
option). They are generally used to do 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 interactively a failing service.
users
: create users and groupsnix
: configure Nixenvironment.etc
: create files in/etc
systemd
: a small subset of the systemd module is implemented with s6nginx
: see its test.
Important: only a small subset of NixOS modules is supported. See the tests directory for supported (and tested) features.
- s6: s6 tests executed in the Nix build environment (fast to run but limited)
- dockerImages: tests on Docker images executed in a NixOS VM.
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:
- Services of type
simple
becomelong-run
s6 services and dependencies are ignored - Services of type
oneshot
becomeonehost-pre
s6 services except if they have anafter
dependency to asimple
service. In this case, they becomeoneshot-post
. Dependencies between oneshot services are respected.
- To generate and run the container init script as user
nix-build -A dockerImages.example-systemd.init ./result S6-STATE-DIR
- To get the image used by a test
nix-build -A tests.dockerImages.nginx.image
- The NixOS config of an image
nix-instantiate --eval -A tests.dockerImages.nginx.image.config
- The NixOS config of an s6 test
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.