196 lines
6.1 KiB
YAML
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 |