at v192 4.4 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 description = 50 '' 51 This option determines which Docker storage driver to use. 52 It is required but lacks a default value as its most 53 suitable value will depend the filesystems available on the 54 host. 55 ''; 56 }; 57 extraOptions = 58 mkOption { 59 type = types.separatedString " "; 60 default = ""; 61 description = 62 '' 63 The extra command-line options to pass to 64 <command>docker</command> daemon. 65 ''; 66 }; 67 68 postStart = 69 mkOption { 70 type = types.string; 71 default = '' 72 while ! [ -e /var/run/docker.sock ]; do 73 sleep 0.1 74 done 75 ''; 76 description = '' 77 The postStart phase of the systemd service. You may need to 78 override this if you are passing in flags to docker which 79 don't cause the socket file to be created. 80 ''; 81 }; 82 83 84 }; 85 86 ###### implementation 87 88 config = mkIf cfg.enable (mkMerge [ 89 { environment.systemPackages = [ pkgs.docker ]; 90 users.extraGroups.docker.gid = config.ids.gids.docker; 91 } 92 (mkIf cfg.socketActivation { 93 94 systemd.services.docker = { 95 description = "Docker Application Container Engine"; 96 after = [ "network.target" "docker.socket" ]; 97 requires = [ "docker.socket" ]; 98 serviceConfig = { 99 ExecStart = "${pkgs.docker}/bin/docker daemon --host=fd:// --group=docker --storage-driver=${cfg.storageDriver} ${cfg.extraOptions}"; 100 # I'm not sure if that limits aren't too high, but it's what 101 # goes in config bundled with docker itself 102 LimitNOFILE = 1048576; 103 LimitNPROC = 1048576; 104 } // proxy_env; 105 }; 106 107 systemd.sockets.docker = { 108 description = "Docker Socket for the API"; 109 wantedBy = [ "sockets.target" ]; 110 socketConfig = { 111 ListenStream = "/var/run/docker.sock"; 112 SocketMode = "0660"; 113 SocketUser = "root"; 114 SocketGroup = "docker"; 115 }; 116 }; 117 }) 118 (mkIf (!cfg.socketActivation) { 119 120 systemd.services.docker = { 121 description = "Docker Application Container Engine"; 122 wantedBy = [ "multi-user.target" ]; 123 after = [ "network.target" ]; 124 serviceConfig = { 125 ExecStart = "${pkgs.docker}/bin/docker daemon --group=docker --storage-driver=${cfg.storageDriver} ${cfg.extraOptions}"; 126 # I'm not sure if that limits aren't too high, but it's what 127 # goes in config bundled with docker itself 128 LimitNOFILE = 1048576; 129 LimitNPROC = 1048576; 130 } // proxy_env; 131 132 path = [ pkgs.kmod ]; 133 environment.MODULE_DIR = "/run/current-system/kernel-modules/lib/modules"; 134 135 postStart = cfg.postStart; 136 137 # Presumably some containers are running we don't want to interrupt 138 restartIfChanged = false; 139 }; 140 }) 141 ]); 142 143}