196 lines
6.1 KiB
YAML

x-info:
github: https://github.com/goauthentik/authentik
docs: https://goauthentik.io/docs
changelog: https://github.com/goauthentik/authentik/releases
homelab_status: stable
last_updated: 2026-03-15
# Managed by Ansible — manual edits will be overwritten on next deploy.
# Source: ansible/templates/stacks/authentik.stack.yml
# Deploy: ansible-playbook -i inventory/hosts.ini playbooks/docker/deploy_authentik.yml
#
# DATA SAFETY NOTE:
# This stack uses absolute bind mounts under /mnt/homelab/apps/authentik.
# Deploy playbook preflight checks require these paths to exist before deploy,
# which protects pre-existing Authentik data from accidental fresh bootstraps.
version: "3.9"
services:
authentik-postgres:
image: docker.io/library/postgres:16-alpine
environment:
- TZ=America/New_York
- POSTGRES_DB={{ authentik_postgres_db | default('authentik') }}
- POSTGRES_PASSWORD={{ vault_authentik_postgres_password }}
- POSTGRES_USER={{ authentik_postgres_user | default('authentik') }}
healthcheck:
test: ["CMD-SHELL", "pg_isready -d $$POSTGRES_DB -U $$POSTGRES_USER"]
interval: 30s
timeout: 5s
retries: 5
start_period: 20s
volumes:
- /mnt/homelab/apps/authentik/data/database:/var/lib/postgresql/data
networks:
- proxy-net
deploy:
replicas: 1
placement:
constraints:
- node.hostname == {{ authentik_placement_node | default('swarm-manager-1') }}
resources:
limits:
memory: 1G
cpus: "0.75"
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
update_config:
parallelism: 1
order: stop-first
failure_action: rollback
delay: 10s
monitor: 30s
rollback_config:
parallelism: 1
order: stop-first
authentik-redis:
image: redis:7-alpine
command: ["--save", "60", "1", "--loglevel", "warning"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- /mnt/homelab/apps/authentik/data/redis:/data
networks:
- proxy-net
deploy:
replicas: 1
placement:
constraints:
- node.hostname == {{ authentik_placement_node | default('swarm-manager-1') }}
resources:
limits:
memory: 512M
cpus: "0.50"
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
update_config:
parallelism: 1
order: start-first
failure_action: rollback
delay: 10s
monitor: 30s
rollback_config:
parallelism: 1
order: stop-first
authentik-server:
image: ghcr.io/goauthentik/server:{{ authentik_version | default('2025.10.1') }}
command: ["server"]
environment:
- TZ=America/New_York
- AUTHENTIK_POSTGRESQL__HOST=authentik-postgres
- AUTHENTIK_POSTGRESQL__NAME={{ authentik_postgres_db | default('authentik') }}
- AUTHENTIK_POSTGRESQL__PASSWORD={{ vault_authentik_postgres_password }}
- AUTHENTIK_POSTGRESQL__USER={{ authentik_postgres_user | default('authentik') }}
- AUTHENTIK_SECRET_KEY={{ vault_authentik_secret_key }}
- AUTHENTIK_REDIS__HOST=authentik-redis
ports:
- "9000:9000"
volumes:
- /mnt/homelab/apps/authentik/data/media:/media
- /mnt/homelab/apps/authentik/data/config:/config
- /mnt/homelab/apps/authentik/data/blueprints:/blueprints/custom:ro
networks:
- proxy-net
labels:
- "homepage.name=Authentik"
- "homepage.icon=si:authentik"
- "homepage.url=https://sso.castaldifamily.com"
- "homepage.description=Identity provider"
deploy:
labels:
- "traefik.enable=true"
- "traefik.http.routers.authentik.rule=Host(`sso.castaldifamily.com`)"
- "traefik.http.routers.authentik.entrypoints=websecure"
- "traefik.http.routers.authentik.tls=true"
- "traefik.http.routers.authentik.tls.certresolver=cloudflare"
- "traefik.http.routers.authentik.middlewares=security-headers@file,ratelimit-basic@file"
- "traefik.http.services.authentik.loadbalancer.server.url=http://{{ edge_routing.swarm.bind_ip }}:9000"
replicas: 1
placement:
constraints:
- node.hostname == {{ authentik_placement_node | default('swarm-manager-1') }}
resources:
limits:
memory: 2G
cpus: "1.0"
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
update_config:
parallelism: 1
order: start-first
failure_action: rollback
delay: 10s
monitor: 30s
rollback_config:
parallelism: 1
order: stop-first
authentik-worker:
image: ghcr.io/goauthentik/server:{{ authentik_version | default('2025.10.1') }}
command: ["worker"]
environment:
- TZ=America/New_York
- AUTHENTIK_POSTGRESQL__HOST=authentik-postgres
- AUTHENTIK_POSTGRESQL__NAME={{ authentik_postgres_db | default('authentik') }}
- AUTHENTIK_POSTGRESQL__PASSWORD={{ vault_authentik_postgres_password }}
- AUTHENTIK_POSTGRESQL__USER={{ authentik_postgres_user | default('authentik') }}
- AUTHENTIK_SECRET_KEY={{ vault_authentik_secret_key }}
- AUTHENTIK_REDIS__HOST=authentik-redis
volumes:
- /mnt/homelab/apps/authentik/data/media:/media
- /mnt/homelab/apps/authentik/data/config:/config
networks:
- proxy-net
deploy:
replicas: 1
placement:
constraints:
- node.hostname == {{ authentik_placement_node | default('swarm-manager-1') }}
resources:
limits:
memory: 1G
cpus: "0.75"
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 60s
update_config:
parallelism: 1
order: start-first
failure_action: rollback
delay: 10s
monitor: 30s
rollback_config:
parallelism: 1
order: stop-first
networks:
proxy-net:
external: true
name: proxy-net