From af38c71fb00af79086851e6de96ad6664300dd79 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 11 Nov 2025 14:13:08 -0500 Subject: [PATCH] core services stack --- stacks/{core => startup}/authentik/stack.yml | 0 stacks/{core => startup}/portainer/stack.yml | 0 stacks/startup/stack.yml | 196 +++++++++++++++++++ stacks/{core => startup}/traefik/stack.yml | 0 4 files changed, 196 insertions(+) rename stacks/{core => startup}/authentik/stack.yml (100%) rename stacks/{core => startup}/portainer/stack.yml (100%) create mode 100644 stacks/startup/stack.yml rename stacks/{core => startup}/traefik/stack.yml (100%) diff --git a/stacks/core/authentik/stack.yml b/stacks/startup/authentik/stack.yml similarity index 100% rename from stacks/core/authentik/stack.yml rename to stacks/startup/authentik/stack.yml diff --git a/stacks/core/portainer/stack.yml b/stacks/startup/portainer/stack.yml similarity index 100% rename from stacks/core/portainer/stack.yml rename to stacks/startup/portainer/stack.yml diff --git a/stacks/startup/stack.yml b/stacks/startup/stack.yml new file mode 100644 index 0000000..365f57c --- /dev/null +++ b/stacks/startup/stack.yml @@ -0,0 +1,196 @@ +#--------------------------- +# AUTHENTIK +#--------------------------- +services: + redis: + image: redis:alpine + command: --save 60 1 --loglevel warning + volumes: + - /home/doc/projects/swarm-data/appdata/authentik/redis:/data + networks: + - homelab + healthcheck: + test: [ "CMD", "redis-cli", "ping" ] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + deploy: + replicas: 1 + resources: + limits: + memory: 512M + reservations: + memory: 128M + + authentik_server: + image: ghcr.io/goauthentik/server:2025.10.0 + command: server + environment: + AUTHENTIK_SECRET_KEY: "file:///run/secrets/auth-key" + AUTHENTIK_REDIS__HOST: "redis" + AUTHENTIK_POSTGRESQL__HOST: "10.0.4.10" + AUTHENTIK_POSTGRESQL__PORT: "5432" + AUTHENTIK_POSTGRESQL__USER: "admin" + AUTHENTIK_POSTGRESQL__NAME: "authentik" + AUTHENTIK_POSTGRESQL__PASSWORD: "file:///run/secrets/postgres-master" + # Optional: Set error reporting (set to false for privacy) + AUTHENTIK_ERROR_REPORTING__ENABLED: "false" + secrets: + - auth-key + - postgres-master + volumes: + - /home/doc/projects/swarm-data/appdata/authentik/media:/media + - /home/doc/projects/swarm-data/appdata/authentik/templates:/templates + - /var/run/docker.sock:/var/run/docker.sock + networks: + - homelab + healthcheck: + test: [ "CMD-SHELL", "ak healthcheck" ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 90s + deploy: + replicas: 1 + resources: + limits: + memory: 1G + cpus: '1.0' + reservations: + memory: 512M + labels: + - "traefik.enable=true" + - "traefik.swarm.network=homelab" + # Public-facing domain with Let's Encrypt certificate + - "traefik.http.routers.authentik.rule=Host(`auth.frostlabs.me`)" + - "traefik.http.routers.authentik.entrypoints=websecure" + - "traefik.http.routers.authentik.tls=true" + - "traefik.http.routers.authentik.tls.certresolver=cloudflare" + - "traefik.http.services.authentik.loadbalancer.server.port=9000" + + depends_on: + - redis + + authentik_worker: + image: ghcr.io/goauthentik/server:2025.10.0 + command: worker + environment: + AUTHENTIK_SECRET_KEY: "file:///run/secrets/auth-key" + AUTHENTIK_REDIS__HOST: "redis" + AUTHENTIK_POSTGRESQL__HOST: "10.0.4.10" + AUTHENTIK_POSTGRESQL__PORT: "5432" + AUTHENTIK_POSTGRESQL__USER: "admin" + AUTHENTIK_POSTGRESQL__NAME: "authentik" + AUTHENTIK_POSTGRESQL__PASSWORD: "file:///run/secrets/postgres-master" + # Optional: Set error reporting (set to false for privacy) + AUTHENTIK_ERROR_REPORTING__ENABLED: "false" + secrets: + - auth-key + - postgres-master + volumes: + - /home/doc/projects/swarm-data/appdata/authentik/media:/media + - /home/doc/projects/swarm-data/appdata/authentik/templates:/templates + - /var/run/docker.sock:/var/run/docker.sock + networks: + - homelab + deploy: + replicas: 1 + resources: + limits: + memory: 1G + cpus: '1.0' + reservations: + memory: 512M + depends_on: + - redis + +#--------------------------- +# TRAEFIK +#--------------------------- + traefik: + image: traefik:v3.5.4 + # Remove all command arguments - using static config file instead + ports: + - 80:80 + - 443:443 + - 8080:8080 + environment: + - CF_DNS_API_TOKEN_FILE=/run/secrets/cloudflare_api_token + volumes: + - type: bind + source: /var/run/docker.sock + target: /var/run/docker.sock + read_only: true + - type: bind + source: /home/doc/projects/swarm-data/swarm-production/conf/traefik-conf/static.yml + target: /etc/traefik/traefik.yml + read_only: true + - type: bind + source: /home/doc/projects/swarm-data/swarm-production/conf/traefik-conf/dynamic.yml + target: /etc/traefik/dynamic/dynamic.yml + - type: bind + source: /home/doc/projects/swarm-data/appdata/traefik/certificates/acme.json + target: /certificates/acme.json + secrets: + - cloudflare_api_token + networks: + - homelab + healthcheck: + test: [ "CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/ping" ] + interval: 30s + timeout: 5s + retries: 3 + start_period: 30s + deploy: + mode: replicated + replicas: 1 + placement: + constraints: + - node.hostname == p0 + +#--------------------------- +# TRAEFIK +#--------------------------- + portainer: + image: portainer/portainer-ce:latest + command: -H tcp://tasks.agent:9001 --tlsskipverify + volumes: + - /home/doc/projects/swarm-data/appdata/portainer:/data + networks: + - homelab + ports: + - 9001:9000 + deploy: + mode: replicated + replicas: 1 + labels: + - "traefik.enable=true" + - "traefik.swarm.network=homelab" + # Public-facing domain with Let's Encrypt certificate + - "traefik.http.routers.portainer.rule=Host(`portainer.frostlabs.me`)" + - "traefik.http.routers.portainer.entrypoints=websecure" + - "traefik.http.routers.portainer.tls=true" + - "traefik.http.routers.portainer.tls.certresolver=cloudflare" + - "traefik.http.services.portainer.loadbalancer.server.port=9000" + + agent: + image: portainer/agent:latest + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /var/lib/docker/volumes:/var/lib/docker/volumes + networks: + - homelab + deploy: + mode: global + +networks: + homelab: + external: true +secrets: + postgres-master: + external: true + auth-key: + external: true + cloudflare_api_token: + external: true diff --git a/stacks/core/traefik/stack.yml b/stacks/startup/traefik/stack.yml similarity index 100% rename from stacks/core/traefik/stack.yml rename to stacks/startup/traefik/stack.yml