diff --git a/system/virtualization/containers/authentik/default.nix b/system/virtualization/containers/authentik/default.nix deleted file mode 100644 index 98d0d03..0000000 --- a/system/virtualization/containers/authentik/default.nix +++ /dev/null @@ -1,71 +0,0 @@ -{ config, lib, ... }: { - - options.sysconfig.containers.authentik.enable = lib.options.mkOption { - type = lib.types.bool; - default = false; - }; - - config = lib.mkIf config.sysconfig.containers.authentik.enable { - - sops.secrets."authentik/dbpass" = {}; - - networking = { - - nat.internalInterfaces = [ "ve-authentik" ]; - }; - - containers.authentik = { - - autoStart = true; - privateNetwork = true; - hostAddress = "192.168.100.10"; - localAddress = "192.168.100.35"; - - extraFlags = [ - "--load-credential=dbpass:${config.sops.secrets."authentik/dbpass".path}" - ]; - - bindMounts = { - "/etc/authentik" = { - hostPath = "/ssd1/Authentik"; - isReadOnly = false; - }; - }; - - config = { - - networking.firewall.allowedTCPPorts = [ 9001 ]; - - systemd.services.secrets_setup = { - wantedBy = [ "authentik.service" ]; - - serviceConfig = { - LoadCredential = [ - "dbpass" - ]; - }; - - script = '' - cat ''${CREDENTIALS_DIRECTORY}/dbpass > /etc/authentik/dbpass - chown postgres:postgres /etc/authentik/dbpass - ''; - }; - - services.authentik = { - enable = true; - - environmentFile = "/etc/authentik/authentik.env"; - - settings = { - disable_startup_analytics = true; - avatars = "initials"; - }; - - worker.listenHTTP = "0.0.0.0:9001"; - }; - - system.stateVersion = "25.05"; - }; - }; - }; -} diff --git a/system/virtualization/containers/jellyfin/default.nix b/system/virtualization/containers/jellyfin/default.nix deleted file mode 100644 index f425251..0000000 --- a/system/virtualization/containers/jellyfin/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ config, lib, ... }: { - - options.sysconfig.containers.jellyfin.enable = lib.options.mkOption { - type = lib.types.bool; - default = false; - }; - - config = lib.mkIf config.sysconfig.containers.jellyfin.enable { - - containers.jellyfin = { - - autoStart = true; - privateNetwork = true; - hostAddress = "192.168.100.10"; - localAddress = "192.168.100.14"; - - bindMounts = { - "/etc/jellyfin" = { - hostPath = "/ssd1/Jellyfin"; - isReadOnly = false; - }; - }; - - config = { - - services.jellyfin = { - - enable = true; - dataDir = "/etc/jellyfin/data"; - configDir = "/etc/jellyfin/config"; - logDir = "/etc/jellyfin/log"; - openFirewall = true; - }; - - system.stateVersion = "24.05"; - }; - }; - }; -} diff --git a/system/virtualization/containers/nextcloud/default.nix b/system/virtualization/containers/nextcloud/default.nix deleted file mode 100644 index 028cd06..0000000 --- a/system/virtualization/containers/nextcloud/default.nix +++ /dev/null @@ -1,81 +0,0 @@ -{ config, lib, ... }: { - - options.sysconfig.containers.nextcloud.enable = lib.options.mkOption { - type = lib.types.bool; - default = false; - }; - - config = lib.mkIf config.sysconfig.containers.nextcloud.enable { - - sops.secrets."nextcloud/pass" = {}; - - containers.nextcloud = { - - autoStart = true; - privateNetwork = true; - hostAddress = "192.168.100.10"; - localAddress = "192.168.100.15"; - - bindMounts = { - - "/var/lib/nextcloud" = { - hostPath = "/ssd1/Nextcloud/data"; - isReadOnly = false; - }; - - }; - - extraFlags = [ - "--load-credential=nextcloud-admin-pass:${config.sops.secrets."nextcloud/pass".path}" - ]; - - config = { config, lib, pkgs, ... }: { - - systemd.services.secrets_setup = { - wantedBy = [ "nextcloud-setup.service" ]; - - serviceConfig = { - LoadCredential = [ - "nextcloud-admin-pass" - ]; - }; - - script = '' - cat $CREDENTIALS_DIRECTORY/nextcloud-admin-pass > /etc/nextcloud-admin-pass - chown nextcloud:nextcloud /etc/nextcloud-admin-pass - ''; - }; - - networking.firewall.allowedTCPPorts = [ 80 443 ]; - services.nginx.virtualHosts."192.168.100.15".listen = [ { addr = "0.0.0.0"; port = 80; } ]; - services.nextcloud = { - enable = true; - package = pkgs.nextcloud32; - hostName = "192.168.100.15"; - config = { - adminpassFile = "/etc/nextcloud-admin-pass"; - adminuser = "root"; - dbtype = "mysql"; - }; - https = true; - home = "/var/lib/nextcloud"; - appstoreEnable = true; - extraApps = with config.services.nextcloud.package.packages.apps; { - inherit mail contacts calendar tasks user_oidc; - inherit impersonate end_to_end_encryption notes spreed music memories phonetrack; - }; - extraAppsEnable = true; - settings = { - overwriteprotocol = "https"; - trusted_domains = [ "nextcloud.esotericbytes.com" ]; - trusted_proxies = [ "192.168.100.11" ]; - default_phone_region = "US"; - }; - database.createLocally = true; - }; - - system.stateVersion = "24.05"; - }; - }; - }; -} diff --git a/system/virtualization/containers/openwebui/default.nix b/system/virtualization/containers/openwebui/default.nix deleted file mode 100644 index bab04c9..0000000 --- a/system/virtualization/containers/openwebui/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ config, lib, nixpkgs-us, ... }: { - - options = { - sysconfig.containers.openwebui.enable = lib.options.mkOption { - type = lib.types.bool; - default = false; - }; - }; - - config = lib.mkIf config.sysconfig.containers.openwebui.enable { - - containers.openwebui = { - - autoStart = true; - privateNetwork = true; - hostAddress = "192.168.100.10"; - localAddress = "192.168.100.33"; - - config = { - - services.open-webui = { - enable = true; - package = let - pkgs-us = import nixpkgs-us { - system = "x86_64-linux"; - config.allowUnfree = true; - }; - in pkgs-us.open-webui; - - openFirewall = true; - host = "0.0.0.0"; - }; - - system.stateVersion = "25.05"; - }; - }; - - }; -} diff --git a/system/virtualization/containers/traefik/default.nix b/system/virtualization/containers/traefik/default.nix deleted file mode 100644 index 1f945c8..0000000 --- a/system/virtualization/containers/traefik/default.nix +++ /dev/null @@ -1,292 +0,0 @@ -{ config, lib, ... }: { - - options.sysconfig.containers.traefik.enable = lib.options.mkOption { - type = lib.types.bool; - default = false; - }; - - config = lib.mkIf config.sysconfig.containers.traefik.enable { - - networking = { - hosts."192.168.100.11" = [ - - "esotericbytes.com" - "*.esotericbytes.com" - ]; - - firewall.allowedTCPPorts = [ 22 80 443 ]; - - nat.internalInterfaces = [ "ve-traefik" ]; - }; - - containers.traefik = { - - autoStart = true; - privateNetwork = true; - hostAddress = "192.168.100.10"; - localAddress = "192.168.100.11"; - forwardPorts = [ - { - containerPort = 81; - hostPort = 80; - } - { - containerPort = 444; - hostPort = 443; - } - ]; - - bindMounts = { - "/etc/traefik/data" = { - hostPath = "/ssd1/Traefik/data"; - isReadOnly = false; - }; - - "/var/run/docker.sock" = lib.mkIf config.sysconfig.docker.enable { - hostPath = "/run/docker.sock"; - isReadOnly = false; - }; - }; - - config = { - - environment.etc."resolv.conf" = { - enable = true; - text = '' - nameserver 1.1.1.1 - nameserver 1.0.0.1 - options edns0 - ''; - - user = "root"; - mode = "0664"; - }; - - #virtualisation.docker.enable = lib.mkIf config.sysconfig.docker.enable true; - - users.groups."docker" = lib.mkIf config.sysconfig.docker.enable { - name = "docker"; - gid = 131; - members = [ - "traefik" - ]; - }; - - services.traefik = { - - enable = true; - - group = lib.mkIf config.sysconfig.docker.enable "docker"; - - dataDir = "/etc/traefik/data"; - - environmentFiles = [ - "/etc/traefik/data/traefik.env" - ]; - - staticConfigOptions = { - serversTransport.insecureSkipVerify = true; - api = { - dashboard = true; - debug = true; - }; - global = { - checknewversion = false; - sendanonymoususage = false; - }; - - providers.docker = lib.mkIf config.sysconfig.docker.enable {}; - - entryPoints = { - - web = { - address = ":81"; - http.redirections.entryPoint = { - to = "websecure"; - scheme = "https"; - }; - }; - - websecure = { - address = ":444"; - asDefault = true; - http.tls = { - certResolver = "cloudflare"; - domains = { - main = "esotericbytes.com"; - sans = [ - "*.esotericbytes.com" - ]; - }; - }; - }; - - local = { - address = ":80"; - http.redirections.entryPoint = { - to = "localsecure"; - scheme = "https"; - }; - }; - - localsecure = { - address = ":443"; - asDefault = true; - http.tls = { - certResolver = "cloudflare"; - domains = { - main = "esotericbytes.com"; - sans = [ - "*.esotericbytes.com" - ]; - }; - }; - }; - }; - log = { - level = "INFO"; - filePath = "/etc/traefik/data/logs/traefik.log"; - format = "json"; - }; - certificatesResolvers = { - cloudflare = { - acme = { - email = "nathanblunkall5@gmail.com"; - storage = "/etc/traefik/data/acme.json"; - keyType = "EC256"; - dnsChallenge = { - provider = "cloudflare"; - resolvers = [ "1.1.1.1:53" "1.0.0.1:53" ]; - }; - }; - }; - }; - }; - - dynamicConfigOptions = { - http = { - routers = { - homepageSecure = { - entryPoints = [ "websecure" "localsecure" ]; - rule = "Host(`esotericbytes.com`) || Host(`www.esotericbytes.com`)"; - service = "homepage"; - tls.certResolver = "cloudflare"; - }; - /*remote = { - entryPoints = [ "websecure" ]; - rule = "Host(`remote.esotericbytes.com`)"; - service = "novnc"; - tls.certResolver = "cloudflare"; - #middlewares = [ "authentik" ]; - };*/ - /*homeassistant = { - entryPoints = [ "localsecure" ]; - rule = "Host(`hass.esotericbytes.com`)"; - service = "homeassistant"; - tls.certResolver = "cloudflare"; - };*/ - jellyfin = { - entryPoints = [ "websecure" "localsecure" ]; - rule = "Host(`jellyfin.esotericbytes.com`)"; - service = "jellyfin"; - tls.certResolver = "cloudflare"; - }; - - /*gitlab = { - entryPoints = [ "websecure" ]; - rule = "Host(`gitlab.esotericbytes.com`)"; - service = "gitlab"; - tls.certResolver = "cloudflare"; - };*/ - gitea = { - entryPoints = [ "websecure" "localsecure" ]; - rule = "Host(`gitea.esotericbytes.com`)"; - service = "gitea"; - tls.certResolver = "cloudflare"; - }; - nextcloud = { - entryPoints = [ "websecure" "localsecure" ]; - rule = "Host(`nextcloud.esotericbytes.com`)"; - service = "nextcloud"; - tls.certResolver = "cloudflare"; - middlewares = [ - "nextcloud_redirectregex" - ]; - }; - traefik = { - entryPoints = [ "localsecure" ]; - rule = "Host(`traefik.esotericbytes.com`)"; - service = "api@internal"; - tls.certResolver = "cloudflare"; - #middlewares = [ "authentik" ]; - }; - /*ntfy = { - entryPoints = [ "websecure" ]; - rule = "Host(`ntfy.esotericbytes.com`)"; - service = "ntfy"; - tls.certResolver = "cloudflare"; - };*/ - - openwebui = { - entryPoints = [ "localsecure" ]; - rule = "Host(`ai.esotericbytes.com`)"; - service = "openwebui"; - tls.certResolver = "cloudflare"; - }; - - code-server = { - entryPoints = [ "localsecure" ]; - rule = "Host(`code.esotericbytes.com`)"; - service = "code-server"; - tls.certResolver = "cloudflare"; - }; - }; - - middlewares = { - - nextcloud_redirectregex.redirectregex = { - permanent = true; - regex = "https://nextcloud.esotericbytes.com/.well-known/(?:card|cal)dav"; - replacement = "https://nextcloud.esotericbytes.com/remote.php/dav"; - }; - }; - - services = { - #gitlab.loadBalancer.servers = [ { url = "http://192.168.100.16:80"; } ]; - - gitea.loadBalancer.servers = [ { url = "http://192.168.100.20:3000"; } ]; - - homepage.loadBalancer.servers = [ { url = "http://192.168.100.13:80"; } ]; - - jellyfin.loadBalancer.servers = [ { url = "http://192.168.100.14:8096"; } ]; - - #novnc.loadBalancer.servers = [ { url = "http://192.168.100.10:6080"; } ]; - - nextcloud.loadBalancer.servers = [ { url = "http://192.168.100.15:80"; } ]; - - #ntfy.loadBalancer.servers = [ { url = "http://192.168.100.19"; } ]; - - openwebui.loadBalancer.servers = [ { url = "http://192.168.100.33:8080"; } ]; - - code-server.loadBalancer.servers = [ { url = "http://192.168.100.31:4444"; } ]; - - /*homeassistant.loadBalancer.servers = [ { url = "http://192.168.100.25:8123"; } ];*/ - }; - }; - }; - }; - - networking = { - firewall = { - allowedTCPPorts = [ 80 443 81 444 ]; - allowedUDPPorts = [ 80 443 81 444 ]; - }; - - useHostResolvConf = false; - }; - - system.stateVersion = "24.05"; - }; - }; - }; -} diff --git a/system/virtualization/docker/gitea/default.nix b/system/virtualization/docker/gitea/default.nix index 0967ef4..f282129 100644 --- a/system/virtualization/docker/gitea/default.nix +++ b/system/virtualization/docker/gitea/default.nix @@ -1 +1,151 @@ -{} +{ config, lib, pkgs, ... }: let + + subdomain = "gitea"; + + name = "gitea"; + +in { + + options.sysconfig.docker."${name}".enable = with lib; mkOption { + type = with types; bool; + default = false; + }; + + config = lib.mkIf (config.sysconfig.docker."${name}".enable && config.sysconfig.docker.enable) { + + + virtualisation.oci-containers.containers."${name}" = { + image = "docker.gitea.com/gitea:1.25.4"; + + # unstable, waiting for 26.05 + #pull = "newer"; + + hostname = "${subdomain}.esotericbytes.com"; + + networks = [ + "docker-main" + ]; + + labels = { + "traefik.enable" = "true"; + "traefik.http.routers.${name}.entrypoints" = "localsecure"; + "traefik.http.routers.${name}.rule" = "Host(`${subdomain}.esotericbytes.com`)"; + "traefik.http.routers.${name}.service" = "${name}"; + "traefik.http.routers.${name}.tls.certResolver" = "cloudflare"; + + "traefik.http.services.${name}.loadbalancer.server.port" = "3000"; + + + "traefik.tcp.routers.${name}-ssh.entrypoints" = "gitea-ssh"; + "traefik.tcp.routers.${name}-ssh.rule" = "HostSNI(`*`)"; + "traefik.tcp.routers.${name}-ssh.service" = "${name}-ssh"; + + "traefik.tcp.services.${name}-ssh.loadbalancer.server.port" = "22"; + }; + + ports = [ + ]; + + extraOptions = [ + "--ip=192.168.101.20" + ]; + + volumes = [ + "vol_gitea:/data" + ]; + + environment = { + }; + }; + + virtualisation.oci-containers.containers."${name}-db" = { + image = "docker.io/library/postgres:14"; + + # unstable, waiting for 26.05 + #pull = "newer"; + + hostname = "${name}-db"; + + networks = [ + "docker-main" + ]; + + labels = { + }; + + ports = [ + ]; + + extraOptions = [ + "--ip=192.168.101.21" + ]; + + volumes = [ + "/etc/gitea/db:/var/lib/postgresql/data" + ]; + + environment = { + }; + }; + + systemd.services."docker-gitea" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-setup.service" + "docker-volume-gitea.service" + "docker-gitea-db.service" + ]; + requires = [ + "docker-network-setup.service" + "docker-volume-gitea.service" + "docker-gitea-db.service" + ]; + partOf = [ + "docker-compose-gitea-root.target" + ]; + wantedBy = [ + "docker-compose-gitea-root.target" + ]; + }; + + systemd.services."docker-gitea-db" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-setup.service" + ]; + requires = [ + "docker-network-setup.service" + ]; + partOf = [ + "docker-compose-gitea-root.target" + ]; + wantedBy = [ + "docker-compose-gitea-root.target" + ]; + }; + + systemd.services."docker-volume-gitea" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect vol_gitea || docker volume create vol_gitea --driver=local + ''; + partOf = [ "docker-compose-gitea-root.target" ]; + wantedBy = [ "docker-compose-gitea-root.target" ]; + }; + + }; +} diff --git a/system/virtualization/docker/n8n/default.nix b/system/virtualization/docker/n8n/default.nix index d0c173f..bd209f2 100644 --- a/system/virtualization/docker/n8n/default.nix +++ b/system/virtualization/docker/n8n/default.nix @@ -1,6 +1,4 @@ -{ config, lib, ... }: let - - hostPort = 9004; +{ config, lib, pkgs, ... }: let subdomain = "n8n"; @@ -15,12 +13,6 @@ in { config = lib.mkIf (config.sysconfig.docker."${name}".enable && config.sysconfig.docker.enable) { - - networking.firewall.interfaces = { - "ve-traefik" = { - allowedTCPPorts = [ hostPort ]; - }; - }; virtualisation.oci-containers.containers."${name}" = { image = "docker.n8n.io/n8nio/n8n"; @@ -41,7 +33,6 @@ in { "traefik.http.routers.${name}.service" = "${name}"; "traefik.http.routers.${name}.tls.certResolver" = "cloudflare"; - #"traefik.http.services.${name}.loadbalancer.server.url" = "http://192.168.100.10:${builtins.toString hostPort}"; "traefik.http.services.${name}.loadbalancer.server.port" = "5678"; }; @@ -70,5 +61,42 @@ in { N8N_SECURE_COOKIE = "false"; }; }; + + systemd.services."docker-n8n" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-setup.service" + "docker-volume-n8n.service" + ]; + requires = [ + "docker-network-setup.service" + "docker-volume-n8n.service" + ]; + partOf = [ + "docker-compose-n8n-root.target" + ]; + wantedBy = [ + "docker-compose-n8n-root.target" + ]; + }; + + systemd.services."docker-volume-n8n" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect vol_n8n || docker volume create vol_n8n --driver=local + ''; + partOf = [ "docker-compose-n8n-root.target" ]; + wantedBy = [ "docker-compose-n8n-root.target" ]; + }; + }; }