PODCAST: This extensive documentation outlines the NixOS operating system, providing a comprehensive guide for installation, including both graphical and manual methods, as well as instructions for virtualized environments. It details how to manage system services, covering aspects like networking configuration, user and group management, and file system setup, with specific instructions for various applications like PostgreSQL, Nextcloud, and GitLab. Furthermore, the text explains developer tools and the testing framework, emphasizing the declarative nature of NixOS for building and upgrading systems, while also offering guidance on troubleshooting and contributing to the manual itself.

NixOS offers two distinct approaches for managing containers: declarative container management and imperative container management. These methods differ primarily in how containers are defined, updated, and integrated with the host system.
Here’s a breakdown of each approach and their differences:
1. Imperative Container Management
- Method: This approach uses the
nixos-container
command-line utility. - Creation and Management: Containers are created with
nixos-container create <name>
and can be started, stopped, updated, and destroyed using commands likenixos-container start <name>
,nixos-container update <name>
, andnixos-container destroy <name>
. - Configuration:
- When created, an imperative container gets its root directory in
/var/lib/nixos-containers/<name>
and a configuration file in/etc/nixos-containers/<name>.conf
. - Its initial system configuration is stored at
/nix/var/nix/profiles/per-container/<name>/system
. - Configuration changes can be made by editing
/var/lib/nixos-containers/foo/etc/nixos/configuration.nix
on the host and then runningnixos-container update foo
. - Alternatively, a new configuration can be specified directly on the command line, which will overwrite the container’s
configuration.nix
. - Configuration changes can also be made from within the container using
nixos-rebuild switch
(afternix-channel --update
).
- When created, an imperative container gets its root directory in
- Networking: Imperative containers by default get their own private IPv4 address in the range 10.233.0.0/16. They operate within their own network namespace and possess the
CAP_NET_ADMIN
capability, allowing them to configure network settings (like firewall rules) without affecting the host’s network. To enable outside network access, Network Address Translation (NAT) rules must be set up on the host. - Login and Execution: You can log in as root using
nixos-container root-login <name>
(host root access required) or get a regular login prompt withnixos-container login <name>
. Arbitrary commands can be executed inside the container usingnixos-container run <name> -- <command>
.
2. Declarative Container Management
- Method: Containers are defined directly within the host’s
configuration.nix
file. - Creation and Management: When
nixos-rebuild switch
is run on the host, the container is built. If it’s already running, it’s updated in place without a reboot. Containers can be configured to start automatically by settingcontainers.<name>.autoStart = true
. They are started and stopped via their corresponding systemd service, e.g.,systemctl start container@<name>
. - Configuration: The container’s configuration is specified as a Nix expression directly within the host’s
configuration.nix
. - Networking: By default, declarative containers share the network namespace of the host, allowing them to listen on (privileged) ports, but they cannot change the network configuration. They can be given their own private network by setting
privateNetwork = true
, along withhostAddress
andlocalAddress
.
Key Differences Summarized:
- Configuration Location:
- Imperative: Managed by individual configuration files (
/etc/nixos-containers/<name>.conf
) and directories (/var/lib/nixos-containers/<name>
) on the host. - Declarative: Defined directly within the host’s central
configuration.nix
file.
- Imperative: Managed by individual configuration files (
- Update Mechanism:
- Imperative: Containers are configured and updated independently from the host system using
nixos-container update
ornixos-rebuild switch
from within the container. - Declarative: Containers are upgraded along with the host system when
nixos-rebuild
is run.
- Imperative: Containers are configured and updated independently from the host system using
- Network Isolation (Default):
- Imperative: By default, imperative containers receive a private IPv4 address and have their own network namespace, allowing them to perform arbitrary network configurations.
- Declarative: By default, declarative containers share the host’s network namespace, meaning they don’t have independent network configuration capabilities.
Important Note: NixOS containers are not perfectly isolated from the host system. A user with root access inside a container can affect the host, so it is advised not to grant container root access to untrusted users.