# Verified compose for Authelia, tested 2026-10-20 by the SelfHostBench lab (3 runs; the figures are the median). # Lab host: AMD EPYC 7763 64-Core Processor, 2 vCPU, 7.8 GiB RAM, x86_64, Docker 28.0.4. # Floating image tags below were replaced by the version resolved at test time; # the registry digest is in the comment on each image line. # Measurements: authelia.json (schema 3). # Companion env file: authelia.env (save it as .env next to this file). # Secrets are not published: the lab's values are public. In authelia.env: # AUTHELIA_USER_PASSWORD_HASH is commented out. Uncomment it and set your own value (the comment above it explains how). # AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET is commented out. Uncomment it and set your own value (the comment above it explains how). # AUTHELIA_SESSION_SECRET is commented out. Uncomment it and set your own value (the comment above it explains how). # AUTHELIA_STORAGE_ENCRYPTION_KEY is commented out. Uncomment it and set your own value (the comment above it explains how). # Authelia 4.39.28 (authentication and authorization server for a reverse proxy): ONE container, SQLite, no Redis. # The minimal setup for a small self-hoster, from the Authelia docs: # - users in a YAML file (authentication_backend.file), # - SQLite storage (storage.local), # - the file notifier (notifier.filesystem: password-reset codes are written to a file instead of e-mailed), # - the default in-memory session provider (session.redis is not configured). # Docs: https://www.authelia.com/configuration/first-factor/file/ , https://www.authelia.com/configuration/storage/sqlite/ , # https://www.authelia.com/configuration/notifications/file/ , https://www.authelia.com/configuration/session/introduction/ # The configuration and the users file are written inline under `configs:` (Compose 2.23.1 or newer), so there is nothing to create next to this file. # Authelia has to be served over HTTPS ("This is not optional even for testing"). It does not do TLS here: put a reverse proxy that does in front of it # (Caddy, Traefik, nginx), and point the proxy's forward-auth at http://authelia:9091/api/authz/forward-auth. No proxy is in this file. # Replace example.com below with your own domain. Authelia and every protected site must share it: a session cookie is set for ONE domain. name: authelia services: authelia: image: authelia/authelia:4.39.28 # sha256:bd97cff4fcbf715b5ff1f9ae286afbe6033afce385302520b0368122d43a6f54 (version 4.39.28, from exec) restart: unless-stopped environment: # Secrets come from the .env file (Authelia reads AUTHELIA_ variables). The docs' own example uses Docker secrets and *_FILE variables instead. AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET: "${AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET:?set it in .env}" AUTHELIA_SESSION_SECRET: "${AUTHELIA_SESSION_SECRET:?set it in .env}" AUTHELIA_STORAGE_ENCRYPTION_KEY: "${AUTHELIA_STORAGE_ENCRYPTION_KEY:?set it in .env}" volumes: # SQLite database (db.sqlite3) and the notification file. Back this up. - authelia-config:/config configs: - source: authelia_configuration target: /config/configuration.yml - source: authelia_users target: /config/users_database.yml ports: # Localhost only. The reverse proxy on the host sends traffic here. - "127.0.0.1:9091:9091" # The image defines its own healthcheck (wget on /api/health every 30 s). configs: authelia_configuration: content: | # The secrets (jwt_secret, session secret, storage encryption key) are not in this file: Authelia reads them from the # AUTHELIA_* environment variables above. server: address: 'tcp://:9091/' endpoints: authz: # The endpoint your reverse proxy calls for every request. Caddy and Traefik use forward-auth; nginx uses auth-request. forward-auth: implementation: 'ForwardAuth' log: level: 'info' authentication_backend: file: path: '/config/users_database.yml' # Password hashing is the default: Argon2id, 3 iterations, 64 MiB of memory, parallelism 4 (every login uses 64 MiB briefly). access_control: default_policy: 'deny' rules: - domain: 'app.example.com' policy: 'one_factor' session: cookies: - name: 'authelia_session' domain: 'example.com' authelia_url: 'https://auth.example.com' default_redirection_url: 'https://app.example.com' storage: local: path: '/config/db.sqlite3' notifier: filesystem: filename: '/config/notification.txt' authelia_users: content: | users: lab-user: disabled: false displayname: 'Lab User' # Argon2id hash from .env (a new one: docker run --rm -it authelia/authelia:4.39.28 authelia crypto hash generate argon2). password: "${AUTHELIA_USER_PASSWORD_HASH:?set it in .env}" email: 'lab-user@example.com' groups: [] volumes: authelia-config: