at v206 4.3 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 pro = config.networking.proxy.default; 11 proxy_env = optionalAttrs (pro != null) { Environment = "\"http_proxy=${pro}\""; }; 12 13in 14 15{ 16 ###### interface 17 18 options.virtualisation.docker = { 19 enable = 20 mkOption { 21 type = types.bool; 22 default = false; 23 description = 24 '' 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> command line tool. 29 ''; 30 }; 31 socketActivation = 32 mkOption { 33 type = types.bool; 34 default = false; 35 description = 36 '' 37 This option enables docker with socket activation. I.e. docker will 38 start when first called by client. 39 40 Note: This is false by default because systemd lower than 214 that 41 nixos uses so far, doesn't support SocketGroup option, so socket 42 created by docker has root group now. This will likely be changed 43 in future. So set this option explicitly to false if you wish. 44 ''; 45 }; 46 storageDriver = 47 mkOption { 48 type = types.enum ["aufs" "btrfs" "devicemapper" "overlay" "zfs"]; 49 default = "devicemapper"; 50 description = 51 '' 52 This option determines which Docker storage driver to use. 53 ''; 54 }; 55 extraOptions = 56 mkOption { 57 type = types.separatedString " "; 58 default = ""; 59 description = 60 '' 61 The extra command-line options to pass to 62 <command>docker</command> daemon. 63 ''; 64 }; 65 66 postStart = 67 mkOption { 68 type = types.lines; 69 default = '' 70 while ! [ -e /var/run/docker.sock ]; do 71 sleep 0.1 72 done 73 ''; 74 description = '' 75 The postStart phase of the systemd service. You may need to 76 override this if you are passing in flags to docker which 77 don't cause the socket file to be created. 78 ''; 79 }; 80 81 82 }; 83 84 ###### implementation 85 86 config = mkIf cfg.enable (mkMerge [ 87 { environment.systemPackages = [ pkgs.docker ]; 88 users.extraGroups.docker.gid = config.ids.gids.docker; 89 } 90 (mkIf cfg.socketActivation { 91 92 systemd.services.docker = { 93 description = "Docker Application Container Engine"; 94 after = [ "network.target" "docker.socket" ]; 95 requires = [ "docker.socket" ]; 96 serviceConfig = { 97 ExecStart = "${pkgs.docker}/bin/docker daemon --host=fd:// --group=docker --storage-driver=${cfg.storageDriver} ${cfg.extraOptions}"; 98 # I'm not sure if that limits aren't too high, but it's what 99 # goes in config bundled with docker itself 100 LimitNOFILE = 1048576; 101 LimitNPROC = 1048576; 102 } // proxy_env; 103 }; 104 105 systemd.sockets.docker = { 106 description = "Docker Socket for the API"; 107 wantedBy = [ "sockets.target" ]; 108 socketConfig = { 109 ListenStream = "/var/run/docker.sock"; 110 SocketMode = "0660"; 111 SocketUser = "root"; 112 SocketGroup = "docker"; 113 }; 114 }; 115 }) 116 (mkIf (!cfg.socketActivation) { 117 118 systemd.services.docker = { 119 description = "Docker Application Container Engine"; 120 wantedBy = [ "multi-user.target" ]; 121 after = [ "network.target" ]; 122 serviceConfig = { 123 ExecStart = "${pkgs.docker}/bin/docker daemon --group=docker --storage-driver=${cfg.storageDriver} ${cfg.extraOptions}"; 124 # I'm not sure if that limits aren't too high, but it's what 125 # goes in config bundled with docker itself 126 LimitNOFILE = 1048576; 127 LimitNPROC = 1048576; 128 } // proxy_env; 129 130 path = [ pkgs.kmod ] ++ (optional (cfg.storageDriver == "zfs") pkgs.zfs); 131 environment.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules"; 132 133 postStart = cfg.postStart; 134 135 # Presumably some containers are running we don't want to interrupt 136 restartIfChanged = false; 137 }; 138 }) 139 ]); 140 141}