Repo had a 0-byte README. New one covers: - Service inventory (authelia + redis) with in-network ports - What the stack provides (login portal + forwardAuth middleware) - How to chain authelia-auth onto other Traefik routes - File-based authentication backend + how to mint argon2id hashes - Configuration file inventory + the three secret env vars - Volume / persistence model (sqlite + Redis session store) - Tailscale-hostname coupling + default one_factor policy as gotchas Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .gitignore | ||
| .python-version | ||
| compose.yml | ||
| configuration.yml | ||
| main.py | ||
| pyproject.toml | ||
| README.md | ||
| users_database.yml | ||
| uv.lock | ||
authelia
Authelia deployment for the homelab — provides forward-auth for Traefik-fronted services. Single-factor by default, with TOTP available.
Services
| Service | Image | Port (in-network) |
|---|---|---|
authelia |
authelia/authelia:latest |
9091 |
authelia-redis |
redis:alpine |
6379 |
No host ports are published — both services are reachable only on the
external traefik docker network. Traefik exposes Authelia at
https://us-test-authy.taila7f44e.ts.net/authelia/ via Tailscale-issued
certs.
What this stack provides
- A
/autheliaportal for login, password reset, and TOTP enrollment. - A
authelia-authforwardAuth middleware that other Traefik routes can chain onto for SSO-style gated access.
The forward-auth middleware is declared by labels on the authelia
service:
traefik.http.middlewares.authelia-auth.forwardAuth.address=http://authelia:9091/authelia/api/authz/forward-auth
To gate any other Traefik route, add the middleware to that service's labels:
traefik.http.routers.<svc>.middlewares=authelia-auth@docker
Authentication backend
File-based, not LDAP. Users live in users_database.yml at the repo
root, mounted read-only into the container at
/config/users_database.yml. Passwords are argon2id hashes — generate
with:
docker run --rm authelia/authelia:latest \
authelia crypto hash generate argon2
Then paste the resulting $argon2id$... string under
users.<id>.password.
Configuration
| File | Purpose |
|---|---|
configuration.yml |
Server settings, access-control rules, session + storage, notifier |
users_database.yml |
File-based user records (id, displayname, argon2id hash, email, groups) |
compose.yml |
Service definitions + Traefik labels + secret env vars |
Three secrets are injected as env vars in compose.yml:
AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRETAUTHELIA_SESSION_SECRETAUTHELIA_STORAGE_ENCRYPTION_KEY
Rotate by replacing those values; restart the stack to pick them up.
Run it
docker compose up -d
docker compose logs -f authelia
Persistence
| Volume | Purpose |
|---|---|
authelia_data |
/config — sqlite storage (db.sqlite3), notifications |
authelia_redis |
/data — Redis session store |
Sessions are kept in Redis (in-memory + AOF), so an authelia-redis
restart loses active logins. Persistent state (TOTP secrets, password
resets) is in the sqlite DB inside authelia_data.
Gotchas
- Hard-coded Tailscale hostname. The TOTP issuer, cookie domain,
and access-control rule all reference
us-test-authy.taila7f44e.ts.net(this host's Tailscale magic-DNS name). Changing the host requires editingconfiguration.yml,compose.ymlTraefik labels, and any clients with TOTP secrets enrolled under the old issuer. access_control.default_policy: one_factor. No 2FA-required rules in the file by default — anything routed throughauthelia-authmiddleware lets users in with just a password. Tighten totwo_factorfor high-sensitivity services by adding arules:entry above the default.- External
traefiknetwork must exist before this stack starts — it's created by thetraefikstack in this samedocker/directory. - The repo also contains some leftover uv-init artifacts (
main.py,pyproject.toml,uv.lock,.python-version). These are not part of the deployment.