Run NixOS configurations inside Docker containers with full systemd support. This project enables you to use NixOS module system and declarative configuration for containerized applications.
- Multi-architecture support: Built for both
amd64andarm64platforms - Full systemd support: Run systemd-based services inside containers
- Declarative configuration: Use NixOS modules to define your container
- Flake support: Load configurations from Nix flakes
- Reproducible builds: Leverage Nix's reproducibility for consistent containers
Create a NixOS configuration file:
# nginx.nix
{ lib, ... }:
{
services.nginx.enable = true;
services.nginx.virtualHosts."127.0.0.1" = {
root = "/web";
};
networking = {
useHostResolvConf = lib.mkForce false;
};
}Run it with Docker Compose:
services:
nginx:
image: ghcr.io/skiffos/docker-nixos:latest
volumes:
- type: tmpfs
target: /run
- /sys/fs/cgroup:/sys/fs/cgroup:rw
- ./nginx.nix:/config/configuration.nix
- ./web:/web
ports:
- "80:80"
cgroup: hostdocker run -d \
--name nixos-nginx \
--tmpfs /run \
-v /sys/fs/cgroup:/sys/fs/cgroup:rw \
-v $(pwd)/nginx.nix:/config/configuration.nix \
-v $(pwd)/web:/web \
-p 80:80 \
--cgroupns=host \
ghcr.io/skiffos/docker-nixos:latestFor more complex configurations, you can use Nix flakes instead of a single configuration.nix file.
Create an options.nix file:
{
flakeUrl = "github:MyUser/myflake/main";
nixosConfiguration = "myConfigurationName";
}Create your flake:
# flake.nix
{
description = "My containerized NixOS configuration";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
};
outputs = { self, nixpkgs, ... }: {
nixosConfigurations.myConfigurationName = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
./configuration.nix
];
};
};
}Mount the options.nix file in your container:
services:
myapp:
image: ghcr.io/skiffos/docker-nixos:latest
volumes:
- type: tmpfs
target: /run
- /sys/fs/cgroup:/sys/fs/cgroup:rw
- ./options.nix:/options.nix
cgroup: host{ lib, pkgs, ... }:
{
services.postgresql = {
enable = true;
package = pkgs.postgresql_15;
enableTCPIP = true;
authentication = ''
host all all 0.0.0.0/0 md5
'';
};
networking.useHostResolvConf = lib.mkForce false;
}{ lib, ... }:
{
services.redis.servers."" = {
enable = true;
bind = "0.0.0.0";
};
networking.useHostResolvConf = lib.mkForce false;
}- Docker with cgroup v2 support
- Linux kernel (tested on recent versions)
The container requires:
/runmounted as tmpfs/sys/fs/cgroupmounted from host with read-write access--cgroupns=hostorcgroup: hostin Docker Compose
These requirements are necessary for running systemd inside the container.
- Build Stage: The Dockerfile builds NixOS from source in an Ubuntu container, compiling Nix and all dependencies
- Runtime Stage: A minimal
FROM scratchimage contains only the built NixOS system - Configuration: On container startup, the provided
configuration.nixor flake is evaluated and built - Init: systemd (
/init) starts and manages services according to your configuration
- Build time: When the container first starts, it builds the provided configuration. This can take several minutes and logs are not forwarded to stdout
- systemd requirement: Some NixOS modules may not work correctly in a containerized systemd environment
- cgroup dependency: Must run with host cgroups mounted
- Platform support: Built for Linux only (amd64 and arm64). Windows and macOS hosts require Docker Desktop with WSL2/virtualization
Clone the repository and build:
git clone https://github.com/skiffos/docker-nixos.git
cd docker-nixos
docker build -t docker-nixos .Multi-platform builds are configured via GitHub Actions and can be triggered on push to the main branch.
Contributions are welcome! Please feel free to submit issues or pull requests.
MIT License - see LICENSE file for details.