128 lines
3.9 KiB
Nix
128 lines
3.9 KiB
Nix
{ config, lib, ... }:
|
|
{
|
|
options =
|
|
with lib;
|
|
with types;
|
|
{
|
|
virtualisation.web-containers = {
|
|
enable = mkEnableOption "web containers";
|
|
containers = mkOption {
|
|
type = lazyAttrsOf (submodule {
|
|
options =
|
|
let
|
|
strOpt = mkOption { type = str; };
|
|
intOpt = mkOption { type = int; };
|
|
boolOpt = mkOption {
|
|
type = bool;
|
|
default = false;
|
|
};
|
|
strList = mkOption {
|
|
type = listOf str;
|
|
default = [ ];
|
|
};
|
|
attrOpt = mkOption {
|
|
type = attrsOf str;
|
|
default = { };
|
|
};
|
|
in
|
|
{
|
|
image = strOpt;
|
|
hostname = strOpt;
|
|
port = intOpt;
|
|
homepageOpts = attrOpt;
|
|
dependsOn = strList;
|
|
domain = strOpt;
|
|
volumes = strList;
|
|
environment = attrOpt;
|
|
environmentFiles = strList;
|
|
public = boolOpt;
|
|
user = mkOption {
|
|
type = nullOr str;
|
|
default = null;
|
|
};
|
|
extraOptions = strList;
|
|
oauthProxy = boolOpt;
|
|
extraLabels = attrOpt;
|
|
};
|
|
});
|
|
default = { };
|
|
description = "";
|
|
};
|
|
};
|
|
};
|
|
|
|
config = {
|
|
virtualisation.oci-containers.containers = lib.mkIf config.virtualisation.web-containers.enable (
|
|
let
|
|
hostRule = host: domain: "Host(`${host}.${domain}`)";
|
|
localNet = "192.168.0.0/16";
|
|
dockerNet = "10.88.0.0/16";
|
|
localNetRule = "(ClientIP(`${localNet}`) || ClientIP(`${dockerNet}`))";
|
|
localHostRule = host: domain: "${localNetRule} && ${hostRule host domain}";
|
|
mkContainer =
|
|
key:
|
|
{
|
|
image,
|
|
hostname,
|
|
port,
|
|
homepageOpts,
|
|
dependsOn,
|
|
domain,
|
|
volumes,
|
|
environment,
|
|
environmentFiles,
|
|
public,
|
|
user,
|
|
extraOptions,
|
|
oauthProxy,
|
|
extraLabels,
|
|
}:
|
|
let
|
|
fqn = "${hostname}.${domain}";
|
|
serviceName = lib.strings.replaceChars [ "." ] [ "-" ] fqn;
|
|
routerRule = if public then hostRule hostname domain else localHostRule hostname domain;
|
|
homepageLabels =
|
|
if homepageOpts == { } then
|
|
{ }
|
|
else
|
|
{
|
|
"homepage.group" = "${homepageOpts.group}";
|
|
"homepage.name" = "${homepageOpts.name}";
|
|
"homepage.icon" = "${homepageOpts.icon}";
|
|
"homepage.href" = "https://${fqn}";
|
|
"homepage.description" = "${homepageOpts.description}";
|
|
};
|
|
oauthLabels =
|
|
if oauthProxy then
|
|
{ "traefik.http.routers.${serviceName}.middlewares" = "oidc-auth@file"; }
|
|
else
|
|
{ };
|
|
in
|
|
{
|
|
inherit
|
|
image
|
|
dependsOn
|
|
volumes
|
|
environment
|
|
environmentFiles
|
|
user
|
|
extraOptions
|
|
;
|
|
autoStart = true;
|
|
labels =
|
|
{
|
|
"traefik.enable" = "true";
|
|
"traefik.http.routers.${serviceName}.rule" = "${routerRule}";
|
|
"traefik.http.routers.${serviceName}.service" = "${serviceName}";
|
|
"traefik.http.services.${serviceName}.loadbalancer.server.port" = "${toString port}";
|
|
}
|
|
// oauthLabels
|
|
// homepageLabels
|
|
// extraLabels;
|
|
};
|
|
in
|
|
builtins.mapAttrs mkContainer config.virtualisation.web-containers.containers
|
|
);
|
|
};
|
|
}
|