Compare commits
7 commits
f2916b84d8
...
7c65e7ad02
Author | SHA1 | Date | |
---|---|---|---|
Tristan Daniël Maat | 7c65e7ad02 | ||
Tristan Daniël Maat | 4c94932490 | ||
Tristan Daniël Maat | 343c7fcc36 | ||
Tristan Daniël Maat | 5f8899d542 | ||
Tristan Daniël Maat | b8bf3bd3a2 | ||
Tristan Daniël Maat | 458f6c7f7b | ||
Tristan Daniël Maat | 517f4f0080 |
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
|
@ -54,18 +54,20 @@
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
recommendedProxySettings = true;
|
recommendedProxySettings = true;
|
||||||
clientMaxBodySize = "10G";
|
clientMaxBodySize = "10G";
|
||||||
|
domain = "tlater.net";
|
||||||
|
|
||||||
virtualHosts = let
|
virtualHosts = let
|
||||||
host = port: extra:
|
host = port: extra:
|
||||||
{
|
lib.recursiveUpdate {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
locations."/" = { proxyPass = "http://localhost:${toString port}"; };
|
locations."/" = { proxyPass = "http://127.0.0.1:${toString port}"; };
|
||||||
} // extra;
|
} extra;
|
||||||
|
domain = config.services.nginx.domain;
|
||||||
in {
|
in {
|
||||||
"tlater.net" = host 3002 { serverAliases = [ "www.tlater.net" ]; };
|
"${domain}" = host 3002 { serverAliases = [ "www.${domain}" ]; };
|
||||||
"gitea.tlater.net" = host 3000 { };
|
"gitea.${domain}" = host 3000 { };
|
||||||
"nextcloud.tlater.net" = host 3001 { };
|
"nextcloud.${domain}" = host 3001 { };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,11 @@
|
||||||
virtualisation.pods.gitea = {
|
virtualisation.pods.gitea = {
|
||||||
hostname = "gitea.tlater.net";
|
hostname = "gitea.tlater.net";
|
||||||
publish = [ "3000:3000" "2221:2221" ];
|
publish = [ "3000:3000" "2221:2221" ];
|
||||||
|
network = "slirp4netns";
|
||||||
|
|
||||||
containers = {
|
containers = {
|
||||||
gitea = {
|
gitea = {
|
||||||
image = "gitea/gitea:latest";
|
image = "docker.io/gitea/gitea:latest";
|
||||||
volumes = [ "gitea:/data:Z" "/etc/localtime:/etc/localtime:ro" ];
|
volumes = [ "gitea:/data:Z" "/etc/localtime:/etc/localtime:ro" ];
|
||||||
dependsOn = [ "postgres" ];
|
dependsOn = [ "postgres" ];
|
||||||
|
|
||||||
|
@ -26,7 +27,6 @@
|
||||||
DB_HOST = "gitea-postgres:5432";
|
DB_HOST = "gitea-postgres:5432";
|
||||||
DB_NAME = "gitea";
|
DB_NAME = "gitea";
|
||||||
DB_USER = "gitea";
|
DB_USER = "gitea";
|
||||||
DB_PASSWD = "/qNDDK9WCMuubfA7D8DFwfl9T+Gy2IMDvPhiNpcxZjY=";
|
|
||||||
|
|
||||||
USER_UID = toString config.users.extraUsers.gitea.uid;
|
USER_UID = toString config.users.extraUsers.gitea.uid;
|
||||||
USER_GID = toString config.users.extraGroups.gitea.gid;
|
USER_GID = toString config.users.extraGroups.gitea.gid;
|
||||||
|
@ -35,6 +35,11 @@
|
||||||
DOMAIN = "gitea.tlater.net";
|
DOMAIN = "gitea.tlater.net";
|
||||||
SSH_PORT = "2221";
|
SSH_PORT = "2221";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extraOptions = [
|
||||||
|
"--replace"
|
||||||
|
"--label" "io.containers.autoupdate=image"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
postgres = {
|
postgres = {
|
||||||
|
@ -42,7 +47,6 @@
|
||||||
environment = {
|
environment = {
|
||||||
POSTGRES_DB = "gitea";
|
POSTGRES_DB = "gitea";
|
||||||
POSTGRES_USER = "gitea";
|
POSTGRES_USER = "gitea";
|
||||||
POSTGRES_PASSWORD = "/qNDDK9WCMuubfA7D8DFwfl9T+Gy2IMDvPhiNpcxZjY=";
|
|
||||||
};
|
};
|
||||||
volumes = [ "gitea-db-data:/var/lib/postgresql/data" ];
|
volumes = [ "gitea-db-data:/var/lib/postgresql/data" ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, pkgs, ... }:
|
{ config, pkgs, lib, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
minecraft-server-args = [
|
minecraft-server-args = [
|
||||||
|
@ -52,7 +52,7 @@ let
|
||||||
|
|
||||||
in {
|
in {
|
||||||
nixpkgs.config.allowUnfreePredicate = pkg:
|
nixpkgs.config.allowUnfreePredicate = pkg:
|
||||||
builtins.elem (pkgs.lib.getName pkg) [ "forge-server" ];
|
builtins.elem (lib.getName pkg) [ "forge-server" ];
|
||||||
|
|
||||||
virtualisation.oci-containers.containers.minecraft-voor-kia = let
|
virtualisation.oci-containers.containers.minecraft-voor-kia = let
|
||||||
properties = ./configs/minecraft/voor-kia/server.properties;
|
properties = ./configs/minecraft/voor-kia/server.properties;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
virtualisation.pods.nextcloud = {
|
virtualisation.pods.nextcloud = {
|
||||||
hostname = "nextcloud.tlater.net";
|
hostname = "nextcloud.tlater.net";
|
||||||
publish = [ "3001:80" ];
|
publish = [ "3001:80" ];
|
||||||
|
network = "slirp4netns";
|
||||||
|
|
||||||
containers = {
|
containers = {
|
||||||
nextcloud = {
|
nextcloud = {
|
||||||
|
@ -18,7 +19,6 @@
|
||||||
POSTGRES_DB = "nextcloud";
|
POSTGRES_DB = "nextcloud";
|
||||||
POSTGRES_USER = "nextcloud";
|
POSTGRES_USER = "nextcloud";
|
||||||
POSTGRES_HOST = "nextcloud-postgres";
|
POSTGRES_HOST = "nextcloud-postgres";
|
||||||
POSTGRES_PASSWORD = "rI7t7Nek1yGA9ucrRc7Uhy0jcjwPjnXa8me4o8tJON8=";
|
|
||||||
OVERWRITEPROTOCOL = "https";
|
OVERWRITEPROTOCOL = "https";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
environment = {
|
environment = {
|
||||||
POSTGRES_DB = "nextcloud";
|
POSTGRES_DB = "nextcloud";
|
||||||
POSTGRES_USER = "nextcloud";
|
POSTGRES_USER = "nextcloud";
|
||||||
POSTGRES_PASSWORD = "rI7t7Nek1yGA9ucrRc7Uhy0jcjwPjnXa8me4o8tJON8=";
|
|
||||||
};
|
};
|
||||||
volumes = [ "nextcloud-db-data:/var/lib/postgresql/data" ];
|
volumes = [ "nextcloud-db-data:/var/lib/postgresql/data" ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,6 +34,10 @@
|
||||||
|
|
||||||
ports = [ "3002:3002" ];
|
ports = [ "3002:3002" ];
|
||||||
volumes = [ "tlaternet-mail:/srv/mail" ];
|
volumes = [ "tlaternet-mail:/srv/mail" ];
|
||||||
extraOptions = [ "--hostname=tlater.net" ];
|
extraOptions = [
|
||||||
|
"--hostname=tlater.net"
|
||||||
|
# Rocket 0.4 doesn't support SIGTERM anyway, so SIGKILL is the cleanest exit possible.
|
||||||
|
"--stop-signal=SIGKILL"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,12 +68,16 @@
|
||||||
(import ./modules)
|
(import ./modules)
|
||||||
|
|
||||||
(import ./configuration)
|
(import ./configuration)
|
||||||
({ ... }: {
|
({ lib, ... }: {
|
||||||
users.users.tlater.password = "insecure";
|
users.users.tlater.password = "insecure";
|
||||||
|
|
||||||
# Disable graphical tty so -curses works
|
# Disable graphical tty so -curses works
|
||||||
boot.kernelParams = [ "nomodeset" ];
|
boot.kernelParams = [ "nomodeset" ];
|
||||||
|
|
||||||
|
# Sets the base domain for nginx to localhost so that we
|
||||||
|
# can easily test locally with the VM.
|
||||||
|
services.nginx.domain = lib.mkOverride 99 "localhost";
|
||||||
|
|
||||||
# # Set up VM settings to match real VPS
|
# # Set up VM settings to match real VPS
|
||||||
# virtualisation.memorySize = 3941;
|
# virtualisation.memorySize = 3941;
|
||||||
# virtualisation.cores = 2;
|
# virtualisation.cores = 2;
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
{ ... }:
|
{ lib, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
|
||||||
{
|
{
|
||||||
imports = [ ./virtualisation/pods.nix ];
|
imports = [ ./virtualisation/pods.nix ./virtualisation/oci-containers.nix ];
|
||||||
|
|
||||||
|
options.services.nginx.domain = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
description = "The base domain name to append to virtual domain names";
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
350
modules/virtualisation/oci-containers.nix
Normal file
350
modules/virtualisation/oci-containers.nix
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
# Pulled from my own modified fork of nixpkgs, awaiting merge
|
||||||
|
# upstream.
|
||||||
|
|
||||||
|
{ config, options, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.virtualisation.oci-containers;
|
||||||
|
proxy_env = config.networking.proxy.envVars;
|
||||||
|
|
||||||
|
defaultBackend = options.virtualisation.oci-containers.backend.default;
|
||||||
|
|
||||||
|
containerOptions =
|
||||||
|
{ ... }: {
|
||||||
|
|
||||||
|
options = {
|
||||||
|
|
||||||
|
image = mkOption {
|
||||||
|
type = with types; str;
|
||||||
|
description = "OCI 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 <literal>image</literal> 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 = [];
|
||||||
|
description = "Commandline arguments to pass to the image's entrypoint.";
|
||||||
|
example = literalExample ''
|
||||||
|
["--port=9000"]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
entrypoint = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
description = "Override the default entrypoint of the image.";
|
||||||
|
default = null;
|
||||||
|
example = "/bin/my-app";
|
||||||
|
};
|
||||||
|
|
||||||
|
environment = mkOption {
|
||||||
|
type = with types; attrsOf str;
|
||||||
|
default = {};
|
||||||
|
description = "Environment variables to set for this container.";
|
||||||
|
example = literalExample ''
|
||||||
|
{
|
||||||
|
DATABASE_HOST = "db.example.com";
|
||||||
|
DATABASE_PORT = "3306";
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environmentFiles = mkOption {
|
||||||
|
type = with types; listOf path;
|
||||||
|
default = [];
|
||||||
|
description = "Environment files for this container.";
|
||||||
|
example = literalExample ''
|
||||||
|
[
|
||||||
|
/path/to/.env
|
||||||
|
/path/to/.env.secret
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
log-driver = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
default = "journald";
|
||||||
|
description = ''
|
||||||
|
Logging driver for the container. The default of
|
||||||
|
<literal>"journald"</literal> means that the container's logs will be
|
||||||
|
handled as part of the systemd unit.
|
||||||
|
|
||||||
|
For more details and a full list of logging drivers, refer to respective backends documentation.
|
||||||
|
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
ports = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
Network ports to publish from the container to the outer host.
|
||||||
|
|
||||||
|
Valid formats:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal><ip>:<hostPort>:<containerPort></literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal><ip>::<containerPort></literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal><hostPort>:<containerPort></literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
<literal><containerPort></literal>
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
Both <literal>hostPort</literal> and
|
||||||
|
<literal>containerPort</literal> can be specified as a range of
|
||||||
|
ports. When specifying ranges for both, the number of container
|
||||||
|
ports in the range must match the number of host ports in the
|
||||||
|
range. Example: <literal>1234-1236:1234-1236/tcp</literal>
|
||||||
|
|
||||||
|
When specifying a range for <literal>hostPort</literal> only, the
|
||||||
|
<literal>containerPort</literal> must <emphasis>not</emphasis> be a
|
||||||
|
range. In this case, the container port is published somewhere
|
||||||
|
within the specified <literal>hostPort</literal> range. Example:
|
||||||
|
<literal>1234-1236:1234/tcp</literal>
|
||||||
|
|
||||||
|
Refer to the
|
||||||
|
<link xlink:href="https://docs.docker.com/engine/reference/run/#expose-incoming-ports">
|
||||||
|
Docker engine documentation</link> for full details.
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
[
|
||||||
|
"8080:9000"
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
user = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = ''
|
||||||
|
Override the username or UID (and optionally groupname or GID) used
|
||||||
|
in the container.
|
||||||
|
'';
|
||||||
|
example = "nobody:nogroup";
|
||||||
|
};
|
||||||
|
|
||||||
|
volumes = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
description = ''
|
||||||
|
List of volumes to attach to this container.
|
||||||
|
|
||||||
|
Note that this is a list of <literal>"src:dst"</literal> strings to
|
||||||
|
allow for <literal>src</literal> to refer to
|
||||||
|
<literal>/nix/store</literal> paths, which would be difficult with an
|
||||||
|
attribute set. There are also a variety of mount options available
|
||||||
|
as a third field; please refer to the
|
||||||
|
<link xlink:href="https://docs.docker.com/engine/reference/run/#volume-shared-filesystems">
|
||||||
|
docker engine documentation</link> for details.
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
[
|
||||||
|
"volume_name:/path/inside/container"
|
||||||
|
"/path/on/host:/path/inside/container"
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
workdir = mkOption {
|
||||||
|
type = with types; nullOr str;
|
||||||
|
default = null;
|
||||||
|
description = "Override the default working directory for the container.";
|
||||||
|
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 <literal>virtualisation.oci-containers.containers</literal>.
|
||||||
|
'';
|
||||||
|
example = literalExample ''
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
node1 = {};
|
||||||
|
node2 = {
|
||||||
|
dependsOn = [ "node1" ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
extraOptions = mkOption {
|
||||||
|
type = with types; listOf str;
|
||||||
|
default = [];
|
||||||
|
description = "Extra options for <command>${defaultBackend} run</command>.";
|
||||||
|
example = literalExample ''
|
||||||
|
["--network=host"]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
autoStart = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
description = ''
|
||||||
|
When enabled, the container is automatically started on boot.
|
||||||
|
If this option is set to false, the container has to be started on-demand via its service.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mkService = name: container: let
|
||||||
|
dependsOn = map (x: "${cfg.backend}-${x}.service") container.dependsOn;
|
||||||
|
in {
|
||||||
|
wantedBy = [] ++ optional (container.autoStart) "multi-user.target";
|
||||||
|
after = lib.optionals (cfg.backend == "docker") [ "docker.service" "docker.socket" ] ++ dependsOn;
|
||||||
|
requires = dependsOn;
|
||||||
|
environment = proxy_env;
|
||||||
|
|
||||||
|
path =
|
||||||
|
if cfg.backend == "docker" then [ config.virtualisation.docker.package ]
|
||||||
|
else if cfg.backend == "podman" then [ config.virtualisation.podman.package ]
|
||||||
|
else throw "Unhandled backend: ${cfg.backend}";
|
||||||
|
|
||||||
|
preStart = ''
|
||||||
|
${cfg.backend} rm -f ${name} || true
|
||||||
|
${optionalString (container.imageFile != null) ''
|
||||||
|
${cfg.backend} load -i ${container.imageFile}
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Podman likes knowing what systemd unit launched its container,
|
||||||
|
# so that it can auto-update containers and restart them.
|
||||||
|
#
|
||||||
|
# Sadly, the NixOS `script` option doesn't expose the systemd
|
||||||
|
# syntax `%n` that would expose the unit location, so we pass it
|
||||||
|
# as $1 in a scriptArg.
|
||||||
|
scriptArgs = lib.optionals (cfg.backend == "podman") "%n";
|
||||||
|
|
||||||
|
script = concatStringsSep " \\\n " ([
|
||||||
|
"exec ${cfg.backend} run"
|
||||||
|
"--rm"
|
||||||
|
"--name=${escapeShellArg name}"
|
||||||
|
"--log-driver=${container.log-driver}"
|
||||||
|
] ++ optional (container.entrypoint != null)
|
||||||
|
"--entrypoint=${escapeShellArg container.entrypoint}"
|
||||||
|
++ (mapAttrsToList (k: v: "-e ${escapeShellArg k}=${escapeShellArg v}") container.environment)
|
||||||
|
++ optional (cfg.backend == "podman") ''-e 'PODMAN_SYSTEMD_UNIT'="$1"''
|
||||||
|
++ map (f: "--env-file ${escapeShellArg f}") container.environmentFiles
|
||||||
|
++ map (p: "-p ${escapeShellArg p}") container.ports
|
||||||
|
++ optional (container.user != null) "-u ${escapeShellArg container.user}"
|
||||||
|
++ map (v: "-v ${escapeShellArg v}") container.volumes
|
||||||
|
++ optional (container.workdir != null) "-w ${escapeShellArg container.workdir}"
|
||||||
|
++ map escapeShellArg container.extraOptions
|
||||||
|
++ [container.image]
|
||||||
|
++ map escapeShellArg container.cmd
|
||||||
|
);
|
||||||
|
|
||||||
|
preStop = "[ $SERVICE_RESULT = success ] || ${cfg.backend} stop ${name}";
|
||||||
|
postStop = "${cfg.backend} rm -f ${name} || true";
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
StandardOutput = "null";
|
||||||
|
StandardError = "null";
|
||||||
|
|
||||||
|
### There is no generalized way of supporting `reload` for docker
|
||||||
|
### containers. Some containers may respond well to SIGHUP sent to their
|
||||||
|
### init process, but it is not guaranteed; some apps have other reload
|
||||||
|
### mechanisms, some don't have a reload signal at all, and some docker
|
||||||
|
### images just have broken signal handling. The best compromise in this
|
||||||
|
### case is probably to leave ExecReload undefined, so `systemctl reload`
|
||||||
|
### will at least result in an error instead of potentially undefined
|
||||||
|
### behaviour.
|
||||||
|
###
|
||||||
|
### Advanced users can still override this part of the unit to implement
|
||||||
|
### a custom reload handler, since the result of all this is a normal
|
||||||
|
### systemd service from the perspective of the NixOS module system.
|
||||||
|
###
|
||||||
|
# ExecReload = ...;
|
||||||
|
###
|
||||||
|
|
||||||
|
TimeoutStartSec = 0;
|
||||||
|
TimeoutStopSec = 120;
|
||||||
|
Restart = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
];
|
||||||
|
disabledModules = [ "virtualisation/oci-containers.nix" ];
|
||||||
|
|
||||||
|
options.virtualisation.oci-containers = {
|
||||||
|
|
||||||
|
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.";
|
||||||
|
};
|
||||||
|
|
||||||
|
containers = mkOption {
|
||||||
|
default = {};
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue