From 508343962ea26e9da9a4c0c10009bfba85f50021 Mon Sep 17 00:00:00 2001 From: Yorick Date: Tue, 28 Jan 2020 22:00:54 +0100 Subject: nixos/docker-containers: add imageFile and dependsOn options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - the `imageFile` option allows to load an image from a derivation - the `dependsOn` option can be used to specify dependencies between container systemd units. Co-authored-by: Christian Höppner --- nixos/modules/virtualisation/docker-containers.nix | 55 ++++++++++++++++++---- nixos/tests/docker-containers.nix | 9 ++-- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/nixos/modules/virtualisation/docker-containers.nix b/nixos/modules/virtualisation/docker-containers.nix index 760cb9122a2f..3a2eb97d1bf1 100644 --- a/nixos/modules/virtualisation/docker-containers.nix +++ b/nixos/modules/virtualisation/docker-containers.nix @@ -10,11 +10,24 @@ let options = { image = mkOption { - type = types.str; + type = with types; str; description = "Docker image to run."; example = "library/hello-world"; }; + imageFile = mkOption { + type = with types; nullOr package; + default = null; + description = '' + Path to an image file to load instead of pulling from a registry. + If defined, do not pull from registry. + + You still need to set the image attribute, as it + will be used as the image name for docker to start a container. + ''; + example = literalExample "pkgs.dockerTools.buildDockerImage {...};"; + }; + cmd = mkOption { type = with types; listOf str; default = []; @@ -153,6 +166,24 @@ let example = "/var/lib/hello_world"; }; + dependsOn = mkOption { + type = with types; listOf str; + default = []; + description = '' + Define which other containers this one depends on. They will be added to both After and Requires for the unit. + + Use the same name as the attribute under services.docker-containers. + ''; + example = literalExample '' + services.docker-containers = { + node1 = {}; + node2 = { + dependsOn = [ "node1" ]; + } + } + ''; + }; + extraDockerOptions = mkOption { type = with types; listOf str; default = []; @@ -164,15 +195,18 @@ let }; }; - mkService = name: container: { + mkService = name: container: let + mkAfter = map (x: "docker-${x}.service") container.dependsOn; + in rec { wantedBy = [ "multi-user.target" ]; - after = [ "docker.service" "docker.socket" ]; - requires = [ "docker.service" "docker.socket" ]; + after = [ "docker.service" "docker.socket" ] ++ mkAfter; + requires = after; + serviceConfig = { ExecStart = concatStringsSep " \\\n " ([ "${pkgs.docker}/bin/docker run" "--rm" - "--name=%n" + "--name=${name}" "--log-driver=${container.log-driver}" ] ++ optional (container.entrypoint != null) "--entrypoint=${escapeShellArg container.entrypoint}" @@ -185,9 +219,14 @@ let ++ [container.image] ++ map escapeShellArg container.cmd ); - ExecStartPre = "-${pkgs.docker}/bin/docker rm -f %n"; - ExecStop = ''${pkgs.bash}/bin/sh -c "[ $SERVICE_RESULT = success ] || ${pkgs.docker}/bin/docker stop %n"''; - ExecStopPost = "-${pkgs.docker}/bin/docker rm -f %n"; + + ExecStartPre = ["-${pkgs.docker}/bin/docker rm -f ${name}" + "-${pkgs.docker}/bin/docker image prune -f"] ++ + (optional (container.imageFile != null) + ["${pkgs.docker}/bin/docker load -i ${container.imageFile}"]); + + ExecStop = ''${pkgs.bash}/bin/sh -c "[ $SERVICE_RESULT = success ] || ${pkgs.docker}/bin/docker stop ${name}"''; + ExecStopPost = "-${pkgs.docker}/bin/docker rm -f ${name}"; ### There is no generalized way of supporting `reload` for docker ### containers. Some containers may respond well to SIGHUP sent to their diff --git a/nixos/tests/docker-containers.nix b/nixos/tests/docker-containers.nix index 972552735202..9be9bfa80ce0 100644 --- a/nixos/tests/docker-containers.nix +++ b/nixos/tests/docker-containers.nix @@ -1,9 +1,11 @@ # Test Docker containers as systemd units -import ./make-test.nix ({ pkgs, lib, ... }: { +import ./make-test.nix ({ pkgs, lib, ... }: + +{ name = "docker-containers"; meta = { - maintainers = with lib.maintainers; [ benley ]; + maintainers = with lib.maintainers; [ benley mkaito ]; }; nodes = { @@ -11,10 +13,9 @@ import ./make-test.nix ({ pkgs, lib, ... }: { { virtualisation.docker.enable = true; - virtualisation.dockerPreloader.images = [ pkgs.dockerTools.examples.nginx ]; - docker-containers.nginx = { image = "nginx-container"; + imageFile = pkgs.dockerTools.examples.nginx; ports = ["8181:80"]; }; }; -- cgit v1.2.3