grafana-alloy: don't build the frontend twice
[NixPkgs.git] / nixos / modules / virtualisation / docker.nix
blob4f38bc0b94d6ccf3598288f5058c0ee59416c252
1 # Systemd services for docker.
3 { config, lib, pkgs, ... }:
5 with lib;
7 let
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;
16   ###### interface
18   options.virtualisation.docker = {
19     enable =
20       mkOption {
21         type = types.bool;
22         default = false;
23         description = ''
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.
28           '';
29       };
31     listenOptions =
32       mkOption {
33         type = types.listOf types.str;
34         default = ["/run/docker.sock"];
35         description = ''
36             A list of unix and tcp docker should listen to. The format follows
37             ListenStream as described in systemd.socket(5).
38           '';
39       };
41     enableOnBoot =
42       mkOption {
43         type = types.bool;
44         default = true;
45         description = ''
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.
50           '';
51       };
53     daemon.settings =
54       mkOption {
55         type = settingsFormat.type;
56         default = { };
57         example = {
58           ipv6 = true;
59           "fixed-cidr-v6" = "fd00::/80";
60         };
61         description = ''
62           Configuration for docker daemon. The attributes are serialized to JSON used as daemon.conf.
63           See https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
64         '';
65       };
67     enableNvidia =
68       mkOption {
69         type = types.bool;
70         default = false;
71         description = ''
72           **Deprecated**, please use hardware.nvidia-container-toolkit.enable instead.
74           Enable nvidia-docker wrapper, supporting NVIDIA GPUs inside docker containers.
75         '';
76       };
78     liveRestore =
79       mkOption {
80         type = types.bool;
81         default = true;
82         description = ''
83             Allow dockerd to be restarted without affecting running container.
84             This option is incompatible with docker swarm.
85           '';
86       };
88     storageDriver =
89       mkOption {
90         type = types.nullOr (types.enum ["aufs" "btrfs" "devicemapper" "overlay" "overlay2" "zfs"]);
91         default = null;
92         description = ''
93             This option determines which Docker
94             [storage driver](https://docs.docker.com/storage/storagedriver/select-storage-driver/)
95             to use.
96             By default it lets docker automatically choose the preferred storage
97             driver.
98             However, it is recommended to specify a storage driver explicitly, as
99             docker's default varies over versions.
101             ::: {.warning}
102             Changing the storage driver will cause any existing containers
103             and images to become inaccessible.
104             :::
105           '';
106       };
108     logDriver =
109       mkOption {
110         type = types.enum ["none" "json-file" "syslog" "journald" "gelf" "fluentd" "awslogs" "splunk" "etwlogs" "gcplogs" "local"];
111         default = "journald";
112         description = ''
113             This option determines which Docker log driver to use.
114           '';
115       };
117     extraOptions =
118       mkOption {
119         type = types.separatedString " ";
120         default = "";
121         description = ''
122             The extra command-line options to pass to
123             {command}`docker` daemon.
124           '';
125       };
127     autoPrune = {
128       enable = mkOption {
129         type = types.bool;
130         default = false;
131         description = ''
132           Whether to periodically prune Docker resources. If enabled, a
133           systemd timer will run `docker system prune -f`
134           as specified by the `dates` option.
135         '';
136       };
138       flags = mkOption {
139         type = types.listOf types.str;
140         default = [];
141         example = [ "--all" ];
142         description = ''
143           Any additional flags passed to {command}`docker system prune`.
144         '';
145       };
147       dates = mkOption {
148         default = "weekly";
149         type = types.str;
150         description = ''
151           Specification (in the format described by
152           {manpage}`systemd.time(7)`) of the time at
153           which the prune will occur.
154         '';
155       };
156     };
158     package = mkPackageOption pkgs "docker" { };
160     extraPackages = mkOption {
161       type = types.listOf types.package;
162       default = [ ];
163       example = literalExpression "with pkgs; [ criu ]";
164       description = ''
165         Extra packages to add to PATH for the docker daemon process.
166       '';
167     };
168   };
170   ###### implementation
172   config = mkIf cfg.enable (mkMerge [{
173       boot.kernelModules = [ "bridge" "veth" "br_netfilter" "xt_nat" ];
174       boot.kernel.sysctl = {
175         "net.ipv4.conf.all.forwarding" = mkOverride 98 true;
176         "net.ipv4.conf.default.forwarding" = mkOverride 98 true;
177       };
178       environment.systemPackages = [ cfg.package ]
179         ++ optional cfg.enableNvidia pkgs.nvidia-docker;
180       users.groups.docker.gid = config.ids.gids.docker;
181       systemd.packages = [ cfg.package ];
183       # Docker 25.0.0 supports CDI by default
184       # (https://docs.docker.com/engine/release-notes/25.0/#new). Encourage
185       # moving to CDI as opposed to having deprecated runtime
186       # wrappers.
187       warnings = lib.optionals (cfg.enableNvidia && (lib.strings.versionAtLeast cfg.package.version "25")) [
188         ''
189           You have set virtualisation.docker.enableNvidia. This option is deprecated, please set hardware.nvidia-container-toolkit.enable instead.
190         ''
191       ];
193       systemd.services.docker = {
194         wantedBy = optional cfg.enableOnBoot "multi-user.target";
195         after = [ "network.target" "docker.socket" ];
196         requires = [ "docker.socket" ];
197         environment = proxy_env;
198         serviceConfig = {
199           Type = "notify";
200           ExecStart = [
201             ""
202             ''
203               ${cfg.package}/bin/dockerd \
204                 --config-file=${daemonSettingsFile} \
205                 ${cfg.extraOptions}
206             ''];
207           ExecReload=[
208             ""
209             "${pkgs.procps}/bin/kill -s HUP $MAINPID"
210           ];
211         };
213         path = [ pkgs.kmod ] ++ optional (cfg.storageDriver == "zfs") pkgs.zfs
214           ++ optional cfg.enableNvidia pkgs.nvidia-docker
215           ++ cfg.extraPackages;
216       };
218       systemd.sockets.docker = {
219         description = "Docker Socket for the API";
220         wantedBy = [ "sockets.target" ];
221         socketConfig = {
222           ListenStream = cfg.listenOptions;
223           SocketMode = "0660";
224           SocketUser = "root";
225           SocketGroup = "docker";
226         };
227       };
229       systemd.services.docker-prune = {
230         description = "Prune docker resources";
232         restartIfChanged = false;
233         unitConfig.X-StopOnRemoval = false;
235         serviceConfig.Type = "oneshot";
237         script = ''
238           ${cfg.package}/bin/docker system prune -f ${toString cfg.autoPrune.flags}
239         '';
241         startAt = optional cfg.autoPrune.enable cfg.autoPrune.dates;
242         after = [ "docker.service" ];
243         requires = [ "docker.service" ];
244       };
246       assertions = [
247         { assertion = cfg.enableNvidia && pkgs.stdenv.hostPlatform.isx86_64 -> config.hardware.graphics.enable32Bit or false;
248           message = "Option enableNvidia on x86_64 requires 32-bit support libraries";
249         }];
251       virtualisation.docker.daemon.settings = {
252         group = "docker";
253         hosts = [ "fd://" ];
254         log-driver = mkDefault cfg.logDriver;
255         storage-driver = mkIf (cfg.storageDriver != null) (mkDefault cfg.storageDriver);
256         live-restore = mkDefault cfg.liveRestore;
257         runtimes = mkIf cfg.enableNvidia {
258           nvidia = {
259             # Use the legacy nvidia-container-runtime wrapper to allow
260             # the `--runtime=nvidia` approach to expose
261             # GPU's. Starting with Docker > 25, CDI can be used
262             # instead, removing the need for runtime wrappers.
263             path = lib.getExe' pkgs.nvidia-docker "nvidia-container-runtime.legacy";
264           };
265         };
266       };
267     }
268   ]);
270   imports = [
271     (mkRemovedOptionModule ["virtualisation" "docker" "socketActivation"] "This option was removed and socket activation is now always active")
272   ];