VOOZH about

URL: https://dev.to/vultr/deploying-authelia-open-source-authentication-and-authorization-gateway-on-ubuntu-2404-134

⇱ Deploying Authelia Open-Source Authentication and Authorization Gateway on Ubuntu 24.04 - DEV Community


Authelia is an open-source authentication and authorization gateway that adds SSO, two-factor authentication, and policy-based access control in front of web applications, integrating natively with reverse proxies through forward-auth. This guide deploys Authelia using Docker Compose with Traefik handling automatic HTTPS, file-backed users, TOTP 2FA, and a sample whoami app protected by forward-auth. By the end, you'll have Authelia gating multiple subdomains with SSO and 2FA over HTTPS.


Set Up the Directory Structure

1. Create the project directory structure:

$mkdir -p ~/authelia/{config,secrets,logs}
$cd ~/authelia

2. Create the environment file:

$nano .env
DOMAIN=example.com
LETSENCRYPT_EMAIL=admin@example.com

DNS A records for auth.${DOMAIN}, app.${DOMAIN}, and traefik.${DOMAIN} must point at the server.


Generate Authelia Secrets

1. Own the secrets directory:

$sudo chown 8000:8000 ./secrets
$sudo chmod 0700 ./secrets

2. Generate session, storage, and JWT secrets in one shot:

$docker run --rm -u 8000:8000 -v ./secrets:/secrets docker.io/authelia/authelia:4.39 \
 sh -c "cd /secrets && authelia crypto rand --length 64 session_secret.txt storage_encryption_key.txt jwt_secret.txt"

Write the Authelia Configuration

1. Create the configuration file:

$nano config/configuration.yml
server:
 address: 'tcp4://:9091'

log:
 level: 'info'
 file_path: '/var/log/authelia/authelia.log'
 keep_stdout: true

identity_validation:
 elevated_session:
 require_second_factor: true
 reset_password:
 jwt_lifespan: '5minutes'
 jwt_secret: {{ secret "/secrets/jwt_secret.txt" | mindent 0 "|" | msquote }}

totp:
 disable: false
 issuer: 'example.com'
 period: 30
 skew: 1

authentication_backend:
 file:
 path: '/config/users.yml'
 password:
 algorithm: 'argon2'
 argon2:
 variant: 'argon2id'
 iterations: 3
 memory: 65535
 parallelism: 4
 key_length: 32
 salt_length: 16

access_control:
 default_policy: 'deny'
 rules:
 - domain: 'app.example.com'
 policy: 'two_factor'
 - domain: 'traefik.example.com'
 policy: 'one_factor'

session:
 name: 'authelia_session'
 secret: {{ secret "/secrets/session_secret.txt" | mindent 0 "|" | msquote }}
 cookies:
 - domain: 'example.com'
 authelia_url: 'https://auth.example.com'

regulation:
 max_retries: 4
 find_time: 120
 ban_time: 300

storage:
 encryption_key: {{ secret "/secrets/storage_encryption_key.txt" | mindent 0 "|" | msquote }}
 local:
 path: '/config/db.sqlite3'

notifier:
 disable_startup_check: false
 filesystem:
 filename: '/config/notification.txt'

2. Generate an argon2 hash for the first user's password:

$docker run --rm authelia/authelia:4.39 authelia crypto hash generate argon2 --password 'your-secure-password'

3. Create the user database with that hash:

$nano config/users.yml
users:
 authuser:
 displayname: 'AuthUser'
 password: '$argon2id$v=19$m=65536,t=3,p=4$BpLnfgDsc2WD8F2q$Zis.ixdg9s/UOJYrs56b5QEZFiZECu0qZVNsIYxBaNJ7ucIL.nlxVCT5tqh8KHG8X4tlwCFm5r6NTOZZ5qRFN/'
 email: 'authuser@example.com'
 groups:
 - 'admin'

Deploy with Docker Compose

1. Create the Docker Compose manifest:

$nano docker-compose.yaml
services:
 traefik:
 image: traefik:v3.6
 container_name: traefik
 depends_on:
 - authelia
 command:
 - "--api.dashboard=true"
 - "--providers.docker=true"
 - "--providers.docker.exposedbydefault=false"
 - "--entrypoints.web.address=:80"
 - "--entrypoints.websecure.address=:443"
 - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
 - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
 - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
 - "--certificatesresolvers.letsencrypt.acme.email=${LETSENCRYPT_EMAIL}"
 - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
 ports:
 - "80:80"
 - "443:443"
 volumes:
 - "./letsencrypt:/letsencrypt"
 - "/var/run/docker.sock:/var/run/docker.sock:ro"
 labels:
 - "traefik.enable=true"
 - "traefik.http.routers.dashboard.rule=Host(`traefik.${DOMAIN}`)"
 - "traefik.http.routers.dashboard.entrypoints=websecure"
 - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
 - "traefik.http.routers.dashboard.service=api@internal"
 - "traefik.http.routers.dashboard.middlewares=authelia@docker"
 restart: unless-stopped

 authelia:
 image: authelia/authelia:4.39
 container_name: authelia
 volumes:
 - "./secrets:/secrets:ro"
 - "./config:/config"
 - "./logs:/var/log/authelia"
 environment:
 TZ: "UTC"
 X_AUTHELIA_CONFIG_FILTERS: "template"
 labels:
 - "traefik.enable=true"
 - "traefik.http.routers.authelia.rule=Host(`auth.${DOMAIN}`)"
 - "traefik.http.routers.authelia.entrypoints=websecure"
 - "traefik.http.routers.authelia.tls.certresolver=letsencrypt"
 - "traefik.http.middlewares.authelia.forwardAuth.address=http://authelia:9091/api/authz/forward-auth"
 - "traefik.http.middlewares.authelia.forwardAuth.trustForwardHeader=true"
 - "traefik.http.middlewares.authelia.forwardAuth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email"
 restart: unless-stopped

 whoami:
 image: traefik/whoami
 container_name: whoami
 depends_on:
 - authelia
 labels:
 - "traefik.enable=true"
 - "traefik.http.routers.whoami.rule=Host(`app.${DOMAIN}`)"
 - "traefik.http.routers.whoami.entrypoints=websecure"
 - "traefik.http.routers.whoami.tls.certresolver=letsencrypt"
 - "traefik.http.routers.whoami.middlewares=authelia@docker"
 restart: unless-stopped

2. Start the services:

$docker compose up -d

3. Verify the services are running:

$docker compose ps
$docker compose logs

Register TOTP and Test SSO

1. Open the login portal:

Navigate to https://auth.example.com and sign in as authuser.

2. Register a TOTP device:

Click Register device and capture the verification code from the filesystem notifier:

$docker compose exec authelia cat /config/notification.txt

Scan the QR code with an authenticator app and enter the 6-digit code.

3. Visit a protected app:

Open https://app.example.com — the request redirects through Authelia for password + TOTP, then the whoami container returns the injected identity headers.

4. Confirm SSO:

Open https://traefik.example.com from the same browser — no re-authentication required.


Next Steps

Authelia is gating multiple subdomains with SSO and 2FA. From here you can:

  • Protect more apps by adding traefik.http.routers.<svc>.middlewares=authelia@docker and a matching access_control rule
  • Switch the authentication backend to LDAP or OpenID Connect 1.0
  • Configure SMTP under notifier to deliver verification codes by email

For the full guide with additional tips, visit the original article on Vultr Docs.