Files
2026-06-01 09:52:14 -04:00

7.1 KiB

authelia-setup

Reusable Authelia SSO + Caddy reverse proxy stack. Single login covers all subdomains. Two-factor via TOTP app. Password reset via SMTP.

What this does

  • Caddy — reverse proxy with automatic HTTPS via Let's Encrypt
  • Authelia — SSO portal at auth.mydomain.com, protects any subdomain with import authelia in the Caddyfile
  • Brevo/Migadu SMTP — sends TOTP registration and password reset emails

Machine requirements

  • Ubuntu 24.04 LTS
  • Docker: curl -fsSL https://get.docker.com | sh && sudo usermod -aG docker $USER
  • No GPU needed

Directory structure

~/docker/
├── authelia/
│   ├── docker-compose.yml
│   ├── .env
│   ├── config/
│   │   ├── configuration.yml
│   │   ├── users.yml
│   │   └── secrets/        ← never committed to git
│   └── data/               ← never committed to git
└── caddy/
    └── Caddyfile

First time setup

1. DNS

At your domain registrar add two records:

@   →  A      →  this machine's public IP
*   →  CNAME  →  mydomain.com

2. Replace placeholders

In every file replace mydomain.com with your real domain. In users.yml replace REPLACE_WITH_HASH with real password hashes (see below).

3. Create secrets

mkdir -p ~/docker/authelia/config/secrets

openssl rand -hex 32 > ~/docker/authelia/config/secrets/jwt_secret
openssl rand -hex 32 > ~/docker/authelia/config/secrets/session_secret
openssl rand -hex 32 > ~/docker/authelia/config/secrets/storage_secret

# Replace with your actual SMTP password — never commit this
echo "your-smtp-password" > ~/docker/authelia/config/secrets/smtp_password

chmod 600 ~/docker/authelia/config/secrets/*

4. Create .env files

cat > ~/docker/authelia/.env << 'EOF'
MY_DOMAIN=yourdomain.com
SMTP_USER=authelia@yourdomain.com
DOCKER_MY_NETWORK=caddy_net
TZ=America/New_York
EOF

5. Generate password hashes

Run once per unique password — all users can share one temporary password:

docker run --rm authelia/authelia:4.39.20 authelia crypto hash generate argon2 --password 'TempPass2026!'

Paste the output into users.yml for each user. Tell users to use "Forgot Password" on first login to set their own.

6. Create or verify Docker network

If the network doesn't exist yet, create it:

docker network create caddy_net

If Caddy is already running with an existing network, find its name and use that instead:

docker network ls

Update DOCKER_MY_NETWORK in authelia/.env to match.

7. Start Authelia

cd ~/docker/authelia
mkdir -p data
sudo chown -R 1000:1000 config data
docker compose up -d
docker compose logs -f

8. Start Caddy

The (authelia) snippet in the Caddyfile must be at the very top, before any site blocks. This is required for import authelia to work in any site block.

cd ~/docker/caddy
docker compose up -d

9. Generate Caddy basic auth hash (if using basic auth anywhere)

docker exec caddy caddy hash-password --plaintext 'yourpassword'

10. Reload Caddy after any Caddyfile changes

docker exec -w /etc/caddy caddy caddy reload

Adding a new protected service

In the Caddyfile add:

newservice.mydomain.com {
    import authelia
    reverse_proxy INTERNAL_IP:PORT
}

Then reload Caddy. No Authelia changes needed.

Adding a service WITHOUT Authelia (has its own login)

newservice.mydomain.com {
    reverse_proxy INTERNAL_IP:PORT
}

Adding Authelia to an existing dockerized Caddy setup

If you already have Caddy running with other services (e.g. via dothevo/selfhosted or similar), follow these steps to add Authelia without disturbing existing services.

1. Find your existing Caddy Docker network

docker inspect caddy | grep -i network
# or
docker network ls

Note the network name — use it as DOCKER_MY_NETWORK in authelia/.env.

2. Connect Authelia to that network

In authelia/docker-compose.yml the network name must match your existing Caddy network. Authelia needs to be on the same network as Caddy to be reachable by container name.

3. Add the authelia snippet to your existing Caddyfile

The (authelia) snippet must be at the top of the Caddyfile, before any site blocks. Without it at the top, import authelia in site blocks will fail.

Add at the very top:

(authelia) {
    forward_auth authelia:9091 {
        uri /api/authz/forward-auth
        copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
    }
}

Add the Authelia portal site block:

auth.mydomain.com {
    reverse_proxy authelia:9091
}

4. Protect existing services

For any existing service you want to protect, add import authelia to its site block:

existingservice.mydomain.com {
    import authelia           add this line
    reverse_proxy container:port
}

Services without import authelia are unaffected — they keep working exactly as before.

5. Reload Caddy

docker exec -w /etc/caddy caddy caddy reload

6. Start Authelia

cd ~/docker/authelia && docker compose up -d

Notes for existing setups

  • Authelia does NOT interfere with services that don't import the snippet
  • Services with their own login (Portainer, Nextcloud, etc.) should NOT use import authelia
  • If an existing service breaks after adding Authelia, remove import authelia from its block
  • The Authelia session cookie is scoped to your domain — it won't affect other domains you host

Adding users

  1. Edit ~/docker/authelia/config/users.yml
  2. Add user block with hash
  3. Restart Authelia: docker compose restart authelia
  4. Tell user to use "Forgot Password" to set their own password

Logging in

Username, not email. Authelia's file backend uses the key name from users.yml as the login username, not the email address.

Example — if users.yml has:

users:
  john:
    email: john@example.com

Login with john, not john@example.com. The email is only used for TOTP registration and password reset emails.

  1. User logs in with username + temporary password
  2. Authelia emails a TOTP registration link — click it
  3. Authelia shows a QR code:
    • Password manager (Bitwarden, 1Password) — may intercept and register automatically
    • Separate app (Google Authenticator, Authy) — scan the QR code manually
  4. Enter the 6-digit code to confirm registration
  5. Every login after: username + password + 6-digit code

Note: if using a password manager, it may complete TOTP setup without showing the QR code — this is normal and correct.

Updating Authelia

Only update when you have a specific reason (bug fix, security issue). Change the version tag in docker-compose.yml then:

docker compose pull authelia
docker compose up -d authelia

Notes

  • Secrets never go in git — they live in config/secrets/ which is gitignored
  • .env files never go in git
  • Session cookies are valid across all *.mydomain.com subdomains — one login covers everything
  • SQLite database lives in ~/docker/authelia/data/ — back this up to preserve user TOTP registrations