diff --git a/hosts/busch-nixos-native/default.nix b/hosts/busch-nixos-native/default.nix index e33ed9c..d3b5dec 100644 --- a/hosts/busch-nixos-native/default.nix +++ b/hosts/busch-nixos-native/default.nix @@ -46,11 +46,13 @@ services.renovate = { enable = true; + schedule = "*:0/10"; credentials = { RENOVATE_TOKEN = config.age.secrets.renovate-token.path; RENOVATE_GITHUB_COM_TOKEN = config.age.secrets.renovate-github-com-token.path; }; settings = { + autodiscover = true; gitAuthor = "Renovate Bot "; platform = "forgejo"; endpoint = "https://git.jfreudenberger.de"; diff --git a/modules/arcane.nix b/modules/arcane.nix new file mode 100644 index 0000000..160088f --- /dev/null +++ b/modules/arcane.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + ... +}: +let + cfg = config.services.arcane; +in { + options.services.arcane = { + enable = lib.mkEnableOption "arcane, a modern Docker management UI"; + appUrl = lib.mkOption { + description = "External URL arcane will be reachable from, without protocol"; + type = lib.types.str; + }; + secretFile = lib.mkOption { + description = '' + Agenix secret containing the following needed environment variables in dotenv notation: + - ENCRYPTION_KEY + - JWT_SECRET + - OIDC_CLIENT_ID + - OIDC_CLIENT_SECRET + - OIDC_ISSUER_URL + - OIDC_ADMIN_CLAIM + - OIDC_ADMIN_VALUE + ''; + }; + }; + + config = lib.mkIf cfg.enable { + virtualisation.oci-containers.containers = { + arcane = { + image = "ghcr.io/getarcaneapp/arcane:v1.11.2"; + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock" + ]; + environment = { + APP_URL = "https://${cfg.appUrl}"; + PUID = "1000"; + PGID = "1000"; + LOG_LEVEL = "info"; + LOG_JSON = "false"; + OIDC_ENABLED = "true"; + OIDC_SCOPES = "openid email profile groups"; + DATABASE_URL = "file:data/arcane.db?_pragma=journal_mode(WAL)&_pragma=busy_timeout(2500)&_txlock=immediate"; + }; + environmentFiles = [ + cfg.secretFile.path + ]; + networks = [ + "traefik" + ]; + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.arcane.middlewares" = "arcane-oidc-auth@file"; + "traefik.http.routers.arcane.rule" = "Host(`${cfg.appUrl}`)"; + "traefik.http.services.arcane.loadbalancer.server.port" = "3552"; + }; + extraOptions = [ + ''--mount=type=volume,source=arcane-data,target=/app/data,volume-driver=local'' + ]; + }; + }; + }; +} diff --git a/modules/beszel-hub.nix b/modules/beszel-hub.nix index 7ea1024..7b2376a 100644 --- a/modules/beszel-hub.nix +++ b/modules/beszel-hub.nix @@ -6,6 +6,7 @@ let cfg = config.services.beszel-docker; + version = "0.18.7"; in { @@ -20,7 +21,7 @@ in { config = lib.mkIf cfg.enable { virtualisation.oci-containers.containers = { beszel = { - image = "henrygd/beszel:0.18.7@sha256:a849ad80814b6a1a3be665304dcace5d4854b3bed7bde4dd1227e8ce1b82d477"; + image = "henrygd/beszel:${version}"; autoStart = true; networks = [ "traefik" diff --git a/modules/dockhand.nix b/modules/dockhand.nix index 82c541b..0d7fabe 100644 --- a/modules/dockhand.nix +++ b/modules/dockhand.nix @@ -17,7 +17,7 @@ in { config = lib.mkIf cfg.enable { virtualisation.oci-containers.containers = { dockhand = { - image = "fnsys/dockhand:v1.0.32@sha256:cda754fc7ccb4acd0ecc37cc37b9cf0d2b933bf19de89d47957b26ecf109a543"; + image = "fnsys/dockhand:v1.0.32"; volumes = [ "/var/run/docker.sock:/var/run/docker.sock" ]; diff --git a/modules/hawser.nix b/modules/hawser.nix index e304abe..5d48686 100644 --- a/modules/hawser.nix +++ b/modules/hawser.nix @@ -27,7 +27,7 @@ in { config = lib.mkIf cfg.enable { virtualisation.oci-containers.containers = { hawser = { - image = "ghcr.io/finsys/hawser:0.2.42@sha256:79f926e8d8fe31c0dfe90858f90b69bfd4cfbb113472605620b91a4b444dd557"; + image = "ghcr.io/finsys/hawser:0.2.42"; volumes = [ "/var/run/docker.sock:/var/run/docker.sock" ]; diff --git a/modules/netbird-client.nix b/modules/netbird-client.nix index 7651800..200984f 100644 --- a/modules/netbird-client.nix +++ b/modules/netbird-client.nix @@ -9,6 +9,8 @@ let cfg = config.services.netbird-client; + clientVersion = "0.72.4"; + clientConfiguration = lib.types.submodule { options = { setupKey = lib.mkOption { @@ -62,7 +64,7 @@ in { virtualisation.oci-containers.containers = lib.mkIf (cfg.docker.setupKey != null) { netbird = { - image = "netbirdio/netbird:0.72.4-rootless@sha256:d42136aabccb82c5237d2ee73febde237e13e850727bcb6bbf5b3c8717ece142"; + image = "netbirdio/netbird:${clientVersion}-rootless"; autoStart = true; hostname = "${config.networking.hostName}-docker"; networks = [ diff --git a/modules/netbird-docker.nix b/modules/netbird-docker.nix index 8d137f2..a8faeb3 100644 --- a/modules/netbird-docker.nix +++ b/modules/netbird-docker.nix @@ -10,6 +10,9 @@ let cfg = config.services.netbird-docker; netbirdCfg = config.services.netbird; + serverVersion = "0.72.4"; + dashboardVersion = "2.39.0"; + in { options.services.netbird-docker = { @@ -57,7 +60,7 @@ in { services.netbird.useRoutingFeatures = lib.mkDefault "server"; virtualisation.oci-containers.containers = { netbird-dashboard = { - image = "netbirdio/dashboard:v2.39.0"; + image = "netbirdio/dashboard:v${dashboardVersion}"; autoStart = true; networks = [ "traefik" @@ -91,7 +94,7 @@ in { ]; }; netbird-server = { - image = "netbirdio/netbird-server:0.72.4@sha256:9ab98a37002517204010ee88a0c7f5e76b1fe6e2a736043db60efb7a02fbded3"; + image = "netbirdio/netbird-server:${serverVersion}"; autoStart = true; networks = [ "traefik" @@ -169,7 +172,7 @@ in { ]; }; netbird-proxy = { - image = "netbirdio/reverse-proxy:0.72.4@sha256:3104d5ca3a76ac224d268b9cc1d2f983eaf6fefbbb1cc78c3dbecd07f9d2a7e0"; + image = "netbirdio/reverse-proxy:${serverVersion}"; autoStart = true; ports = [ "51820:51820/udp" diff --git a/modules/newt.nix b/modules/newt.nix new file mode 100644 index 0000000..5f7a8f4 --- /dev/null +++ b/modules/newt.nix @@ -0,0 +1,72 @@ +{ + pkgs, + config, + lib, + ... +}: +let + + cfg = config.services.newt-docker; + +in { + + options.services.newt-docker = { + enable = lib.mkEnableOption "Newt, user space tunnel client for Pangolin"; + pangolinEndpoint = lib.mkOption { + description = "External URL of the Pangolin instance"; + type = lib.types.str; + }; + connectionSecret = lib.mkOption { + description = "Secrets for Pangolin authentication."; + type = lib.types.anything; + }; + }; + + config = lib.mkIf cfg.enable { + virtualisation.oci-containers.containers = { + newt = { + image = "fosrl/newt:1.9.0"; + autoStart = true; + networks = [ + "pangolin" + ]; + environment = { + PANGOLIN_ENDPOINT = cfg.pangolinEndpoint; + DOCKER_SOCKET = "/var/run/docker.sock"; + }; + environmentFiles = [ cfg.connectionSecret.path ]; + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock:ro" + ]; + extraOptions = [ + "--add-host=host.docker.internal:host-gateway" + ]; + }; + }; + + systemd.services."docker-newt" = { + after = [ + "docker-network-newt.service" + ]; + requires = [ + "docker-network-newt.service" + ]; + }; + + systemd.services."docker-network-newt" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + }; + script = '' + docker network inspect pangolin || docker network create pangolin --ipv4 --ipv6 --subnet=172.18.0.0/16 --gateway=172.18.0.1 + ''; + }; + + networking.firewall.extraCommands = '' + iptables -A INPUT -p icmp --source 100.89.128.0/24 -j ACCEPT + iptables -A INPUT -p tcp --source 172.18.0.0/12 --dport 22 -j ACCEPT + ''; + + }; +} diff --git a/modules/pangolin.nix b/modules/pangolin.nix new file mode 100644 index 0000000..55e5fed --- /dev/null +++ b/modules/pangolin.nix @@ -0,0 +1,53 @@ +{ + pkgs-unstable, + utils, + config, + lib, + ... +}: { + + services = { + pangolin = { + enable = true; + package = pkgs-unstable.fosrl-pangolin; + openFirewall = true; + settings = { + app = { + save_logs = true; + log_failed_attempts = true; + }; + domains = { + domain1 = { + prefer_wildcard_cert = true; + }; + }; + flags = { + disable_signup_without_invite = true; + disable_user_create_org = true; + }; + }; + }; + }; + + systemd.services.gerbil.serviceConfig.ExecStart = lib.mkForce (utils.escapeSystemdExecArgs [ + (lib.getExe pkgs-unstable.fosrl-gerbil) + "--reachableAt=http://localhost:${toString config.services.gerbil.port}" + "--generateAndSaveKeyTo=${toString config.services.pangolin.dataDir}/config/key" + "--remoteConfig=http://localhost:3001/api/v1/gerbil/get-config" + ]); + +} + +# Settings needed on the host +# +# services = { +# pangolin = { +# dnsProvider = ""; +# baseDomain = ""; +# letsEncryptEmail = ""; +# environmentFile = config.age.secrets."".path; +# }; +# traefik = { +# environmentFiles = [ config.age.secrets."".path ]; +# }; +# }; diff --git a/modules/pocket-id.nix b/modules/pocket-id.nix index b183d4b..fd311c1 100644 --- a/modules/pocket-id.nix +++ b/modules/pocket-id.nix @@ -7,6 +7,7 @@ let cfg = config.services.pocket-id-docker; pocketidCfg = config.services.pocket-id; + version = "2.8.0"; in { @@ -17,7 +18,7 @@ in { config = lib.mkIf cfg.enable { virtualisation.oci-containers.containers = { pocket-id = { - image = "ghcr.io/pocket-id/pocket-id:v2.8.0@sha256:a073640418b2cfc8587c488a7270580b3ab95cae2c543f5d64bbbe1fd7ccbae8"; + image = "ghcr.io/pocket-id/pocket-id:v${version}"; autoStart = true; networks = [ "traefik" diff --git a/modules/portainer_agent.nix b/modules/portainer_agent.nix new file mode 100644 index 0000000..408834b --- /dev/null +++ b/modules/portainer_agent.nix @@ -0,0 +1,21 @@ +{ + ... +}: { + virtualisation.oci-containers.containers = { + portainer_agent = { + image = "portainer/agent:2.33.2"; + volumes = [ + "/var/run/docker.sock:/var/run/docker.sock" + "/var/lib/docker/volumes:/var/lib/docker/volumes" + "/:/host" + ]; + environment = { + EDGE = "1"; + CAP_HOST_MANAGEMENT = "1"; + }; + extraOptions = [ + ''--mount=type=volume,source=portainer_agent,target=/data,volume-driver=local'' + ]; + }; + }; +} diff --git a/modules/traefik-oidc.nix b/modules/traefik-oidc.nix index aa3f80c..c1bff3f 100644 --- a/modules/traefik-oidc.nix +++ b/modules/traefik-oidc.nix @@ -105,7 +105,7 @@ in { config = lib.mkIf cfg.enable { virtualisation.oci-containers.containers = { traefik = { - image = "traefik:v3.7.5@sha256:d6858791f9e74df44ca4014166647c41cdc2abd3bf2a71b832ca4e1c6a91b257"; + image = "traefik:v3.6.6"; cmd = [ "--providers.docker=true" "--providers.docker.exposedByDefault=false" diff --git a/modules/traefik.nix b/modules/traefik.nix index 1709d0b..7e8e19c 100644 --- a/modules/traefik.nix +++ b/modules/traefik.nix @@ -7,6 +7,7 @@ let cfg = config.services.traefik-docker; + version = "3.7.5"; in { @@ -29,7 +30,7 @@ in { config = lib.mkIf cfg.enable { virtualisation.oci-containers.containers = { traefik = { - image = "traefik:v3.7.5@sha256:d6858791f9e74df44ca4014166647c41cdc2abd3bf2a71b832ca4e1c6a91b257"; + image = "traefik:v${version}"; cmd = [ "--providers.docker=true" "--providers.docker.endpoint=http://docker-socket-proxy:2375" diff --git a/renovate.json b/renovate.json deleted file mode 100644 index e25b3b1..0000000 --- a/renovate.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "prHourlyLimit": 0, - "nix": { - "enabled": true - }, - "customManagers": [ - { - "customType": "regex", - "datasourceTemplate": "docker", - "fileMatch": [ - ".+\\.nix$" - ], - "matchStrings": [ - "\\s+image\\s+=\\s+\"(?.*?):(?.*?)(@(?sha256:[a-z0-9]{64}))?\"" - ] - } - ] -}