Files
portainer-core/stacks/authentik.yml
T
jpmschweitzerandClaude Opus 4.5 75c3950dd8 feat: add Docker healthchecks, remove Uptime Kuma
- Add healthcheck configurations to 13 stacks for Portainer status monitoring
- Remove Uptime Kuma service (replaced by Docker healthchecks)
- Clean up stale Heimdall references
- Update documentation and service counts

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 12:05:05 +01:00

217 lines
6.4 KiB
YAML

version: '3.8'
# Authentik Identity Provider (SSO)
# Purpose: Centralized authentication for all homelab services
# Ports: 9000 (web UI), 9444 (standalone proxy outpost)
# GPU: No
# Storage: SSD (configs), PostgreSQL shared (user data)
# Note: Using standalone outpost - embedded outpost has issues in 2024.8.4
services:
authentik-server:
image: ghcr.io/goauthentik/server:2024.8.4 # Pinned version (2024.10 has redirect loop issues)
container_name: authentik-server
restart: unless-stopped
command: server
environment:
# External URLs (CRITICAL for redirect loop prevention)
AUTHENTIK_HOST: https://auth.schweitz.net
AUTHENTIK_HOST_BROWSER: https://auth.schweitz.net
# Cookie settings (CRITICAL for SSO across subdomains)
AUTHENTIK_COOKIE_DOMAIN: .schweitz.net
AUTHENTIK_COOKIE_SAMESITE: lax
# SSL/TLS
AUTHENTIK_INSECURE: false
# PostgreSQL (shared)
AUTHENTIK_POSTGRESQL__HOST: postgres-shared
AUTHENTIK_POSTGRESQL__PORT: 5432
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__USER: authentik_user
AUTHENTIK_POSTGRESQL__PASSWORD: F//j0ktck7cX06Vfgh0YXceONOtlSsHvadqROICeDx8=
AUTHENTIK_POSTGRESQL__USE_PGBOUNCER: false
# Redis (shared)
AUTHENTIK_REDIS__HOST: redis-shared
AUTHENTIK_REDIS__PORT: 6379
AUTHENTIK_REDIS__DB: 0
# Secret key (generated: openssl rand -base64 32)
AUTHENTIK_SECRET_KEY: TnFaTZ//RDcO2hxVR4QGOBORd5tfXe4Vok+lcAz/AdE=
# Resource optimization
AUTHENTIK_LOG_LEVEL: warning
AUTHENTIK_ERROR_REPORTING__ENABLED: false
AUTHENTIK_AVATARS: none
AUTHENTIK_FOOTER_LINKS: '[]'
# Embedded outpost configuration
AUTHENTIK_OUTPOSTS__DOCKER_IMAGE_BASE: "ghcr.io/goauthentik/%(type)s:%(version)s"
# Timezone
TZ: Europe/Amsterdam
ports:
- "9000:9000" # Web UI + Embedded outpost (path: /outpost.goauthentik.io/*)
volumes:
- /home/jpmschweitzer/docker-data/authentik/media:/media
- /home/jpmschweitzer/docker-data/authentik/custom-templates:/templates
networks:
- docker-dataplane
healthcheck:
test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:9000/-/health/live/')\" || exit 1"]
start_period: 60s
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
authentik-worker:
image: ghcr.io/goauthentik/server:2024.8.4 # Same version as server
container_name: authentik-worker
restart: unless-stopped
command: worker
environment:
# Same environment as server (MUST match exactly)
AUTHENTIK_HOST: https://auth.schweitz.net
AUTHENTIK_HOST_BROWSER: https://auth.schweitz.net
AUTHENTIK_COOKIE_DOMAIN: .schweitz.net
AUTHENTIK_COOKIE_SAMESITE: lax
AUTHENTIK_INSECURE: false
AUTHENTIK_POSTGRESQL__HOST: postgres-shared
AUTHENTIK_POSTGRESQL__PORT: 5432
AUTHENTIK_POSTGRESQL__NAME: authentik
AUTHENTIK_POSTGRESQL__USER: authentik_user
AUTHENTIK_POSTGRESQL__PASSWORD: F//j0ktck7cX06Vfgh0YXceONOtlSsHvadqROICeDx8=
AUTHENTIK_POSTGRESQL__USE_PGBOUNCER: false
AUTHENTIK_REDIS__HOST: redis-shared
AUTHENTIK_REDIS__PORT: 6379
AUTHENTIK_REDIS__DB: 0
AUTHENTIK_SECRET_KEY: TnFaTZ//RDcO2hxVR4QGOBORd5tfXe4Vok+lcAz/AdE=
AUTHENTIK_LOG_LEVEL: warning
AUTHENTIK_ERROR_REPORTING__ENABLED: false
TZ: Europe/Amsterdam
# Worker-specific configuration
AUTHENTIK_BOOTSTRAP_WORKERS: 1 # Single worker (homelab scale)
AUTHENTIK_WORKER__CONCURRENCY: 2 # 2 threads per worker
volumes:
- /home/jpmschweitzer/docker-data/authentik/media:/media
- /home/jpmschweitzer/docker-data/authentik/custom-templates:/templates
- /home/jpmschweitzer/docker-data/authentik/certs:/certs
- /var/run/docker.sock:/var/run/docker.sock # For outpost management
networks:
- docker-dataplane
depends_on:
- authentik-server
healthcheck:
test: ["CMD-SHELL", "ak healthcheck || exit 1"]
start_period: 60s
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 384M
cpus: '0.3'
reservations:
memory: 128M
authentik-proxy:
image: ghcr.io/goauthentik/proxy:2024.8.4 # Standalone outpost (embedded outpost not working in 2024.8.4)
container_name: authentik-proxy
restart: unless-stopped
environment:
# Authentik server connection
AUTHENTIK_HOST: https://auth.schweitz.net
AUTHENTIK_INSECURE: false
AUTHENTIK_TOKEN: 9blMGz71CFMJszs7AedQefgydpTnwvybjmMn0AlYilIKBV5LIq7snqnCodwX
# Logging
AUTHENTIK_LOG_LEVEL: info
# Timezone
TZ: Europe/Amsterdam
ports:
- "9444:9443" # Proxy outpost endpoint (9443 used by Portainer)
networks:
- docker-dataplane
depends_on:
- authentik-server
healthcheck:
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:9300/outpost.goauthentik.io/ping || exit 1"]
start_period: 30s
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
memory: 256M
cpus: '0.2'
reservations:
memory: 128M
networks:
docker-dataplane:
external: true
name: docker-dataplane
# Setup Instructions:
#
# 1. Create directories:
# mkdir -p ~/docker-data/authentik/{media,custom-templates,certs}
#
# 2. Deploy stack:
# docker-compose -f stacks/authentik.yml up -d
#
# 3. Watch logs:
# docker logs -f authentik-server
# docker logs -f authentik-worker
#
# 4. Wait for migrations to complete (~2-3 minutes):
# docker logs authentik-server 2>&1 | grep "Applying migration"
#
# 5. Access web UI:
# https://auth.schweitz.net (should show setup wizard)
#
# 6. Complete setup wizard:
# - Email: admin@schweitz.net
# - Password: <secure-password>
# - Finish setup
#
# Monitoring:
#
# Memory usage:
# docker stats authentik-server authentik-worker --no-stream
#
# Database connectivity:
# docker exec authentik-server ak check
#
# Outpost status (embedded outpost on port 9000):
# curl http://authentik-server:9000/outpost.goauthentik.io/ping
# curl http://192.168.86.149:9000/outpost.goauthentik.io/auth/nginx (should return 401, not 404)