How to Deploy Authelia – Open-Source Authentication and Authorization Gateway

Updated on 16 April, 2026
Deploy Authelia as a self-hosted authentication layer for SSO and 2FA with Traefik and Docker.
How to Deploy Authelia – Open-Source Authentication and Authorization Gateway header image

Authelia is an open-source authentication and authorization server that provides two-factor authentication (2FA) and single sign-on (SSO) for web applications through a login portal. It acts as a companion for reverse proxies like Traefik, NGINX, and Caddy by allowing, denying, or redirecting requests based on access control policies. With a container size under 20 megabytes and memory usage typically under 30 megabytes, Authelia is one of the most lightweight authentication solutions available.

This article explains how to deploy Authelia on a Linux server using Docker Compose with Traefik as the reverse proxy. It covers directory setup, Authelia configuration, automatic HTTPS with Let's Encrypt, and protecting a sample web application with authentication policies.

Prerequisites

Before you begin, you need to:

Set Up the Directory Structure, Configuration, and Environment Variables

Authelia requires a project directory that holds its configuration file, user database, and secrets for JSON Web Token (JWT) management, session handling, and storage encryption.

  1. Create the project directory with subdirectories for Authelia configuration, secrets, and logs.

    console
    $ mkdir -p ~/authelia/{config,secrets,logs}
    
    • config: Holds the main configuration file (configuration.yml) and the user database (users.yml).
    • secrets: Stores sensitive values such as JWT, session, and storage encryption secrets.
    • logs: Stores Authelia application logs.
  2. Navigate to the project directory.

    console
    $ cd ~/authelia
    
  3. Create the environment file.

    console
    $ nano .env
    
  4. Add the following configuration:

    ini
    DOMAIN=example.com
    LETSENCRYPT_EMAIL=admin@example.com
    

    Replace:

    • example.com with your registered domain (the parent domain for all subdomains).
    • admin@example.com with your email address for Let's Encrypt certificate notifications.

    Save and close the file.

  5. Set ownership on the secrets directory and generate the Authelia secrets. The Authelia container runs as UID 8000 and needs write access to the secrets directory.

    console
    $ sudo chown 8000:8000 ./secrets
    $ sudo chmod 0700 ./secrets
    $ 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"
    
    • chown 8000:8000: Sets ownership to the Authelia container user.
    • chmod 0700: Restricts access to the secrets directory to the owner only.
    • authelia crypto rand: Generates cryptographically secure random strings of 64 characters for each secret file.
  6. Create the Authelia configuration file.

    console
    $ nano config/configuration.yml
    
  7. Add the following configuration. Replace all instances of example.com with your actual domain.

    yaml
    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: '5 minutes'
        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'
    

    Save and close the file.

    • server: Configures Authelia to listen on port 9091.
    • authentication_backend: Uses a file-based user database with Argon2id password hashing.
    • access_control: Denies all requests by default. The app.example.com subdomain requires 2FA, and traefik.example.com requires single-factor authentication.
    • session.cookies: Scopes session cookies to the parent domain example.com, enabling SSO across all subdomains.
    • storage: Uses a local SQLite database for simplicity.
    • notifier: Writes notification emails such as 2FA setup links to a local file. Replace this with Simple Mail Transfer Protocol (SMTP) configuration for production use.
  8. Generate a secure password hash. Replace your-secure-password with your desired password.

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

    Copy the output hash for use in the next step.

  9. Create the user database file.

    console
    $ nano config/users.yml
    
  10. Add the following configuration:

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

    Replace:

    • authuser@example.com with your email address.
    • The password value with your generated hash.

    Save and close the file.

Deploy with Docker Compose

The Docker Compose manifest defines Traefik as the reverse proxy, Authelia as the authentication gateway, and a sample whoami application to demonstrate authentication enforcement. This configuration is based on the official Authelia Docker examples.

  1. Create the Docker Compose manifest.

    console
    $ nano docker-compose.yaml
    
  2. Add the following configuration:

    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
    

    Save and close the file.

    In the above manifest:

    • services: Launches three containers managed by Docker Compose:
      • traefik: Functions as the reverse proxy and TLS termination point with automatic Let's Encrypt certificates.
      • authelia: Runs the authentication gateway on port 9091.
      • whoami: A lightweight service that displays HTTP request headers for testing authentication.
    • command (Traefik): Configures Traefik's core behavior including Docker discovery, HTTP/HTTPS entry points, automatic HTTP-to-HTTPS redirection, and Let's Encrypt certificate generation.
    • environment (Authelia): The X_AUTHELIA_CONFIG_FILTERS: "template" setting enables the template filter that loads secrets from files.
    • labels (Authelia): The forwardAuth labels instruct Traefik to check every request against Authelia before forwarding it to backend services.
    • labels (whoami): The authelia@docker middleware attaches authentication to the whoami service.
    • volumes: The letsencrypt directory stores TLS certificates persistently. The Docker socket enables Traefik to discover and route to containers automatically.
    • restart: unless-stopped: Ensures containers recover automatically after failures or restarts.
  3. Launch the containers.

    console
    $ docker compose up -d
    
  4. Verify all three services are running.

    console
    $ docker compose ps
    

    The output displays three running containers: Traefik, Authelia, and whoami with Traefik listening on ports 80 and 443.

  5. Check the service logs for any errors.

    console
    $ docker compose logs
    

    For more information on managing a Docker Compose stack, see the How to Use Docker Compose article.

Access and Configure Authelia

Authelia serves a web portal for user authentication. The first login requires setting up a Time-based One-Time Password (TOTP) device for 2FA using the filesystem notifier to retrieve verification codes.

  1. Open a web browser and navigate to https://auth.example.com, replacing example.com with your configured domain.

    Authelia sign in page

  2. Sign in with the default credentials:

    • Username: authuser
    • Password: The password you set when generating the hash earlier.
  3. After a successful login, Authelia displays the portal page with a prompt to register your first 2FA device. Click Register device to begin the TOTP setup process.

  4. Authelia displays an Identity Verification dialog requesting a One-Time Code. Since the notifier uses a filesystem backend, retrieve the code from the server.

    console
    $ docker compose exec authelia cat /config/notification.txt
    
  5. After verification, Authelia displays a QR code. Scan it with a TOTP authenticator app such as Google Authenticator, Authy, or Microsoft Authenticator. Enter the 6-digit code from the app to complete the registration.

Test Authentication and Single Sign-On

The whoami container displays HTTP request headers and connection details, allowing you to verify that Authelia correctly enforces authentication and injects identity headers.

  1. Open a web browser and navigate to https://app.example.com, replacing example.com with your configured domain.

  2. Authelia redirects to the login portal at https://auth.example.com. Enter your username and password. Since app.example.com uses a two_factor policy, Authelia prompts for a TOTP code after the password step. Enter the 6-digit code from your authenticator app to gain access.

    Authelia TOTP entry prompt

  3. After successful authentication, the browser displays the whoami output. Verify that Authelia injects identity headers into the proxied request by looking for the following headers:

    Remote-User: authuser
    Remote-Name: Auth User
    Remote-Email: authuser@example.com
    Remote-Groups: admin

    These headers allow backend applications to identify the authenticated user without implementing their own authentication logic.

  4. Test SSO functionality by opening a new tab and navigating to https://traefik.example.com, replacing example.com with your configured domain. Since the session cookie scopes to the parent domain, Authelia recognizes your existing session. The Traefik dashboard requires only one_factor authentication, so Authelia grants access immediately without prompting for credentials again.

    Traefik dashboard

  5. To protect additional web applications, add the Authelia middleware label to any new service in your docker-compose.yaml:

    yaml
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.<service-name>.rule=Host(`newapp.${DOMAIN}`)"
      - "traefik.http.routers.<service-name>.entrypoints=websecure"
      - "traefik.http.routers.<service-name>.tls.certresolver=letsencrypt"
      - "traefik.http.routers.<service-name>.middlewares=authelia@docker"
    

    Then add a corresponding rule in the access_control section of config/configuration.yml:

    yaml
    - domain: 'newapp.example.com'
      policy: 'one_factor'
    

    Run docker compose up -d to apply the changes.

Conclusion

You have successfully deployed Authelia with Traefik as the reverse proxy on a Linux server using Docker Compose. The setup provides centralized 2FA and SSO for web applications behind the proxy. For more information on extending this configuration with SMTP notifications, Lightweight Directory Access Protocol (LDAP) user backends, or OpenID Connect 1.0, visit the official Authelia documentation.

Comments