Authentik Setup

Overview

Central OIDC provider for selfhosted apps. Guild pushes tier data, Authentik issues tokens.

  • Public URL: auth.dungeon.club via Cloudflare Tunnel (kuroda)
  • Internal: localhost:9000 (HTTP), localhost:9443 (HTTPS) on Cosmos LXC
  • Image: ghcr.io/goauthentik/server:2026.2.2
  • Database: PostgreSQL 16 (localhost:5432)
  • Cache: Redis 8 (localhost:6379)
  • Network: All containers on host mode

Generate secrets

openssl rand -base64 36  # PG_PASS
openssl rand -base64 60  # AUTHENTIK_SECRET_KEY

Docker Compose

services:
  authentik-db:
    container_name: authentik-db
    image: postgres:16-alpine
    restart: unless-stopped
    network_mode: host
    environment:
      POSTGRES_DB: authentik
      POSTGRES_USER: authentik
      POSTGRES_PASSWORD: <PG_PASS>
    volumes:
      - authentik-db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -d authentik -U authentik"]
      interval: 30s
      retries: 5
      start_period: 20s
      timeout: 5s
 
  authentik-redis:
    container_name: authentik-redis
    image: redis:8-alpine
    restart: unless-stopped
    network_mode: host
    command: ["--save", "60", "1", "--loglevel", "warning"]
    volumes:
      - authentik-redis:/data
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
      interval: 30s
      retries: 5
      start_period: 20s
      timeout: 3s
 
  authentik-server:
    container_name: authentik-server
    image: ghcr.io/goauthentik/server:2026.2.2
    command: server
    restart: unless-stopped
    network_mode: host
    environment:
      AUTHENTIK_POSTGRESQL__HOST: localhost
      AUTHENTIK_POSTGRESQL__NAME: authentik
      AUTHENTIK_POSTGRESQL__USER: authentik
      AUTHENTIK_POSTGRESQL__PASSWORD: <PG_PASS>
      AUTHENTIK_REDIS__HOST: localhost
      AUTHENTIK_SECRET_KEY: <AUTHENTIK_SECRET_KEY>
    volumes:
      - authentik-media:/media
      - authentik-templates:/templates
 
  authentik-worker:
    container_name: authentik-worker
    image: ghcr.io/goauthentik/server:2026.2.2
    command: worker
    restart: unless-stopped
    network_mode: host
    user: root
    environment:
      AUTHENTIK_POSTGRESQL__HOST: localhost
      AUTHENTIK_POSTGRESQL__NAME: authentik
      AUTHENTIK_POSTGRESQL__USER: authentik
      AUTHENTIK_POSTGRESQL__PASSWORD: <PG_PASS>
      AUTHENTIK_REDIS__HOST: localhost
      AUTHENTIK_SECRET_KEY: <AUTHENTIK_SECRET_KEY>
    volumes:
      - authentik-media:/media
      - authentik-certs:/certs
      - authentik-templates:/templates
 
volumes:
  authentik-db:
  authentik-redis:
  authentik-media:
  authentik-certs:
  authentik-templates:

First-time setup

  1. Start all four containers (db and redis first, then server and worker)
  2. Open http://localhost:9000/if/flow/initial-setup/ from Tailnet
  3. Create admin account
  4. Add Cloudflare Tunnel route: auth.dungeon.clubhttp://localhost:9000

Port conflicts

Host mode means these ports must be free on the Cosmos host:

  • 5432 — PostgreSQL
  • 6379 — Redis
  • 9000 — Authentik HTTP
  • 9443 — Authentik HTTPS

Resource requirements

Authentik needs minimum 2 CPU cores and 2GB RAM. The Cosmos LXC needs at least 4GB total to run Authentik alongside HedgeDoc, Kavita, CWA, and Cloudflared. Beelink N95 has 8GB (upgrading to 16GB).

Discord social login source (live)

  • Source type: Discord OAuth
  • Uses Marty prod Discord app
  • Redirect URI in Discord Developer Portal: https://auth.dungeon.club/source/oauth/callback/discord/
  • User matching: link by identical email
  • Promoted (big button on login page)
  • Discord source added to default-authentication-identification stage

Applications configured

HedgeDoc (live)

  • Provider: OAuth2/OpenID
  • Application slug: hedgedoc
  • Redirect URI: https://write.dungeon.club/auth/oauth2/callback
  • Scopes: openid, email, profile

Admin accounts

Next steps

  1. Create groups: guild-free, guild-silver, guild-gold, guild-mithril
  2. Build syncMemberToAuthentik() in Guild to push tier changes
  3. Add more OIDC applications (Kavita, Calibre Web, etc.)