Skip to Content

How to Deploy Authentik with Docker Compose and Traefik (Production Guide)

Build a resilient self-hosted SSO stack with TLS, backups, and operational guardrails.

As companies scale, fragmented login systems create avoidable risk: inconsistent MFA, manual onboarding, weak audit trails, and delayed offboarding. This guide shows how to deploy Authentik with Docker Compose and Traefik in a production-ready pattern.

The objective is dependable operations: clear secret boundaries, HTTPS by default, observable runtime checks, and lifecycle practices that survive real incidents.

Identity is a platform dependency, not just an app feature. Assign ownership across platform, security, and support teams so incident routing is clear when login error rates spike. Keep a runbook for certificate renewal failures, session anomalies, and dependency outages.

Change discipline matters: use staging promotion for every auth policy change, capture before/after verification evidence, and avoid ad-hoc edits directly on production hosts. This lowers blast radius and makes post-incident analysis much faster.

Architecture/flow overview

The stack runs Authentik server and worker, with PostgreSQL for persistent state and Redis for queue/ephemeral coordination. Traefik handles TLS termination and routes only the identity host to the Authentik web service.

This separation narrows public exposure and simplifies troubleshooting. Edge, app, and data concerns can be validated independently under pressure.

  • Edge: Traefik + ACME certificates
  • App: Authentik server/UI/API
  • Worker: asynchronous tasks and policy execution
  • Data: PostgreSQL + Redis

For compliance-heavy environments, map this deployment to concrete controls: retention periods, privileged-access approvals, MFA exception handling, and periodic review of dormant accounts. The technical stack is only half the solution; governance completes it.

Prerequisites

  • Linux host with Docker Engine and Compose plugin
  • DNS record for auth.example.com pointed to Traefik host
  • Traefik with resolver letsencrypt
  • At least 2 vCPU, 4 GB RAM, SSD storage
  • Defined owner for patching, backups, and on-call support

Verify NTP synchronization and outbound connectivity before rollout. Authentication tokens and certificate issuance are both sensitive to time/network drift.

Change discipline matters: use staging promotion for every auth policy change, capture before/after verification evidence, and avoid ad-hoc edits directly on production hosts. This lowers blast radius and makes post-incident analysis much faster.

Step-by-step deployment

1) Prepare folders and secrets

Separate compose, secrets, and data paths from day one. This keeps audits, backup jobs, and troubleshooting deterministic.

mkdir -p /opt/authentik/{compose,secrets,postgres,redis,backups}
cd /opt/authentik/compose
umask 077
touch ../secrets/postgres_password.txt ../secrets/authentik_secret_key.txt
openssl rand -base64 32 > ../secrets/postgres_password.txt
openssl rand -base64 64 > ../secrets/authentik_secret_key.txt
chmod 600 ../secrets/*.txt

If the copy button does not work in your browser, manually select the code block and copy it.

2) Define environment values

Keep non-sensitive values in environment files while loading credentials through secret files. Never hard-code secrets in versioned compose manifests.

# /opt/authentik/compose/.env
TZ=UTC
PG_DB=authentik
PG_USER=authentik
AUTHENTIK_HOST=auth.example.com
[email protected]

If the copy button does not work in your browser, manually select the code block and copy it.

3) Deploy compose stack with Traefik labels

Attach Authentik server to the external Traefik network and route only the intended host. Keep database and cache internal.

version: "3.9"
services:
  postgresql:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${PG_DB}
      POSTGRES_USER: ${PG_USER}
      POSTGRES_PASSWORD_FILE: /run/secrets/postgres_password
    volumes: ["../postgres:/var/lib/postgresql/data"]
    secrets: [postgres_password]
  redis:
    image: redis:7-alpine
    restart: unless-stopped
  server:
    image: ghcr.io/goauthentik/server:2026.2
    restart: unless-stopped
    env_file: .env
    command: server
    labels:
      - traefik.enable=true
      - traefik.http.routers.authentik.rule=Host(`${AUTHENTIK_HOST}`)
      - traefik.http.routers.authentik.entrypoints=websecure
      - traefik.http.routers.authentik.tls.certresolver=letsencrypt
      - traefik.http.services.authentik.loadbalancer.server.port=9000
      - traefik.docker.network=traefik-public
    networks: [default, traefik-public]
  worker:
    image: ghcr.io/goauthentik/server:2026.2
    restart: unless-stopped
    env_file: .env
    command: worker
secrets:
  postgres_password: {file: ../secrets/postgres_password.txt}
networks:
  traefik-public: {external: true}

If the copy button does not work in your browser, manually select the code block and copy it.

4) Launch and inspect first boot

Validate compose syntax before startup, then watch logs during migrations. Most first-run failures are hostname, TLS, or dependency-order issues.

docker network create traefik-public || true
docker compose config
docker compose up -d
docker compose logs -f --tail=100 server worker

If the copy button does not work in your browser, manually select the code block and copy it.

Identity is a platform dependency, not just an app feature. Assign ownership across platform, security, and support teams so incident routing is clear when login error rates spike. Keep a runbook for certificate renewal failures, session anomalies, and dependency outages.

Configuration and secrets handling

Rotate secrets quarterly, enforce least privilege for host access, and require peer review for auth-policy changes. Limit administrative access to a small trusted group and log every privileged action.

Roll out application integrations gradually: one pilot application, then broader expansion after real-user validation.

For compliance-heavy environments, map this deployment to concrete controls: retention periods, privileged-access approvals, MFA exception handling, and periodic review of dormant accounts. The technical stack is only half the solution; governance completes it.

Verification

Use both infrastructure checks and functional checks (actual user login, MFA flow, audit log entries). Verification must be reproducible by any on-call engineer.

curl -I https://auth.example.com/
docker compose ps
docker compose exec -T postgresql psql -U authentik -d authentik -c "select now();"
docker compose logs --tail=80 server | grep -Ei "ready|error|exception"

If the copy button does not work in your browser, manually select the code block and copy it.

Document expected outputs for each check so responders can quickly distinguish degradation from normal variance.

Common issues and fixes

TLS certificate does not issue

Check DNS target, open ports 80/443, and ACME resolver names in Traefik labels.

Service is up but page is unreachable

Confirm host rule and external network attachment for the Authentik server container.

Background jobs are delayed

Validate Redis reachability and consistent environment values for server and worker services.

Intermittent login loops

Inspect redirect URIs and host clock skew.

Database growth accelerates

Tune retention policy and monitoring thresholds before storage pressure occurs.

Change discipline matters: use staging promotion for every auth policy change, capture before/after verification evidence, and avoid ad-hoc edits directly on production hosts. This lowers blast radius and makes post-incident analysis much faster.

Backups and lifecycle operations

Backups without restore drills are assumptions. Automate backups and test restoration in staging on a fixed cadence.

cat >/usr/local/bin/authentik-backup.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
STAMP=$(date +%F-%H%M)
OUT=/opt/authentik/backups/pg-${STAMP}.sql.gz
docker compose -f /opt/authentik/compose/docker-compose.yml exec -T postgresql   pg_dump -U authentik authentik | gzip > "$OUT"
EOF
chmod +x /usr/local/bin/authentik-backup.sh
( crontab -l 2>/dev/null; echo "15 2 * * * /usr/local/bin/authentik-backup.sh" ) | crontab -

If the copy button does not work in your browser, manually select the code block and copy it.

Before upgrades, capture an on-demand backup, pin image versions, and smoke-test critical authentication paths after deployment.

FAQ

1) Is Redis optional in production?

No. Keep Redis for stable asynchronous behavior and queue processing.

2) Can I expose Authentik directly instead of Traefik?

Not recommended. A reverse proxy provides consistent TLS and edge policy controls.

3) How often should secrets be rotated?

Quarterly baseline, plus immediate rotation after suspected exposure.

4) What is a minimum backup standard?

Daily backup, retention policy, and scheduled restore drill.

5) Can this architecture scale later?

Yes. Start simple, then scale app layer and harden data services.

6) Which alerts should we prioritize first?

TLS renewal failures, login error spikes, worker queue lag, DB latency, and restart storms.

7) Should we separate staging and production identity?

Yes. Separate domains and secrets reduce accidental cross-environment impact.

Internal links

Talk to us

If you want this implemented with hardened defaults, observability, and tested recovery playbooks, our team can help.

Contact Us

Copy-code helper

If JS is allowed, this snippet enables one-click copy. If Odoo strips scripts, manual-copy fallback remains under each code block.

<script>
(function(){
 const buttons=document.querySelectorAll('.copy-code');
 buttons.forEach(btn=>btn.addEventListener('click',async()=>{
  const code=btn.parentElement.querySelector('code'); if(!code)return;
  try{await navigator.clipboard.writeText(code.innerText);btn.innerText='✅ Copied';}
  catch(e){alert('Clipboard blocked. Please copy manually.');}
 }));
})();
</script>

If the copy button does not work in your browser, manually select the code block and copy it.

Production Guide: Deploy FreshRSS with Docker Compose, Traefik, and PostgreSQL on Ubuntu
A production-ready FreshRSS deployment with TLS, database hardening, backups, upgrades, and operational troubleshooting.