1 # Systemd services for docker.
3 { config, lib, pkgs, ... }:
9 cfg = config.virtualisation.docker;
10 proxy_env = config.networking.proxy.envVars;
11 settingsFormat = pkgs.formats.json {};
12 daemonSettingsFile = settingsFormat.generate "daemon.json" cfg.daemon.settings;
18 options.virtualisation.docker = {
24 This option enables docker, a daemon that manages
25 linux containers. Users in the "docker" group can interact with
26 the daemon (e.g. to start or stop containers) using the
27 {command}`docker` command line tool.
33 type = types.listOf types.str;
34 default = ["/run/docker.sock"];
36 A list of unix and tcp docker should listen to. The format follows
37 ListenStream as described in systemd.socket(5).
46 When enabled dockerd is started on boot. This is required for
47 containers which are created with the
48 `--restart=always` flag to work. If this option is
49 disabled, docker might be started on demand by socket activation.
55 type = types.submodule {
56 freeformType = settingsFormat.type;
58 live-restore = mkOption {
60 # Prior to NixOS 24.11, this was set to true by default, while upstream defaulted to false.
61 # Keep the option unset to follow upstream defaults
62 default = versionOlder config.system.stateVersion "24.11";
63 defaultText = literalExpression "lib.versionOlder config.system.stateVersion \"24.11\"";
65 Allow dockerd to be restarted without affecting running container.
66 This option is incompatible with docker swarm.
74 "live-restore" = true;
75 "fixed-cidr-v6" = "fd00::/80";
78 Configuration for docker daemon. The attributes are serialized to JSON used as daemon.conf.
79 See https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
88 **Deprecated**, please use hardware.nvidia-container-toolkit.enable instead.
90 Enable nvidia-docker wrapper, supporting NVIDIA GPUs inside docker containers.
96 type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]);
99 This option determines which Docker
100 [storage driver](https://docs.docker.com/storage/storagedriver/select-storage-driver/)
102 By default it lets docker automatically choose the preferred storage
104 However, it is recommended to specify a storage driver explicitly, as
105 docker's default varies over versions.
108 Changing the storage driver will cause any existing containers
109 and images to become inaccessible.
116 type = types.enum ["none" "json-file" "syslog" "journald" "gelf" "fluentd" "awslogs" "splunk" "etwlogs" "gcplogs" "local"];
117 default = "journald";
119 This option determines which Docker log driver to use.
125 type = types.separatedString " ";
128 The extra command-line options to pass to
129 {command}`docker` daemon.
138 Whether to periodically prune Docker resources. If enabled, a
139 systemd timer will run `docker system prune -f`
140 as specified by the `dates` option.
145 type = types.listOf types.str;
147 example = [ "--all" ];
149 Any additional flags passed to {command}`docker system prune`.
157 Specification (in the format described by
158 {manpage}`systemd.time(7)`) of the time at
159 which the prune will occur.
164 package = mkPackageOption pkgs "docker" { };
166 extraPackages = mkOption {
167 type = types.listOf types.package;
169 example = literalExpression "with pkgs; [ criu ]";
171 Extra packages to add to PATH for the docker daemon process.
177 (mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed and socket activation is now always active")
178 (mkAliasOptionModule ["virtualisation" "docker" "liveRestore"] ["virtualisation" "docker" "daemon" "settings" "live-restore"])
181 ###### implementation
183 config = mkIf cfg.enable (mkMerge [{
184 boot.kernelModules = [ "bridge" "veth" "br_netfilter" "xt_nat" ];
185 boot.kernel.sysctl = {
186 "net.ipv4.conf.all.forwarding" = mkOverride 98 true;
187 "net.ipv4.conf.default.forwarding" = mkOverride 98 true;
189 environment.systemPackages = [ cfg.package ]
190 ++ optional cfg.enableNvidia pkgs.nvidia-docker;
191 users.groups.docker.gid = config.ids.gids.docker;
192 systemd.packages = [ cfg.package ];
194 # Docker 25.0.0 supports CDI by default
195 # (https://docs.docker.com/engine/release-notes/25.0/#new). Encourage
196 # moving to CDI as opposed to having deprecated runtime
198 warnings = lib.optionals (cfg.enableNvidia && (lib.strings.versionAtLeast cfg.package.version "25")) [
200 You have set virtualisation.docker.enableNvidia. This option is deprecated, please set hardware.nvidia-container-toolkit.enable instead.
204 systemd.services.docker = {
205 wantedBy = optional cfg.enableOnBoot "multi-user.target";
206 after = [ "network.target" "docker.socket" ];
207 requires = [ "docker.socket" ];
208 environment = proxy_env;
214 ${cfg.package}/bin/dockerd \
215 --config-file=${daemonSettingsFile} \
220 "${pkgs.procps}/bin/kill -s HUP $MAINPID"
224 path = [ pkgs.kmod ] ++ optional (cfg.storageDriver == "zfs") pkgs.zfs
225 ++ optional cfg.enableNvidia pkgs.nvidia-docker
226 ++ cfg.extraPackages;
229 systemd.sockets.docker = {
230 description = "Docker Socket for the API";
231 wantedBy = [ "sockets.target" ];
233 ListenStream = cfg.listenOptions;
236 SocketGroup = "docker";
240 systemd.services.docker-prune = {
241 description = "Prune docker resources";
243 restartIfChanged = false;
244 unitConfig.X-StopOnRemoval = false;
246 serviceConfig.Type = "oneshot";
249 ${cfg.package}/bin/docker system prune -f ${toString cfg.autoPrune.flags}
252 startAt = optional cfg.autoPrune.enable cfg.autoPrune.dates;
253 after = [ "docker.service" ];
254 requires = [ "docker.service" ];
258 { assertion = cfg.enableNvidia && pkgs.stdenv.hostPlatform.isx86_64 -> config.hardware.graphics.enable32Bit or false;
259 message = "Option enableNvidia on x86_64 requires 32-bit support libraries";
262 virtualisation.docker.daemon.settings = {
265 log-driver = mkDefault cfg.logDriver;
266 storage-driver = mkIf (cfg.storageDriver != null) (mkDefault cfg.storageDriver);
267 runtimes = mkIf cfg.enableNvidia {
269 # Use the legacy nvidia-container-runtime wrapper to allow
270 # the `--runtime=nvidia` approach to expose
271 # GPU's. Starting with Docker > 25, CDI can be used
272 # instead, removing the need for runtime wrappers.
273 path = lib.getExe' pkgs.nvidia-docker "nvidia-container-runtime.legacy";