nixos/docker-containers: Rename to virtualisation.oci-containers.containers.
And allow the runtime to be configurable via the `virtualisation.oci-containers.backend` option. Valid choices are "podman" and "docker".
This commit is contained in:
parent
2fb5dac372
commit
2f7747526c
|
@ -55,6 +55,12 @@
|
||||||
The new <varname>virtualisation.containers</varname> module manages configuration shared by the CRI-O and Podman modules.
|
The new <varname>virtualisation.containers</varname> module manages configuration shared by the CRI-O and Podman modules.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Declarative Docker containers are renamed from <varname>docker-containers</varname> to <varname>virtualisation.oci-containers.containers</varname>.
|
||||||
|
This is to make it possible to use <literal>podman</literal> instead of <literal>docker</literal>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -984,9 +984,9 @@
|
||||||
./virtualisation/container-config.nix
|
./virtualisation/container-config.nix
|
||||||
./virtualisation/containers.nix
|
./virtualisation/containers.nix
|
||||||
./virtualisation/nixos-containers.nix
|
./virtualisation/nixos-containers.nix
|
||||||
|
./virtualisation/oci-containers.nix
|
||||||
./virtualisation/cri-o.nix
|
./virtualisation/cri-o.nix
|
||||||
./virtualisation/docker.nix
|
./virtualisation/docker.nix
|
||||||
./virtualisation/docker-containers.nix
|
|
||||||
./virtualisation/ecs-agent.nix
|
./virtualisation/ecs-agent.nix
|
||||||
./virtualisation/libvirtd.nix
|
./virtualisation/libvirtd.nix
|
||||||
./virtualisation/lxc.nix
|
./virtualisation/lxc.nix
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, options, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
let
|
let
|
||||||
cfg = config.docker-containers;
|
cfg = config.virtualisation.oci-containers;
|
||||||
|
proxy_env = config.networking.proxy.envVars;
|
||||||
|
|
||||||
dockerContainer =
|
defaultBackend = options.virtualisation.oci-containers.backend.default;
|
||||||
|
|
||||||
|
containerOptions =
|
||||||
{ ... }: {
|
{ ... }: {
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
image = mkOption {
|
image = mkOption {
|
||||||
type = with types; str;
|
type = with types; str;
|
||||||
description = "Docker image to run.";
|
description = "OCI image to run.";
|
||||||
example = "library/hello-world";
|
example = "library/hello-world";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,18 +61,19 @@ let
|
||||||
|
|
||||||
log-driver = mkOption {
|
log-driver = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
default = "none";
|
default = "journald";
|
||||||
description = ''
|
description = ''
|
||||||
Logging driver for the container. The default of
|
Logging driver for the container. The default of
|
||||||
<literal>"none"</literal> means that the container's logs will be
|
<literal>"journald"</literal> means that the container's logs will be
|
||||||
handled as part of the systemd unit. Setting this to
|
handled as part of the systemd unit.
|
||||||
<literal>"journald"</literal> will result in duplicate logging, but
|
|
||||||
the container's logs will be visible to the <command>docker
|
|
||||||
logs</command> command.
|
|
||||||
|
|
||||||
For more details and a full list of logging drivers, refer to the
|
For more details and a full list of logging drivers, refer to respective backends documentation.
|
||||||
<link xlink:href="https://docs.docker.com/engine/reference/run/#logging-drivers---log-driver">
|
|
||||||
Docker engine documentation</link>
|
For Docker:
|
||||||
|
<link xlink:href="https://docs.docker.com/engine/reference/run/#logging-drivers---log-driver">Docker engine documentation</link>
|
||||||
|
|
||||||
|
For Podman:
|
||||||
|
Refer to the docker-run(1) man page.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -172,10 +176,10 @@ let
|
||||||
description = ''
|
description = ''
|
||||||
Define which other containers this one depends on. They will be added to both After and Requires for the unit.
|
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 <literal>services.docker-containers</literal>.
|
Use the same name as the attribute under <literal>virtualisation.oci-containers</literal>.
|
||||||
'';
|
'';
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
services.docker-containers = {
|
virtualisation.oci-containers = {
|
||||||
node1 = {};
|
node1 = {};
|
||||||
node2 = {
|
node2 = {
|
||||||
dependsOn = [ "node1" ];
|
dependsOn = [ "node1" ];
|
||||||
|
@ -184,10 +188,10 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
extraDockerOptions = mkOption {
|
extraOptions = mkOption {
|
||||||
type = with types; listOf str;
|
type = with types; listOf str;
|
||||||
default = [];
|
default = [];
|
||||||
description = "Extra options for <command>docker run</command>.";
|
description = "Extra options for <command>${defaultBackend} run</command>.";
|
||||||
example = literalExample ''
|
example = literalExample ''
|
||||||
["--network=host"]
|
["--network=host"]
|
||||||
'';
|
'';
|
||||||
|
@ -205,24 +209,31 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
mkService = name: container: let
|
mkService = name: container: let
|
||||||
mkAfter = map (x: "docker-${x}.service") container.dependsOn;
|
dependsOn = map (x: "${cfg.backend}-${x}.service") container.dependsOn;
|
||||||
in rec {
|
in {
|
||||||
wantedBy = [] ++ optional (container.autoStart) "multi-user.target";
|
wantedBy = [] ++ optional (container.autoStart) "multi-user.target";
|
||||||
after = [ "docker.service" "docker.socket" ] ++ mkAfter;
|
after = lib.optionals (cfg.backend == "docker") [ "docker.service" "docker.socket" ] ++ dependsOn;
|
||||||
requires = after;
|
requires = dependsOn;
|
||||||
path = [ pkgs.docker ];
|
environment = proxy_env;
|
||||||
|
|
||||||
|
path =
|
||||||
|
if cfg.backend == "docker" then [ pkgs.docker ]
|
||||||
|
else if cfg.backend == "podman" then [ config.virtualisation.podman.package ]
|
||||||
|
else throw "Unhandled backend: ${cfg.backend}";
|
||||||
|
|
||||||
preStart = ''
|
preStart = ''
|
||||||
docker rm -f ${name} || true
|
${cfg.backend} rm -f ${name} || true
|
||||||
${optionalString (container.imageFile != null) ''
|
${optionalString (container.imageFile != null) ''
|
||||||
docker load -i ${container.imageFile}
|
${cfg.backend} load -i ${container.imageFile}
|
||||||
''}
|
''}
|
||||||
'';
|
'';
|
||||||
postStop = "docker rm -f ${name} || true";
|
postStop = "${cfg.backend} rm -f ${name} || true";
|
||||||
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
|
StandardOutput = "null";
|
||||||
|
StandardError = "null";
|
||||||
ExecStart = concatStringsSep " \\\n " ([
|
ExecStart = concatStringsSep " \\\n " ([
|
||||||
"${pkgs.docker}/bin/docker run"
|
"${config.system.path}/bin/${cfg.backend} run"
|
||||||
"--rm"
|
"--rm"
|
||||||
"--name=${name}"
|
"--name=${name}"
|
||||||
"--log-driver=${container.log-driver}"
|
"--log-driver=${container.log-driver}"
|
||||||
|
@ -233,12 +244,12 @@ let
|
||||||
++ optional (container.user != null) "-u ${escapeShellArg container.user}"
|
++ optional (container.user != null) "-u ${escapeShellArg container.user}"
|
||||||
++ map (v: "-v ${escapeShellArg v}") container.volumes
|
++ map (v: "-v ${escapeShellArg v}") container.volumes
|
||||||
++ optional (container.workdir != null) "-w ${escapeShellArg container.workdir}"
|
++ optional (container.workdir != null) "-w ${escapeShellArg container.workdir}"
|
||||||
++ map escapeShellArg container.extraDockerOptions
|
++ map escapeShellArg container.extraOptions
|
||||||
++ [container.image]
|
++ [container.image]
|
||||||
++ map escapeShellArg container.cmd
|
++ map escapeShellArg container.cmd
|
||||||
);
|
);
|
||||||
|
|
||||||
ExecStop = ''${pkgs.bash}/bin/sh -c "[ $SERVICE_RESULT = success ] || docker stop ${name}"'';
|
ExecStop = ''${pkgs.bash}/bin/sh -c "[ $SERVICE_RESULT = success ] || ${cfg.backend} stop ${name}"'';
|
||||||
|
|
||||||
### There is no generalized way of supporting `reload` for docker
|
### There is no generalized way of supporting `reload` for docker
|
||||||
### containers. Some containers may respond well to SIGHUP sent to their
|
### containers. Some containers may respond well to SIGHUP sent to their
|
||||||
|
@ -263,19 +274,50 @@ let
|
||||||
};
|
};
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
imports = [
|
||||||
|
(
|
||||||
|
lib.mkChangedOptionModule
|
||||||
|
[ "docker-containers" ]
|
||||||
|
[ "virtualisation" "oci-containers" ]
|
||||||
|
(oldcfg: {
|
||||||
|
backend = "docker";
|
||||||
|
containers = lib.mapAttrs (n: v: builtins.removeAttrs (v // {
|
||||||
|
extraOptions = v.extraDockerOptions or [];
|
||||||
|
}) [ "extraDockerOptions" ]) oldcfg.docker-containers;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
options.docker-containers = mkOption {
|
options.virtualisation.oci-containers = {
|
||||||
default = {};
|
|
||||||
type = types.attrsOf (types.submodule dockerContainer);
|
|
||||||
description = "Docker containers to run as systemd services.";
|
|
||||||
};
|
|
||||||
|
|
||||||
config = mkIf (cfg != {}) {
|
backend = mkOption {
|
||||||
|
type = types.enum [ "podman" "docker" ];
|
||||||
|
default =
|
||||||
|
# TODO: Once https://github.com/NixOS/nixpkgs/issues/77925 is resolved default to podman
|
||||||
|
# if versionAtLeast config.system.stateVersion "20.09" then "podman"
|
||||||
|
# else "docker";
|
||||||
|
"docker";
|
||||||
|
description = "The underlying Docker implementation to use.";
|
||||||
|
};
|
||||||
|
|
||||||
systemd.services = mapAttrs' (n: v: nameValuePair "docker-${n}" (mkService n v)) cfg;
|
containers = mkOption {
|
||||||
|
default = {};
|
||||||
virtualisation.docker.enable = true;
|
type = types.attrsOf (types.submodule containerOptions);
|
||||||
|
description = "OCI (Docker) containers to run as systemd services.";
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (cfg.containers != {}) (lib.mkMerge [
|
||||||
|
{
|
||||||
|
systemd.services = mapAttrs' (n: v: nameValuePair "${cfg.backend}-${n}" (mkService n v)) cfg.containers;
|
||||||
|
}
|
||||||
|
(lib.mkIf (cfg.backend == "podman") {
|
||||||
|
virtualisation.podman.enable = true;
|
||||||
|
})
|
||||||
|
(lib.mkIf (cfg.backend == "docker") {
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
}
|
}
|
|
@ -88,11 +88,21 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
package = lib.mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = podmanPackage;
|
||||||
|
internal = true;
|
||||||
|
description = ''
|
||||||
|
The final Podman package (including extra packages).
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
|
|
||||||
environment.systemPackages = [ podmanPackage ]
|
environment.systemPackages = [ cfg.package ]
|
||||||
++ lib.optional cfg.dockerCompat dockerCompat;
|
++ lib.optional cfg.dockerCompat dockerCompat;
|
||||||
|
|
||||||
environment.etc."containers/libpod.conf".text = ''
|
environment.etc."containers/libpod.conf".text = ''
|
||||||
|
|
|
@ -70,7 +70,7 @@ in
|
||||||
dhparams = handleTest ./dhparams.nix {};
|
dhparams = handleTest ./dhparams.nix {};
|
||||||
dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {};
|
dnscrypt-proxy2 = handleTestOn ["x86_64-linux"] ./dnscrypt-proxy2.nix {};
|
||||||
docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
|
docker = handleTestOn ["x86_64-linux"] ./docker.nix {};
|
||||||
docker-containers = handleTestOn ["x86_64-linux"] ./docker-containers.nix {};
|
oci-containers = handleTestOn ["x86_64-linux"] ./oci-containers.nix {};
|
||||||
docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {};
|
docker-edge = handleTestOn ["x86_64-linux"] ./docker-edge.nix {};
|
||||||
docker-preloader = handleTestOn ["x86_64-linux"] ./docker-preloader.nix {};
|
docker-preloader = handleTestOn ["x86_64-linux"] ./docker-preloader.nix {};
|
||||||
docker-registry = handleTest ./docker-registry.nix {};
|
docker-registry = handleTest ./docker-registry.nix {};
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Test Docker containers as systemd units
|
|
||||||
|
|
||||||
import ./make-test-python.nix ({ pkgs, lib, ... }: {
|
|
||||||
name = "docker-containers";
|
|
||||||
meta = {
|
|
||||||
maintainers = with lib.maintainers; [ benley mkaito ];
|
|
||||||
};
|
|
||||||
|
|
||||||
nodes = {
|
|
||||||
docker = { pkgs, ... }: {
|
|
||||||
virtualisation.docker.enable = true;
|
|
||||||
|
|
||||||
docker-containers.nginx = {
|
|
||||||
image = "nginx-container";
|
|
||||||
imageFile = pkgs.dockerTools.examples.nginx;
|
|
||||||
ports = ["8181:80"];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
start_all()
|
|
||||||
docker.wait_for_unit("docker-nginx.service")
|
|
||||||
docker.wait_for_open_port(8181)
|
|
||||||
docker.wait_until_succeeds("curl http://localhost:8181 | grep Hello")
|
|
||||||
'';
|
|
||||||
})
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
{ system ? builtins.currentSystem
|
||||||
|
, config ? {}
|
||||||
|
, pkgs ? import ../.. { inherit system config; }
|
||||||
|
, lib ? pkgs.lib
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
|
||||||
|
inherit (import ../lib/testing-python.nix { inherit system pkgs; }) makeTest;
|
||||||
|
|
||||||
|
mkOCITest = backend: makeTest {
|
||||||
|
name = "oci-containers-${backend}";
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
maintainers = with lib.maintainers; [ adisbladis benley mkaito ];
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes = {
|
||||||
|
${backend} = { pkgs, ... }: {
|
||||||
|
virtualisation.oci-containers = {
|
||||||
|
inherit backend;
|
||||||
|
containers.nginx = {
|
||||||
|
image = "nginx-container";
|
||||||
|
imageFile = pkgs.dockerTools.examples.nginx;
|
||||||
|
ports = ["8181:80"];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
start_all()
|
||||||
|
${backend}.wait_for_unit("${backend}-nginx.service")
|
||||||
|
${backend}.wait_for_open_port(8181)
|
||||||
|
${backend}.wait_until_succeeds("curl http://localhost:8181 | grep Hello")
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
lib.foldl' (attrs: backend: attrs // { ${backend} = mkOCITest backend; }) {} [
|
||||||
|
"docker"
|
||||||
|
"podman"
|
||||||
|
]
|
Loading…
Reference in New Issue