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 = {
25 This option enables docker, a daemon that manages
26 linux containers. Users in the "docker" group can interact with
27 the daemon (e.g. to start or stop containers) using the
28 {command}`docker` command line tool.
34 type = types.listOf types.str;
35 default = ["/run/docker.sock"];
38 A list of unix and tcp docker should listen to. The format follows
39 ListenStream as described in systemd.socket(5).
49 When enabled dockerd is started on boot. This is required for
50 containers which are created with the
51 `--restart=always` flag to work. If this option is
52 disabled, docker might be started on demand by socket activation.
58 type = settingsFormat.type;
62 "fixed-cidr-v6" = "fd00::/80";
64 description = lib.mdDoc ''
65 Configuration for docker daemon. The attributes are serialized to JSON used as daemon.conf.
66 See https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
74 description = lib.mdDoc ''
75 Enable nvidia-docker wrapper, supporting NVIDIA GPUs inside docker containers.
85 Allow dockerd to be restarted without affecting running container.
86 This option is incompatible with docker swarm.
92 type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]);
96 This option determines which Docker storage driver to use. By default
97 it let's docker automatically choose preferred storage driver.
103 type = types.enum ["none" "json-file" "syslog" "journald" "gelf" "fluentd" "awslogs" "splunk" "etwlogs" "gcplogs" "local"];
104 default = "journald";
107 This option determines which Docker log driver to use.
113 type = types.separatedString " ";
117 The extra command-line options to pass to
118 {command}`docker` daemon.
126 description = lib.mdDoc ''
127 Whether to periodically prune Docker resources. If enabled, a
128 systemd timer will run `docker system prune -f`
129 as specified by the `dates` option.
134 type = types.listOf types.str;
136 example = [ "--all" ];
137 description = lib.mdDoc ''
138 Any additional flags passed to {command}`docker system prune`.
145 description = lib.mdDoc ''
146 Specification (in the format described by
147 {manpage}`systemd.time(7)`) of the time at
148 which the prune will occur.
154 default = pkgs.docker;
155 defaultText = literalExpression "pkgs.docker";
156 type = types.package;
157 description = lib.mdDoc ''
158 Docker package to be used in the module.
162 extraPackages = mkOption {
163 type = types.listOf types.package;
165 example = literalExpression "with pkgs; [ criu ]";
166 description = lib.mdDoc ''
167 Extra packages to add to PATH for the docker daemon process.
172 ###### implementation
174 config = mkIf cfg.enable (mkMerge [{
175 boot.kernelModules = [ "bridge" "veth" "br_netfilter" "xt_nat" ];
176 boot.kernel.sysctl = {
177 "net.ipv4.conf.all.forwarding" = mkOverride 98 true;
178 "net.ipv4.conf.default.forwarding" = mkOverride 98 true;
180 environment.systemPackages = [ cfg.package ]
181 ++ optional cfg.enableNvidia pkgs.nvidia-docker;
182 users.groups.docker.gid = config.ids.gids.docker;
183 systemd.packages = [ cfg.package ];
185 systemd.services.docker = {
186 wantedBy = optional cfg.enableOnBoot "multi-user.target";
187 after = [ "network.target" "docker.socket" ];
188 requires = [ "docker.socket" ];
189 environment = proxy_env;
195 ${cfg.package}/bin/dockerd \
196 --config-file=${daemonSettingsFile} \
201 "${pkgs.procps}/bin/kill -s HUP $MAINPID"
205 path = [ pkgs.kmod ] ++ optional (cfg.storageDriver == "zfs") pkgs.zfs
206 ++ optional cfg.enableNvidia pkgs.nvidia-docker
207 ++ cfg.extraPackages;
210 systemd.sockets.docker = {
211 description = "Docker Socket for the API";
212 wantedBy = [ "sockets.target" ];
214 ListenStream = cfg.listenOptions;
217 SocketGroup = "docker";
221 systemd.services.docker-prune = {
222 description = "Prune docker resources";
224 restartIfChanged = false;
225 unitConfig.X-StopOnRemoval = false;
227 serviceConfig.Type = "oneshot";
230 ${cfg.package}/bin/docker system prune -f ${toString cfg.autoPrune.flags}
233 startAt = optional cfg.autoPrune.enable cfg.autoPrune.dates;
234 after = [ "docker.service" ];
235 requires = [ "docker.service" ];
239 { assertion = cfg.enableNvidia && pkgs.stdenv.isx86_64 -> config.hardware.opengl.driSupport32Bit or false;
240 message = "Option enableNvidia on x86_64 requires 32bit support libraries";
243 virtualisation.docker.daemon.settings = {
246 log-driver = mkDefault cfg.logDriver;
247 storage-driver = mkIf (cfg.storageDriver != null) (mkDefault cfg.storageDriver);
248 live-restore = mkDefault cfg.liveRestore;
249 runtimes = mkIf cfg.enableNvidia {
251 path = "${pkgs.nvidia-docker}/bin/nvidia-container-runtime";
259 (mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed and socket activation is now always active")