1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8
9 cfg = config.virtualisation.docker.rootless;
10 proxy_env = config.networking.proxy.envVars;
11 settingsFormat = pkgs.formats.json { };
12 daemonSettingsFile = settingsFormat.generate "daemon.json" cfg.daemon.settings;
13
14in
15
16{
17 ###### interface
18
19 options.virtualisation.docker.rootless = {
20 enable = lib.mkOption {
21 type = lib.types.bool;
22 default = false;
23 description = ''
24 This option enables docker in a rootless mode, a daemon that manages
25 linux containers. To interact with the daemon, one needs to set
26 {command}`DOCKER_HOST=unix://$XDG_RUNTIME_DIR/docker.sock`.
27 '';
28 };
29
30 setSocketVariable = lib.mkOption {
31 type = lib.types.bool;
32 default = false;
33 description = ''
34 Point {command}`DOCKER_HOST` to rootless Docker instance for
35 normal users by default.
36 '';
37 };
38
39 daemon.settings = lib.mkOption {
40 type = settingsFormat.type;
41 default = { };
42 example = {
43 ipv6 = true;
44 "fixed-cidr-v6" = "fd00::/80";
45 };
46 description = ''
47 Configuration for docker daemon. The attributes are serialized to JSON used as daemon.conf.
48 See <https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file>
49 '';
50 };
51
52 package = lib.mkPackageOption pkgs "docker" { };
53
54 extraPackages = lib.mkOption {
55 type = lib.types.listOf lib.types.package;
56 default = [ ];
57 description = ''
58 Extra packages to add to PATH for the docker daemon process.
59 '';
60 };
61 };
62
63 ###### implementation
64
65 config = lib.mkIf cfg.enable {
66 environment.systemPackages = [ cfg.package ];
67
68 environment.extraInit = lib.optionalString cfg.setSocketVariable ''
69 if [ -z "$DOCKER_HOST" -a -n "$XDG_RUNTIME_DIR" ]; then
70 export DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"
71 fi
72 '';
73
74 # Taken from https://github.com/moby/moby/blob/master/contrib/dockerd-rootless-setuptool.sh
75 systemd.user.services.docker = {
76 wantedBy = [ "default.target" ];
77 description = "Docker Application Container Engine (Rootless)";
78 # needs newuidmap from pkgs.shadow
79 path = [ "/run/wrappers" ] ++ cfg.extraPackages;
80 environment = proxy_env;
81 unitConfig = {
82 # docker-rootless doesn't support running as root.
83 ConditionUser = "!root";
84 StartLimitInterval = "60s";
85 };
86 serviceConfig = {
87 Type = "notify";
88 ExecStart = "${cfg.package}/bin/dockerd-rootless --config-file=${daemonSettingsFile}";
89 ExecReload = "${pkgs.procps}/bin/kill -s HUP $MAINPID";
90 TimeoutSec = 0;
91 RestartSec = 2;
92 Restart = "always";
93 LimitNOFILE = "infinity";
94 LimitNPROC = "infinity";
95 LimitCORE = "infinity";
96 Delegate = true;
97 NotifyAccess = "all";
98 KillMode = "mixed";
99 };
100 unitConfig = {
101 StartLimitBurst = 3;
102 };
103 };
104 };
105
106}