cd454b2926
Full public/ directory — services, network, decisions, security, inventory, rebuild sequence, and per-LXC setup guides. Sourced from wiki. No secrets or WAN IPs included.
6.1 KiB
6.1 KiB
Authentik Setup
Overview
Authentik is the centralized identity provider for the entire homelab. It runs in the auth LXC (10.2.0.25) in VLAN 1020. It provides two auth mechanisms:
- Forward auth — Caddy asks Authentik "is this person logged in?" before proxying any request. Services that don't support SSO natively get a login wall this way.
- OIDC provider — Services that support OAuth2/OIDC (Outline, Gitea, Vikunja, Grafana, Proxmox) get true single sign-on.
Stack: Postgres + Authentik server + Authentik worker (Redis removed as of 2025.10).
Prerequisites
- LXC at 10.2.0.25 with nesting enabled (Docker requires it)
- Caddy already deployed at 10.2.0.20
- Pi-hole DNS record:
auth.lerkolabs.com → 10.2.0.20
LXC Spec
| Property | Value |
|---|---|
| Hostname | auth |
| IP | 10.2.0.25/24 |
| Gateway | 10.2.0.1 |
| Cores | 2 |
| RAM | 2GB |
| Disk | 10GB |
| Template | debian-12-standard |
| Nesting | ✓ |
Installation
apt update && apt upgrade -y
apt install -y curl nano
timedatectl set-timezone America/Chicago
curl -fsSL https://get.docker.com | sh
systemctl enable docker
mkdir -p /opt/docker/authentik/{data,certs,custom-templates}
Configuration
Generate secrets and create .env
echo "PG_PASS=$(openssl rand -base64 36 | tr -d '\n')" >> /opt/docker/authentik/.env
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d '\n')" >> /opt/docker/authentik/.env
Add remaining config:
# PostgreSQL
PG_USER=authentik
PG_DB=authentik
# Pin to current version
AUTHENTIK_TAG=2026.2.1
AUTHENTIK_LOG_LEVEL=info
chmod 600 /opt/docker/authentik/.env
docker-compose.yml
services:
postgresql:
image: docker.io/library/postgres:16-alpine
container_name: authentik-db
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -d ${PG_DB} -U ${PG_USER}"]
start_period: 20s
interval: 30s
retries: 5
timeout: 5s
volumes:
- ./postgres:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: ${PG_PASS}
POSTGRES_USER: ${PG_USER}
POSTGRES_DB: ${PG_DB}
server:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2026.2.1}
container_name: authentik-server
restart: unless-stopped
command: server
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB}
AUTHENTIK_LOG_LEVEL: ${AUTHENTIK_LOG_LEVEL:-info}
volumes:
- ./data:/data
- ./custom-templates:/templates
ports:
- "9000:9000"
- "9443:9443"
depends_on:
postgresql:
condition: service_healthy
worker:
image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2026.2.1}
container_name: authentik-worker
restart: unless-stopped
command: worker
environment:
AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY}
AUTHENTIK_POSTGRESQL__HOST: postgresql
AUTHENTIK_POSTGRESQL__USER: ${PG_USER}
AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
AUTHENTIK_POSTGRESQL__NAME: ${PG_DB}
AUTHENTIK_LOG_LEVEL: ${AUTHENTIK_LOG_LEVEL:-info}
user: root
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./data:/data
- ./certs:/certs
- ./custom-templates:/templates
depends_on:
postgresql:
condition: service_healthy
Start Authentik
cd /opt/docker/authentik
docker compose up -d
docker logs -f authentik-server
# Wait for: "Everything is ready"
Initial Admin Setup
Navigate to: http://10.2.0.25:9000/if/flow/initial-setup/ (include trailing slash)
Set admin password for the akadmin account. Save in Vaultwarden.
Caddy Integration
Add to Caddyfile on the infra LXC (see caddy.md):
# Forward auth snippet
(authentik_forward_auth) {
forward_auth 10.2.0.25:9000 {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email \
X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks \
X-Authentik-Meta-Outpost X-Authentik-Meta-Provider \
X-Authentik-Meta-App X-Authentik-Meta-Version
trusted_proxies private_ranges
}
}
auth.lerkolabs.com {
reverse_proxy 10.2.0.25:9000
}
Configure Outpost
In Authentik admin: Applications → Outposts → authentik Embedded Outpost → Edit
Set both:
authentik Host:https://auth.lerkolabs.comauthentik Host (browser):https://auth.lerkolabs.com
Adding Applications
Forward auth pattern (services without native OIDC)
- Applications → Providers → Create → Proxy Provider
- Mode: Forward auth (single application)
- External host:
https://<service>.lerkolabs.com
- Applications → Applications → Create
- Assign provider, set slug and launch URL
- Outposts → Embedded Outpost → Edit → add application to Selected Applications
OIDC pattern (Outline, Gitea, Vikunja)
- Applications → Providers → Create → OAuth2/OpenID Provider
- Client type: Confidential
- Redirect URI: service-specific (see table below)
- Scopes: openid, email, profile
- Note the Client ID and Client Secret — configure in the service's .env
| Service | Redirect URI |
|---|---|
| Outline | https://outline.lerkolabs.com/auth/oidc.callback |
| Gitea | https://gitea.lerkolabs.com/user/oauth2/authentik/callback |
| Vikunja | https://tasks.lerkolabs.com/auth/openid/authentik |
| Grafana | https://grafana.lerkolabs.com/login/generic_oauth |
OIDC discovery URL pattern: https://auth.lerkolabs.com/application/o/<slug>/.well-known/openid-configuration
Verification
# All containers healthy
docker ps
# authentik-db Up X minutes (healthy)
# authentik-server Up X minutes
# authentik-worker Up X minutes
# Accessible via Caddy
curl -I https://auth.lerkolabs.com
# Expected: HTTP/2 302 (redirect to login)
Updates
# Edit .env, bump AUTHENTIK_TAG to new version
docker compose pull
docker compose up -d