aboutsummaryrefslogtreecommitdiff
path: root/modules/apps
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2018-05-05 13:09:30 +0300
committerIgor Pashev <pashev.igor@gmail.com>2018-05-05 13:16:21 +0300
commit0cad0928bd0f7f4ad877b95de7f65d229d70313a (patch)
treeddd07fd43265439f61c63416caabccfd6adb50ae /modules/apps
parentfe5629b0e8d18ee9c1defc94a07fea57b819c730 (diff)
downloadnixsap-0cad0928bd0f7f4ad877b95de7f65d229d70313a.tar.gz
Add multi-instance Docker app with bash completion
Example configuration: { config, ... }: let inherit (config.nixsap) apps; in { imports = [ <modules> ]; nixsap.apps.docker.foo = { }; users.users.pashev.extraGroups = [apps.docker.foo.daemon.group]; } Usage: (Sat, 05 May 2018 10:09:01 +0000) [pashev@vbox-devops:~] # docker-foo images REPOSITORY TAG IMAGE ID CREATED SIZE debian latest 8626492fecd3 7 days ago 101MB ubuntu latest 452a96d81c30 7 days ago 79.6MB
Diffstat (limited to 'modules/apps')
-rw-r--r--modules/apps/docker/default.nix63
-rw-r--r--modules/apps/docker/instance.nix109
2 files changed, 172 insertions, 0 deletions
diff --git a/modules/apps/docker/default.nix b/modules/apps/docker/default.nix
new file mode 100644
index 0000000..7698959
--- /dev/null
+++ b/modules/apps/docker/default.nix
@@ -0,0 +1,63 @@
+{ config, pkgs, lib, ... }:
+
+let
+
+ inherit (builtins) toJSON;
+
+ inherit (lib)
+ filterAttrs foldl mapAttrsToList mkOption optional
+ ;
+
+ inherit (lib.types) attrsOf submodule;
+
+ explicit = filterAttrs (n: v: n != "_module" && v != null);
+
+ instances = explicit config.nixsap.apps.docker;
+
+ groups = mapAttrsToList (_: i: i.daemon.group) instances;
+ clis = mapAttrsToList (_: i: i.docker-cli) instances;
+
+ mkService = name: opts:
+ let
+ config-file = pkgs.runCommand "dockerd-${name}.json" {} ''
+ cat <<'EOF' | ${pkgs.jq}/bin/jq . > $out
+ ${toJSON (explicit (opts.daemon))}
+ EOF
+ '';
+ in {
+ "docker-${name}" = {
+ description = "Docker daemon (${name})";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "local-fs.target" ];
+ path = [ pkgs.kmod ] ++ (optional (opts.daemon.storage-driver == "zfs") pkgs.zfs);
+ preStart = ''
+ mkdir -p -- '${opts.daemon.data-root}'
+ rm -rf -- '${opts.daemon.exec-root}'
+ mkdir -p -- '${opts.daemon.exec-root}'
+
+ chown -c -- 'root:root' '${opts.daemon.data-root}'
+ chmod -c -- u=rwX,g=rX,o= '${opts.daemon.data-root}'
+ '';
+ serviceConfig = {
+ ExecStart = "${opts.package}/bin/dockerd --config-file ${config-file}";
+ ExecReload = "${pkgs.procps}/bin/kill -s HUP $MAINPID";
+ };
+ };
+ };
+
+in {
+
+ options.nixsap.apps.docker = mkOption {
+ description = "Instances of Docker";
+ type = attrsOf (submodule (import ./instance.nix pkgs));
+ default = {};
+ };
+
+ config = {
+ systemd.services = foldl (a: b: a//b) {} (mapAttrsToList mkService instances);
+ nixsap.system.groups = groups;
+ environment.systemPackages = clis;
+ };
+
+}
+
diff --git a/modules/apps/docker/instance.nix b/modules/apps/docker/instance.nix
new file mode 100644
index 0000000..fc361f3
--- /dev/null
+++ b/modules/apps/docker/instance.nix
@@ -0,0 +1,109 @@
+pkgs:
+
+{ lib, name, config, ... }:
+
+let
+
+ inherit (lib)
+ mkOption
+ ;
+
+ inherit (lib.types)
+ bool enum int listOf nullOr package path str
+ ;
+
+ default = d: t: mkOption { type = t; default = d; };
+ optional = t: mkOption { type = nullOr t; default = null; };
+ readonly = d: t: mkOption { type = nullOr t; default = d; readOnly = true; };
+
+ socket = "unix://${config.daemon.exec-root}/dockerd.sock";
+
+in {
+ options = {
+ package = mkOption {
+ description = "Docker package";
+ default = pkgs.docker;
+ type = package;
+ };
+
+ docker-cli = mkOption {
+ description = "Convenient wrapper of docker command line uitlity for this Docker instance";
+ type = package;
+ readOnly = true;
+ default = pkgs.runCommand "docker-${name}" {} ''
+ mkdir -p $out/bin
+ mkdir -p $out/share/bash-completion/completions
+
+ cat << 'ETC' > "$out/share/bash-completion/completions/docker-${name}"
+ . ${config.package}/share/bash-completion/completions/docker
+ complete -r docker
+ complete -F _docker 'docker-${name}'
+ ETC
+
+ cat << 'BIN' > "$out/bin/docker-${name}"
+ exec ${config.package}/bin/docker --host '${socket}' "$@"
+ BIN
+
+ chmod +x "$out/bin/docker-${name}"
+ '';
+ };
+
+ daemon = {
+ debug = optional bool;
+ add-runtime = optional (listOf str);
+ allow-nondistributable-artifacts = optional (listOf str);
+ api-cors-header = optional str;
+ authorization-plugin = optional (listOf str);
+ bip = optional str;
+ bridge = optional str;
+ cgroup-parent = optional str;
+ containerd = optional str;
+ cpu-rt-period = optional int;
+ cpu-rt-runtime = optional int;
+ data-root = default "/docker/${name}" path;
+ default-gateway = optional str;
+ default-gateway-v6 = optional str;
+ default-runtime = optional str;
+ # TBD: default-ulimit = optional attributes
+ dns = optional (listOf str);
+ dns-opt = optional (listOf str);
+ dns-search = optional (listOf str);
+ exec-root = readonly "${config.daemon.data-root}/run" path;
+ experimental = optional bool;
+ fixed-cidr = optional str;
+ fixed-cidr-v6 = optional str;
+ group = default "docker-${name}" str;
+ hosts = readonly [socket] (listOf str);
+ icc = optional bool;
+ init = optional bool;
+ init-path = optional path;
+ insecure-registry = optional (listOf str);
+ ip = optional str;
+ ip-forward = optional bool;
+ ip-masq = optional bool;
+ iptables = optional bool;
+ ipv6 = optional bool;
+ live-restore = optional bool;
+ log-driver = readonly "journald" str;
+ log-level = optional (enum ["debug" "info" "warn" "error" "fatal"]);
+ max-concurrent-downloads = optional int;
+ max-concurrent-uploads = optional int;
+ metrics-addr = optional str;
+ mtu = optional int;
+ no-new-privileges = optional bool;
+ oom-score-adjust = optional int;
+ pidfile = readonly "${config.daemon.exec-root}/dockerd.pid" path;
+ raw-logs = optional bool;
+ registry-mirror = optional (listOf str);
+ seccomp-profile = optional path;
+ selinux-enabled = optional bool;
+ shutdown-timeout = optional int;
+ storage-driver = optional (enum ["aufs" "devicemapper" "btrfs" "zfs" "overlay" "overlay2"]);
+ storage-opt = optional (listOf str);
+ swarm-default-advertise-addr = optional str;
+ userland-proxy = optional bool;
+ userland-proxy-path = optional path;
+ userns-remap = optional str;
+ };
+ };
+}