152 lines
5.5 KiB
Nix
152 lines
5.5 KiB
Nix
{ lib, config, pkgs }:
|
|
|
|
with lib;
|
|
|
|
{
|
|
mkPodmanService = {
|
|
description,
|
|
name,
|
|
secondName ? null,
|
|
thirdName ? null,
|
|
defaultSubdomain ? name,
|
|
secondDefaultSubdomain ? secondName,
|
|
thirdDefaultSubdomain ? thirdName,
|
|
defaultPort ? "",
|
|
secondDefaultPort ? "",
|
|
thirdDefaultPort ? "",
|
|
scheme ? "http",
|
|
secondScheme ? "http",
|
|
thirdScheme ? "http",
|
|
reverseProxied ? true,
|
|
secondReverseProxied ? false,
|
|
thirdReverseProxied ? false,
|
|
configDirEnabled ? true,
|
|
secondConfigDirEnabled ? false,
|
|
thirdConfigDirEnabled ? false,
|
|
dataDirEnabled ? true,
|
|
secondDataDirEnabled ? false,
|
|
thirdDataDirEnabled ? false,
|
|
pod ? "false",
|
|
composeText,
|
|
extraOptions ? {},
|
|
extraConfig ? {},
|
|
delaySec ? 180,
|
|
useSopsSecrets ? false, # New argument to enable sops integration
|
|
middlewares ? [ "secureHeaders" ],
|
|
dependencies ? [ "traefik.service" "${config.numbus.services.dns}.service" ],
|
|
}:
|
|
let
|
|
mkServiceOpts = svcName: svcDesc: svcPort: svcSubdomain: svcReverseProxied: svcConfigDir: svcDataDir:
|
|
{
|
|
numbus.services.${svcName} = {
|
|
enable = mkEnableOption svcDesc;
|
|
|
|
subdomain = mkOption {
|
|
type = types.str;
|
|
default = svcSubdomain;
|
|
example = svcSubdomain;
|
|
description = "The subdomain that ${svcName} will use";
|
|
};
|
|
|
|
port = mkOption {
|
|
type = types.str;
|
|
default = svcPort;
|
|
example = svcPort;
|
|
description = "The port that ${svcName} will use.";
|
|
};
|
|
|
|
reverseProxied = mkOption {
|
|
type = types.bool;
|
|
default = svcReverseProxied;
|
|
description = "Whether to create a Traefik reverse proxy configuration for this service.";
|
|
};
|
|
} // (optionalAttrs svcConfigDir {
|
|
configDir = mkOption {
|
|
type = types.str;
|
|
default = "/mnt/config/${svcName}";
|
|
example = "/mnt/config/${svcName}";
|
|
description = "The directory where ${svcName}'s configuration files will be stored";
|
|
};
|
|
}) // (optionalAttrs svcDataDir {
|
|
dataDir = mkOption {
|
|
type = types.str;
|
|
default = "/mnt/data/${svcName}";
|
|
example = "/mnt/data/${svcName}";
|
|
description = "The directory where ${svcName}'s data will be stored";
|
|
};
|
|
});
|
|
};
|
|
|
|
cfg = config.numbus.services.${name};
|
|
cfg2 = if secondName != null then config.numbus.services.${secondName} else {};
|
|
cfg3 = if thirdName != null then config.numbus.services.${thirdName} else {};
|
|
|
|
mkTraefikConfig = svcName: svcCfg: svcScheme:
|
|
mkIf (cfg.enable && svcCfg.reverseProxied) {
|
|
text = ''
|
|
http:
|
|
routers:
|
|
${svcName}:
|
|
rule: "Host(`${svcCfg.subdomain}.${config.numbus.services.domain}`)"
|
|
entrypoints:
|
|
- "websecure"
|
|
service: ${svcName}
|
|
middlewares:
|
|
${concatStringsSep "\n" (map (m: " - ${m}") middlewares)}
|
|
tls:
|
|
certresolver: "cloudflare"
|
|
options: "secureTLS"
|
|
services:
|
|
${svcName}:
|
|
loadBalancer:
|
|
servers:
|
|
- url: "${svcScheme}://host.containers.internal:${svcCfg.port}"
|
|
'';
|
|
};
|
|
in
|
|
{
|
|
options = mkMerge [
|
|
(mkServiceOpts name description defaultPort defaultSubdomain reverseProxied configDirEnabled dataDirEnabled)
|
|
(optionalAttrs (secondName != null) (mkServiceOpts secondName "Secondary service for ${name}" secondDefaultPort secondDefaultSubdomain secondReverseProxied secondConfigDirEnabled secondDataDirEnabled))
|
|
(optionalAttrs (thirdName != null) (mkServiceOpts thirdName "Tertiary service for ${name}" thirdDefaultPort thirdDefaultSubdomain thirdReverseProxied thirdConfigDirEnabled thirdDataDirEnabled))
|
|
{ numbus.services.${name} = extraOptions; }
|
|
];
|
|
|
|
config = mkIf cfg.enable (mkMerge [
|
|
{
|
|
environment.etc."podman/${name}/compose.yaml".text = composeText;
|
|
|
|
environment.etc = mkMerge [
|
|
{ "${config.numbus.traefikDynamicConfigDir}/${name}.yaml" = mkTraefikConfig name cfg scheme; }
|
|
(mkIf (secondName != null) {
|
|
"${config.numbus.traefikDynamicConfigDir}/${secondName}.yaml" = mkTraefikConfig secondName cfg2 secondScheme;
|
|
})
|
|
(mkIf (thirdName != null) {
|
|
"${config.numbus.traefikDynamicConfigDir}/${thirdName}.yaml" = mkTraefikConfig thirdName cfg3 thirdScheme;
|
|
})
|
|
];
|
|
|
|
systemd.services."${name}" = {
|
|
description = "Podman container : ${name}";
|
|
requires = dependencies;
|
|
after = dependencies;
|
|
wantedBy = [ "multi-user.target" ];
|
|
path = [ pkgs.podman pkgs.podman-compose pkgs.coreutils pkgs.sudo ];
|
|
serviceConfig = {
|
|
Type = "exec";
|
|
ExecStartPre = [
|
|
"bash -c 'sleep $((RANDOM % ${toString delaySec}))'"
|
|
"- sudo -u numbus-admin podman-compose -f /etc/podman/${name}/compose.yaml pull"
|
|
];
|
|
ExecStart = "sudo -u numbus-admin podman-compose --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml up --remove-orphans";
|
|
ExecStop = "sudo -u numbus-admin podman-compose --in-pod ${toString pod} -f /etc/podman/${name}/compose.yaml down";
|
|
Restart = "on-failure";
|
|
RestartSec = "1m";
|
|
StartLimitBurst = "5";
|
|
};
|
|
};
|
|
}
|
|
extraConfig
|
|
]);
|
|
};
|
|
} |