at 22.05-pre 6.8 kB view raw
1# Systemd services for docker. 2 3{ config, lib, pkgs, ... }: 4 5with lib; 6 7let 8 9 cfg = config.virtualisation.docker; 10 proxy_env = config.networking.proxy.envVars; 11 12in 13 14{ 15 ###### interface 16 17 options.virtualisation.docker = { 18 enable = 19 mkOption { 20 type = types.bool; 21 default = false; 22 description = 23 '' 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> command line tool. 28 ''; 29 }; 30 31 listenOptions = 32 mkOption { 33 type = types.listOf types.str; 34 default = ["/run/docker.sock"]; 35 description = 36 '' 37 A list of unix and tcp docker should listen to. The format follows 38 ListenStream as described in systemd.socket(5). 39 ''; 40 }; 41 42 enableOnBoot = 43 mkOption { 44 type = types.bool; 45 default = true; 46 description = 47 '' 48 When enabled dockerd is started on boot. This is required for 49 containers which are created with the 50 <literal>--restart=always</literal> flag to work. If this option is 51 disabled, docker might be started on demand by socket activation. 52 ''; 53 }; 54 55 enableNvidia = 56 mkOption { 57 type = types.bool; 58 default = false; 59 description = '' 60 Enable nvidia-docker wrapper, supporting NVIDIA GPUs inside docker containers. 61 ''; 62 }; 63 64 liveRestore = 65 mkOption { 66 type = types.bool; 67 default = true; 68 description = 69 '' 70 Allow dockerd to be restarted without affecting running container. 71 This option is incompatible with docker swarm. 72 ''; 73 }; 74 75 storageDriver = 76 mkOption { 77 type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]); 78 default = null; 79 description = 80 '' 81 This option determines which Docker storage driver to use. By default 82 it let's docker automatically choose preferred storage driver. 83 ''; 84 }; 85 86 logDriver = 87 mkOption { 88 type = types.enum ["none" "json-file" "syslog" "journald" "gelf" "fluentd" "awslogs" "splunk" "etwlogs" "gcplogs"]; 89 default = "journald"; 90 description = 91 '' 92 This option determines which Docker log driver to use. 93 ''; 94 }; 95 96 extraOptions = 97 mkOption { 98 type = types.separatedString " "; 99 default = ""; 100 description = 101 '' 102 The extra command-line options to pass to 103 <command>docker</command> daemon. 104 ''; 105 }; 106 107 autoPrune = { 108 enable = mkOption { 109 type = types.bool; 110 default = false; 111 description = '' 112 Whether to periodically prune Docker resources. If enabled, a 113 systemd timer will run <literal>docker system prune -f</literal> 114 as specified by the <literal>dates</literal> option. 115 ''; 116 }; 117 118 flags = mkOption { 119 type = types.listOf types.str; 120 default = []; 121 example = [ "--all" ]; 122 description = '' 123 Any additional flags passed to <command>docker system prune</command>. 124 ''; 125 }; 126 127 dates = mkOption { 128 default = "weekly"; 129 type = types.str; 130 description = '' 131 Specification (in the format described by 132 <citerefentry><refentrytitle>systemd.time</refentrytitle> 133 <manvolnum>7</manvolnum></citerefentry>) of the time at 134 which the prune will occur. 135 ''; 136 }; 137 }; 138 139 package = mkOption { 140 default = pkgs.docker; 141 defaultText = literalExpression "pkgs.docker"; 142 type = types.package; 143 example = literalExpression "pkgs.docker-edge"; 144 description = '' 145 Docker package to be used in the module. 146 ''; 147 }; 148 }; 149 150 ###### implementation 151 152 config = mkIf cfg.enable (mkMerge [{ 153 boot.kernelModules = [ "bridge" "veth" ]; 154 boot.kernel.sysctl = { 155 "net.ipv4.conf.all.forwarding" = mkOverride 98 true; 156 "net.ipv4.conf.default.forwarding" = mkOverride 98 true; 157 }; 158 environment.systemPackages = [ cfg.package ] 159 ++ optional cfg.enableNvidia pkgs.nvidia-docker; 160 users.groups.docker.gid = config.ids.gids.docker; 161 systemd.packages = [ cfg.package ]; 162 163 systemd.services.docker = { 164 wantedBy = optional cfg.enableOnBoot "multi-user.target"; 165 after = [ "network.target" "docker.socket" ]; 166 requires = [ "docker.socket" ]; 167 environment = proxy_env; 168 serviceConfig = { 169 Type = "notify"; 170 ExecStart = [ 171 "" 172 '' 173 ${cfg.package}/bin/dockerd \ 174 --group=docker \ 175 --host=fd:// \ 176 --log-driver=${cfg.logDriver} \ 177 ${optionalString (cfg.storageDriver != null) "--storage-driver=${cfg.storageDriver}"} \ 178 ${optionalString cfg.liveRestore "--live-restore" } \ 179 ${optionalString cfg.enableNvidia "--add-runtime nvidia=${pkgs.nvidia-docker}/bin/nvidia-container-runtime" } \ 180 ${cfg.extraOptions} 181 '']; 182 ExecReload=[ 183 "" 184 "${pkgs.procps}/bin/kill -s HUP $MAINPID" 185 ]; 186 }; 187 188 path = [ pkgs.kmod ] ++ optional (cfg.storageDriver == "zfs") pkgs.zfs 189 ++ optional cfg.enableNvidia pkgs.nvidia-docker; 190 }; 191 192 systemd.sockets.docker = { 193 description = "Docker Socket for the API"; 194 wantedBy = [ "sockets.target" ]; 195 socketConfig = { 196 ListenStream = cfg.listenOptions; 197 SocketMode = "0660"; 198 SocketUser = "root"; 199 SocketGroup = "docker"; 200 }; 201 }; 202 203 systemd.services.docker-prune = { 204 description = "Prune docker resources"; 205 206 restartIfChanged = false; 207 unitConfig.X-StopOnRemoval = false; 208 209 serviceConfig.Type = "oneshot"; 210 211 script = '' 212 ${cfg.package}/bin/docker system prune -f ${toString cfg.autoPrune.flags} 213 ''; 214 215 startAt = optional cfg.autoPrune.enable cfg.autoPrune.dates; 216 }; 217 218 assertions = [ 219 { assertion = cfg.enableNvidia -> config.hardware.opengl.driSupport32Bit or false; 220 message = "Option enableNvidia requires 32bit support libraries"; 221 }]; 222 } 223 ]); 224 225 imports = [ 226 (mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed and socket activation is now always active") 227 ]; 228 229}