Authelia is a self-contained and local authentication layer for Docker services. This Authelia Docker Compose tutorial is going to show you how to easily add a secure multi-factor authentication to your Docker stack.
As you may know, I am a big fan of Docker and Traefik. I have covered this in detail in my Ultimate Docker Server series:
Ultimate Docker Server Series:
This post is part of the Docker Server Tutorial Series, which includes the following individual chapters/parts:- Ultimate Docker Server: Getting Started with OS Preparation [VIDEO] [2024]
- Docker Media Server Ubuntu/Debian with 60+ Awesome Apps [VIDEO] [2024]
- ZeroTier VPN Ubuntu, Docker, Synology, Windows: Secure on-the-go access [coming soon]
- Nginx Proxy Manager Docker Compose Guide: Simplest Reverse Proxy [coming soon]
- Traefik Reverse Proxy
- Authelia Docker Compose Guide: Secure 2-Factor Authentication [VIDEO] [2024]
- Google OAuth Docker Compose Guide: Multi-Factor Authentication [VIDEO] [2024]
- Docker Security Practices for Homelab: Secrets, Firewall, and more
- Cloudflare Settings for Docker Traefik Stacks
- Implementing a Backup System for Docker Traefik Stack [coming soon]
- Automate Homelab Setup Deployarr: 60+ Apps in Minutes
In my Traefik guide, I left you with basic HTTP authentication. But urged you to upgrade to a more secure and modern authentication layer such as Authelia (self-hosted) or Google Oauth (if you trust Google).
I covered Authelia in my previous post in 2020 and updated it again earlier in 2024. And, then Authelia 4.38 came out, which had significant changes. Therefore, it's time for an updated Docker Compose guide for Authelia.
We are going to do this in sections. First, we will meet the bare minimum requirements to get Authelia running on Docker. Then, I will leave you with a few Authelia enhancement ideas. We are going to do it all using Docker Compose because it is easier.
Table of Contents
What is Authelia?
Authelia is an open-source authentication and authorization server providing 2-factor authentication and single sign-on (SSO) for your applications via a web portal. It acts as a companion of reverse proxies like Nginx, Traefik, or HAProxy to let them know whether queries should pass through. Unauthenticated users are redirected to the Authelia Sign-in portal instead.
The schematic below shows how Authelia fits into the grand scheme of things.
Detailed information is available on Authelia's GitHub page and its Documentation.
Authelia Features
Here are some key features of Authelia:
- Several kinds of second factor:
- Security Key (U2F) with Yubikey.
- Time-based One-Time password with Google Authenticator.
- Mobile Push Notifications with Duo.
- Password reset with identity verification using email confirmation.
- Single-factor only authentication method available.
- Access restriction after too many authentication attempts.
- Fine-grained access control per subdomain, user, resource and network.
- Support of basic authentication for endpoints protected by single factor.
- Highly available using a remote database and Redis as a highly available KV store.
Types of Authelia Deployment
Authelia supports three scenarios:
- Local: Meant to be used for scenarios where the server is not exposed to the internet. Domains will be defined in the local hosts file and self-signed certificates will be utilized. This is useful for testing.
- Lite: Authelia Lite is for scenarios where the server will be exposed to the internet with proper domains, DNS, and LetsEncrypt certificates. The Lite element refers to minimal external dependencies; File based user storage; SQLite based configuration storage. In this configuration, the service will not scale well.
- Full: Authelia full, is similar to Lite but with scalable setup which includes external dependencies; LDAP based user storage, Database based configuration storage (MariaDB, MySQL or Postgres).
In this Authelia Docker-Compose guide, we are going to setup the Lite scenario, which is sufficient for a typical homelab user. However, we are going to also make it slightly scalable with Redis and MySQL configuration. Only LDAP user storage is not covered here.
Authelia Alternatives
Are there alternatives to Authelia? Sure, there are many replacements for Authelia: Google OAuth, Keycloak, and Authentik.
Authelia vs Google Oauth
We already discussed Google OAuth. I liked Google OAuth 2.0 and I rarely had to login because I am usually logged into my google account on the browser.
I never really had any issues using Google OAuth. But if the thought of using my private authentication layer that is open-source fascinates you, then Authelia is a strong candidate to consider.
Authelia vs Keycloak
I have personally not administered Keycloak but have used it and spoken to others that administer it. In my limited knowledge, my opinion is that Authelia is a lot simpler to administer and use than Keycloak for protecting Docker services. Authelia has also met all my needs so far.
Combined with Cloudflare settings for Docker and Docker Security best practices, Authelia has significantly enhanced the security of my setup.
Authelia vs Authentik
Authentik has been gaining a lot of traction as a replacement for Authelia. But unlike Authelia, Authentik appears to be geared towards enterprise environments. Consequently, it offers more features and integrations but is also more complex to setup. For example, Authelia requires just one docker container whereas Authentik requires multiple.
Automated Authelia Setup
If you have not heard of Deployarr (formerly Auto-Traefik), then you should consider checking out this playlist.
Auto-Traefik makes it very easy to setup and activate Authelia in just under 2 minutes. Check it out:
Of course, Deployarr can do a lot more than just installing Authelia.
Deployarr was launched as a perk to my supporters and to find a way to financially support what I do with this site.
Everything that the Deployarr Script does should be possible by following this series without paying for Deployarr. But my hope is that you continue to support my work by becoming a member.
Be the 1 in 200,000. Help us sustain what we do.You will gain benefits such as discord roles, exclusive content, ad-free browsing, raffles, and more.Become a Sponsor (starting from just $1.67/month)
Authelia Docker Compose Requirements
Before we get started with Authelia docker configuration, ensure that you have read and followed my previous Docker Traefik guide. You should have a working Traefik Docker stack with the Docker root folder defined using the environmental variable $DOCKERDIR.
Authelia Configuration
If you prefer to follow a video guide instead, check out my YouTube video:
That's right. We are going to first configure Authelia before setting it up. Authelia needs some basic configuration to be done before the Authelia docker service can start properly.
Prepare Authelia Folder
In the appdata folder (or a known location), create a folder called authelia. If you have been following my 2024 Ultimate Docker Server series or used Deployarr, this would be in the path /home/anand/docker/appdata.
Then, set the right permissions for the folder using the following commands (replace anand with your username):
sudo chown -R anand:anand /home/anand/docker/appdata/authelia sudo find /home/anand/docker/appdata/authelia/ -type d -exec chmod 750 {} \; sudo find /home/anand/docker/appdata/authelia/ -type f -exec chmod 640 {} \;
With that done, let us begin configuring Authelia.
1. Authelia "Required" Configuration
Authelia configurations are defined in configuration.yml. Some are required and some are optional.
Begin by creating an empty configuration.yml file in the authelia folder we created above and add content to it as defined below (Pay attention to indentation and spaces. YAML will throw errors if proper indentation/spacing are not followed.).
############################################################### # Authelia configuration # ############################################################### server: address: tcp://0.0.0.0:9091/ buffers: read: 4096 write: 4096 endpoints: enable_pprof: false enable_expvars: false disable_healthcheck: false tls: key: "" certificate: "" # https://www.authelia.com/configuration/miscellaneous/logging/ log: level: info format: text file_path: /config/authelia.log keep_stdout: true # https://www.authelia.com/configuration/second-factor/time-based-one-time-password/ totp: issuer: example.com period: 30 skew: 1 # AUTHELIA_DUO_PLACEHOLDER # https://www.authelia.com/reference/guides/passwords/ authentication_backend: password_reset: disable: false refresh_interval: 5m file: path: /config/users.yml password: algorithm: argon2id iterations: 1 salt_length: 16 parallelism: 8 memory: 256 # blocks this much of the RAM # https://www.authelia.com/overview/authorization/access-control/ access_control: default_policy: deny rules: # - domain: # - "*.example.com" # - "example.com" # policy: bypass # networks: # bypass authentication for local networks # - 10.0.0.0/8 # - 192.168.0.0/16 # - 172.16.0.0/12 - domain: - "*.example.com" - "example.com" policy: two_factor # https://www.authelia.com/configuration/session/introduction/ session: name: authelia_session same_site: lax expiration: 7h inactivity: 5m remember_me: 1M cookies: - domain: 'example.com' authelia_url: 'https://authelia.example.com' default_redirection_url: 'https://example.com' # AUTHELIA_REDIS_PLACEHOLDER # https://www.authelia.com/configuration/security/regulation/ regulation: max_retries: 3 find_time: 10m ban_time: 12h # https://www.authelia.com/configuration/storage/introduction/ storage: # For local storage, uncomment lines below and comment out mysql. https://docs.authelia.com/configuration/storage/sqlite.html # This is good for the beginning. If you have a busy site then switch to other databases. local: path: /config/db.sqlite3 # https://www.authelia.com/configuration/notifications/introduction/ notifier: disable_startup_check: false # For testing purposes, notifications can be sent in a file. Be sure to map the volume in docker-compose. filesystem: filename: /config/notifications.txt
Customizing Authelia Configuration
At any point, you may refer to Authelia Documentation to further customize your setup.
The defaults above should work for most Docker Authelia setups. But here are some notes:
Server
This is quite straightforward. With the server directive, we are asking authelia to listen on all network interface (0.0.0.0) on port 9091.
server: address: tcp://0.0.0.0:9091/
There are a few other settings under server but they rarely require any tweaking.
Log
Default is set to info. But when creating bypass rules or troubleshooting, you may change the level to debug or trace.
# https://www.authelia.com/configuration/miscellaneous/logging/ log: level: info format: text file_path: /config/authelia.log keep_stdout: true
The logs will be stored in /config/authelia.log file inside the container. Since we will be mapping the /config folder to /home/anand/docker/appdata/authelia on the Docker host, you will find authelia.log inside this folder.
totp
Authelia uses time-based one-time-passwords (TOTP). By default, it is set to rotate every 30 seconds. The details for above settings are here. However, it is highly recommended not to mess with these.
# https://www.authelia.com/configuration/second-factor/time-based-one-time-password/ totp: issuer: simplehomelab.com period: 30 skew: 1
Replace simplehomelab.com with your domain name.
authentication_backend
We are going to use file-based authentication (users.yml) with one of the strongest hashing algorithms for passwords (argon2id). We will create the users file in the later steps.
For passwords, argon2id is the recommended hashing algorithm. You may choose to use sha512 (recommended for low power devices). The defaults shown above for iterations, salt_length, parallelism, and memory should work for most instances. You may customize them based on this documentation.
# https://www.authelia.com/reference/guides/passwords/ authentication_backend: password_reset: disable: false refresh_interval: 5m file: path: /config/users.yml password: algorithm: argon2id iterations: 1 salt_length: 16 parallelism: 8 memory: 256 # blocks this much of the RAM
We are also disabling the ability to reset passwords. You may or may not want to turn this on in a multi-user environment.
access_control
For access control, we are denying access by default. Everything will require two-factor authentication.
You have the flexibility to bypass authentication for certain situations (e.g. requests from LAN IPs). This will be discussed in the enhancements section below. Meanwhile, feel free to check Authelia documentation for other ways to customize access.
# https://www.authelia.com/overview/authorization/access-control/ access_control: default_policy: deny rules: - domain: - "*.simplehomelab.com" - "simplehomelab.com" policy: two_factor
session
Customizing the session will determine how long authentication will be valid. Shorter intervals will result in more frequent multi-factor authentication. You can further enhance the performance of session storage by using a database backend and Redis as described later.
But this is optional and improvements are marginal in a single-user environment.
# https://www.authelia.com/configuration/session/introduction/ session: name: authelia_session same_site: lax expiration: 7h inactivity: 5m remember_me: 1M cookies: - domain: 'example.com' authelia_url: 'https://authelia.simplehomelab.com' default_redirection_url: 'https://simplehomelab.com' # AUTHELIA_REDIS_PLACEHOLDER
We are redirecting "unknown" target URLs to https://simplehomelab.com (simplehomelab.com is the test domain I use in my guides). You may change this to another page if you would like.
regulation
Regulation provides a layer of security by banning brute-force attempts. We are banning any user that has three incorrect attempts in 5 minutes (300 seconds).
# https://www.authelia.com/configuration/security/regulation/ regulation: max_retries: 3 find_time: 10m ban_time: 12h
Note that the user account will be banned, not the IP. While this can slow down brute-force attack, an intrusion prevention system such as CrowdSec is strongly recommended.
How-To Series: Crowd Security Intrusion Prevention System
storage
Authelia has built-in session storage using SQLite. This is sufficient for a single-user environment.
# https://www.authelia.com/configuration/storage/introduction/ storage: # For local storage, uncomment lines below and comment out mysql. https://docs.authelia.com/configuration/storage/sqlite.html # This is good for the beginning. If you have a busy site then switch to other databases. local: path: /config/db.sqlite3
Replacing SQLite with a database such as MySQL (described later) offers performance, scalability, and the ability to run multiple authelia instances.
notifier
Finally, notifications can be done in two ways: file or via email. Email requires a valid SMTP server, which may or may not be available in your case.
For now, we will send all notifications to a file called notifications.txt inside the authelia config folder.
# https://www.authelia.com/configuration/notifications/introduction/ notifier: disable_startup_check: false # For testing purposes, notifications can be sent in a file. Be sure to map the volume in docker-compose. filesystem: filename: /config/notifications.txt
2. Authelia Secrets
In my 2020 version of this guide, I did not use Docker secrets. I used environment variables. With revision and as with my Ultimate Docker Guide 2024, I am taking secure approach from the beginning. So, let's pass sensitive information as Docker Secrets.
At the minimum, 3 secret tokens are needed for Authelia: identity_validation.reset_password.jwt_secret, storage.encryption_key, and session_secret. All the secrets supported by Authelia are listed here.
Let's create the 3 for now. Adding secrets to Docker is essentially a multi-step process, as explained in part 2 of this Docker series.
Create Secrets Folder
If you haven't already done so, create a folder called secrets in a known location. If you have been following my guides, this would be /home/anand/docker/secrets. The folder must be owned by root:root and have 600 permission as shown below.
Create the Secret Files
Next, use the following commands to automatically create a random string for each secret and save them in the secrets folder (/home/anand/docker/secrets/).
tr -cd '[:alnum:]' </dev/urandom | fold -w "64" | head -n 1 | tr -d '\n' | sudo tee /home/anand/docker/secrets/authelia_jwt_secret
tr -cd '[:alnum:]' </dev/urandom | fold -w "64" | head -n 1 | tr -d '\n' | sudo tee /home/anand/docker/secrets/authelia_storage_encryption_key
tr -cd '[:alnum:]' </dev/urandom | fold -w "64" | head -n 1 | tr -d '\n' | sudo tee /home/anand/docker/secrets/authelia_session_secret
Secret Permissions
Next, let's ensure proper permissions for those using the following command:
sudo chown root:root /home/anand/docker/secrets/authelia* sudo chmod 600 /home/anand/docker/secrets/authelia*
Notice that they all have the same permissions (owner root, group root, and 600 permissions) as the secrets folder.
Don't worry about any missing or additional ones. We will add a few more later. The above is just an example to show the permissions.
Add Authelia Secrets to Master Docker Compose
Open your master docker compose file for editing. If you have been following the Ultimate docker server series, this might be docker-compose-udms.yml (or whatever you named it to be).
Under secrets section, ensure you define the three secrets we created above:
########################### SECRETS secrets: ... authelia_jwt_secret: file: $DOCKERDIR/secrets/authelia_jwt_secret authelia_session_secret: file: $DOCKERDIR/secrets/authelia_session_secret authelia_storage_encryption_key: file: $DOCKERDIR/secrets/authelia_storage_encryption_key ...
Note that, $DOCKERDIR is the environment variable defined in .env file to represent /home/anand/docker.
If you have any questions on where exactly this is added, check out the compose files in my GitHub Repo.
We have now completed 2 of the 4 steps in adding secrets. We will perform the remaining 2 steps when we create the Authelia Docker Compose file.
3. Authelia Users
Next, let's create a user. In our configuration.yml file we said users are in the users.yml file, which is described here.
Create a file called users.yml inside authelia configuration folder in appdata, and add the following contents to it:
############################################################### # Users Database # ############################################################### # This file can be used if you do not have an LDAP set up. # List of users users: AUTHELIA_USERNAME: disabled: false displayname: "AUTHELIA_USER_DISPLAY_NAME" email: AUTHELIA_USER_EMAIL password: AUTHELIA_HASHED_PASSWORD groups: - admins
Replace AUTHELIA_USERNAME with a username for the user.
Change AUTHELIA_USER_DISPLAY_NAME to a name for the user. AUTHELIA_USER_EMAIL can be a valid email or a dummy email. Remember that we do not have an SMTP server and no emails will be sent. Instead, all notifications will be stored in the notifications.txt file. Therefore, the validity of the email does not matter.
AUTHELIA_HASHED_PASSWORD is the hashed password. NOT the plain text password. To hash the password, use the following command:
sudo docker run -v /home/anand/docker/appdata/authelia/configuration.yml:/configuration.yml -it authelia/authelia:4.38.8 authelia crypto hash generate --config /configuration.yml --password MYSTRONGPASSWORD
Replace MYSTRONGPASSWORD with your strong password. Your password will be hashed using the argon2id algorithm and displayed as shown below.
Copy hashed password in its entirety (highlighted by red box) and replace AUTHELIA_HASHED_PASSWORD in the users.yml.
Save the file and exit.
Adding Additional Users
4. Authelia Traefik Configuration
Now that Authelia configuration is done. Let us configure Traefik to use Authelia.
Building on the same framework we built using the Docker-Traefik guide, we need to add two sections to Traefik configuration: a middleware for authelia and a middleware chain for authelia.
Authelia Traefik Middleware
First, let us create a Authelia Traefik middleware that will forward authentication to the Authelia container. Create a file called middlewares-authelia.yml in your Traefik rules folder and add the following contents to it:
http: middlewares: middlewares-authelia: forwardAuth: address: "http://authelia:9091/api/verify?rd=https://authelia.{{env "DOMAINNAME_HS"}}" trustForwardHeader: true authResponseHeaders: - "Remote-User" - "Remote-Groups"
Remember the DOMAINNAME_HS environmental variable we passed into Traefik container? This is where it comes in handy. {{env "DOMAINNAME_HS"}} will refer to the domain name set for this variable. You may replace it and hardcode your domain name.
We are basically specifying the URL to which authentication requests must be forwarded.
Since this is a dynamic configuration using a file provider, traefik will pick it up automatically.
Authelia Middleware Chain
Again, building on my Traefik guide, let's build the middleware chain for Authelia.
We will reuse a few of the middlewares from the Traefik guide: middlewares-rate-limit and middlewares-secure-headers.
Create a file called chain-authelia.yml in your Traefik rules folder and add the following contents to it:
http: middlewares: chain-authelia: chain: middlewares: - middlewares-rate-limit - middlewares-secure-headers - middlewares-authelia
If you do not understand what this does, then I suggest reading my Traefik guide.
In short, we are rate limit and specifying security headers, which are both security measures. Then we are including Authelia authentication in the chain (the middleware we created in the previous step).
That's it. We are now ready to create Authelia docker-compose file.
Be the 1 in 200,000. Help us sustain what we do.Join Us (starting from just $1.67/month)
5. Authelia Docker Compose (v4.38 and Above)
Now that all the configuration part is done. Let us add the Authelia docker compose service.
Create Authelia Docker Compose File
Let's create the Authelia Docker compose file. Head over to the compose folder in my Github Repository, and then into any of the host folders. Find the compose file for Authelia and copy the contents.
Create a file called authelia.yml inside /home/anand/docker/compose/udms. Copy-paste the contents into authelia.yml compose file (pay attention to blank spaces at the beginning of each line).
services: # Authelia (Lite) - Self-Hosted Single Sign-On and Two-Factor Authentication authelia: container_name: authelia image: authelia/authelia:4.38.8 security_opt: - no-new-privileges:true restart: unless-stopped # profiles: ["core", "all"] networks: - t3_proxy - default # ports: # - "9091:9091" volumes: - $DOCKERDIR/appdata/authelia:/config environment: - TZ=$TZ - PUID=$PUID - PGID=$PGID - AUTHELIA_IDENTITY_VALIDATION_RESET_PASSWORD_JWT_SECRET_FILE=/run/secrets/authelia_jwt_secret - AUTHELIA_SESSION_SECRET_FILE=/run/secrets/authelia_session_secret - AUTHELIA_STORAGE_ENCRYPTION_KEY_FILE=/run/secrets/authelia_storage_encryption_key # - AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE=/run/secrets/authelia_storage_mysql_password # - AUTHELIA_SESSION_REDIS_PASSWORD_FILE=/run/secrets/authelia_session_redis_password # - AUTHELIA_DUO_API_INTEGRATION_KEY_FILE=/run/secrets/authelia_duo_api_integration_key # - AUTHELIA_DUO_API_SECRET_KEY_FILE=/run/secrets/authelia_duo_api_secret_key secrets: - authelia_jwt_secret - authelia_storage_encryption_key - authelia_session_secret labels: - "traefik.enable=true" ## HTTP Routers - "traefik.http.routers.authelia-rtr.entrypoints=websecure" - "traefik.http.routers.authelia-rtr.rule=Host(`authelia.$DOMAINNAME_HS`)" ## Middlewares - "traefik.http.routers.authelia-rtr.middlewares=chain-no-auth@file" # Should be chain-no-auth and not chain-authelia ## HTTP Services - "traefik.http.routers.authelia-rtr.service=authelia-svc" - "traefik.http.services.authelia-svc.loadbalancer.server.port=9091"
Here are some notes about the Authelia Docker Compose:
- We are going to fix the Authelia docker image as 4.38.8 because, sometimes, latest tag brings in breaking changes, which can crash your setup.
- Docker profiles is commented out as explained previously (see my Docker guide for how I use profiles).
- networks: We added Authelia to t3_proxy and default networks. You could probably leave out the default network. I included default because my MariaDB container was on default network.
- ports: Exposing ports is typically not needed for Authelia.
- The environmental variable $DOCKERDIR is already defined in our .env file. All Authelia data is being stored in an authelia-specific folder within appdata.
- In the environment and secret sections, we are specifying the 3 Authelia secrets we created previously (steps 3 and 4 in adding secrets).
- With the labels, we are specifying that Authelia will use the websecure entrypoint and chain-no-auth file provider we created previously.
- Authelia listens on port 9091. So, we point authelia-rtr.service to a service name authelia-svc and in the next line, we define where that service is listening at (authelia-svc.loadbalancer.server.port=9091.
Add Authelia to the Docker Stack
We created the authelia.yml file. Now we need to add it to our master docker-compose-udms.yml file. To do so, add the path to the authelia.yml (compose/udms/authelia.yml) file under the include block, as shown below:
... ... include: ... - compose/$HOSTNAME/authelia.yml ...
$HOSTNAME here will be replaced with udms automatically (as defined in the .env file).
Save the Master Docker Compose file.
6. Starting Authelia and Registering
Recreate the stack and follow Authelia container logs using the following commands:
sudo docker compose -f /home/anand/docker/docker-compose-udms.yml up -d sudo docker compose -f /home/anand/docker/docker-compose-udms.yml logs -tf --tail="50" authelia
You should see confirmation that Authelia Docker container started successfully, as shown below. [Read: Dozzle Docker Compose: Simple Docker Logs Viewer]
Now that Authelia Docker container is up and running. Let us test it out.
Authelia First Time Use and Registration
Let's visit https://authelia.simplehomelab.com (obviously use your domain name). Now and while accessing a service protected by Authelia, you should see the following login form.
Log in using the username and password you defined in users.yml file.
Next, you will have to register your device. Click on Methods, choose One-time Password, and then click Not registered yet?, as shown below.
Next, pick One-Time Password as the registration method and hit ADD.
An OTP code will be sent to the email, which you will have to enter in the following screen to confirm registration (IMPORTANT! Keep this screen open until you complete the registration step).
What if you did not configure SMTP server for email notifications? Well, in that case, the code is embedded in the notification saved to notification.txt file.
Open the notifications.txt file inside Authelia config folder in appdata to find the code, as shown below:
Enter the code in the previous screen to confirm device registration. Hit next to continue to OTP registration.
You can use any of the authenticator apps (Duo, Authy, Google Authenticator, etc.) to scan the code. I recommend Duo because it supports push notifications, which makes authentications easier (described later).
After scanning, enter the OTP code from the authenticator app into Authelia.
This should complete your account registration for Authelia and you should see something like the screenshot below.
That is about it. You can now start using Authelia multi-factor authentication for your Docker apps. Authelia protects some of my key administration apps such as Guacamole.
Authentication and Conditional Bypassing
Now that we have Authelia working, let's look at ways to protect apps and also some ways to conditionally bypass authentication.
Putting Docker Services behind Authelia
If you created the authelia traefik middleware and middleware chain discussed above, then putting docker services behind Authelia authentication is simple. All you need to do is add the following middleware (chain-authelia) to docker-compose labels:
## Middlewares - "traefik.http.routers.service-rtr.middlewares=chain-authelia@file"
service-rtr could be different for different services. As always, check the docker-compose files in GitHub repo for working examples.
Putting Non-Docker Services behind Authelia
Adding non-docker apps or apps from docker host or external hosts is also quite simple using file providers, as previously explained in my Traefik guide.
Let's take the same example of Adguard Home running on Raspberry Pi, as in my Traefik guide.
Previously, we had AdGuard Home with no Traefik authentication (chain-no-auth). Putting it behind Authelia is as simple as changing the middleware from chain-no-auth to chain-authelia, as shown below:
http: routers: adguard-rtr: rule: "Host(`ag.{{env "DOMAINNAME_HS"}}`)" entryPoints: - websecure middlewares: - chain-authelia service: adguard-svc tls: certResolver: dns-cloudflare options: tls-opts@file services: adguard-svc: loadBalancer: servers: - url: "http://192.168.1.225:80"
Note that AdGuard Home is listening on a non-SSL port. Some services (e.g. NextCloud, UniFi controller, Proxmox etc.) tend to be available via HTTPS protocol with a self-signed certificate. For these, be sure to refer to my guide on putting HTTPS apps behind Traefik.
Since the rules directory is dynamic, simply by adding this file to that directory we have created the route. You should be able to connect to AdGuard Home behind Authelia, without restarting Traefik!
Bypassing Authelia
Although you can use Authelia's built-in access control methods, I do not use it. I leverage custom headers to let Traefik handle the bypassing instead of the authentication service.
Traefik has built-in mechanisms for conditional bypassing. Depending on certain conditions, I can specify a different middleware or a middleware chain. This is explained in detail in my separate guide on Traefik Auth bypass.
Several apps in my GitHub repo have auth bypasses set based on certain conditions.
Authelia Enhancements
At this point, you should already have a fully functional Authelia Docker authentication system. But depending on your situation, you could benefit from some optional enhancements. Let's look at some of those now.
Redis
In simple terms, Redis is a key-value caching mechanism that can enhance the performance of applications that access databases frequently. If you do not have Redis, it is quite easy to have it up and running using Deployarr or with my Redis Docker guide.
If you have a Redis instance available add the following block under session: (replace # AUTHELIA_REDIS_PLACEHOLDER) in configuration.yml file to activate the usage of Redis (pay attention to indentation).
session: # https://www.authelia.com/configuration/session/redis/ redis: host: redis port: 6379
Customize the host with the host running Redis. If Redis and Authelia are on the same Docker network, you can use the hostname (redis; if that is how your Redis service is called). The port is typically 6379.
We are going to use Secrets to provide Redis password.
Adding Secrets for Redis
- You will have to create a secret file: /home/anand/docker/secrets/authelia_session_redis_password.
- Define the secret globally in the master docker compose file.
... authelia_session_redis_password: file: $DOCKERDIR/secrets/authelia_session_redis_password ...
- Define the AUTHELIA_SESSION_REDIS_PASSWORD_FILE environment variable and point it to the secret file.
... environment: - AUTHELIA_SESSION_REDIS_PASSWORD_FILE=/run/secrets/authelia_session_redis_password ...
- Enable the secret in Authelia docker compose.
... secrets: - authelia_session_redis_password ...
Reminder that in a non-busy system, using Redis will have minimal impact. Recreate Authelia for the changes to take effect.
MySQL Storage
Authelia offers several storage backends. In this example, let us use MySQL. Add the following block under storage: in configuration.yml file, paying attention to the indentation.
storage: # https://www.authelia.com/configuration/storage/mysql/ mysql: host: mariadb port: 3306 database: authelia username: DBUSERNAME # password: DBPASSWORD
Once again, if MariaDB and Authelia are on the same network, you can use mariadb for hostname (if that is how your MariaDB service is called). 3306 is the default MariaDB port. Customize the database name and username based on your situation.
Only the password can be specified as a secret (check for supported secrets). The four steps are exactly the same as described for Redis, with minor changes. Use AUTHELIA_STORAGE_MYSQL_PASSWORD_FILE for environment variable name and authelia_storage_mysql_password for secret name.
If you use MySQL, be sure to comment out or remove the SQLite storage backend in the configuration.yml file.
Recreate Authelia for the changes to take effect.
Email Notifications
Storing notifications in a text file is not ideal. If you have an email server (I use and recommend Brevo (there are others too), which is free), you can enable email notification by adding the following block under notifier::
notifier: smtp: username: SMTP_USERNAME # password: SMTP_PASSWORD host: SMTP_HOST port: 587 # Or 465 sender: SENDER_EMAIL
Once again, you can specify the above details in 2 ways: directly in configuration.yml and as environment variables (check for variable names to use).
Only the SMTP_PASSWORD can be specified as a secret (check for supported secrets). The four steps are exactly the same as described for Redis, with minor changes. Use AUTHELIA_NOTIFIER_SMTP_PASSWORD_FILE for environment variable name and authelia_notifier_smtp_password for secret name.
After enabling email notifications, you may choose to disable writing notifications to the notifications.txt file (comment out or remove those lines).
Recreate Authelia for the changes to take effect.
When configured correctly, here is an example of an email you may receive during account registration (of course, a valid email is now necessary).
Enabling Duo Push Notification for Authelia
As I hinted before, I like Duo because it supports push notifications that allow one-click easy login approvals compared to entering the OTP. Enabling this is a little bit of work and unintuitive.
But don't worry, I will walk you through it and it's FREE.
First, head over to Duo's website and register an account.
1. Create a Duo User
From the Users menu, click on Add User as shown below and create a new user.
Fill in the user details.
Scroll down and add a phone number.
2. Activate the User
You should see a warning message (shown below) on the Duo admin page that says that the user is not activated.
Send the activation link to the user's/your phone and click the received link to activate the user.
3. Create an Application
Under Applications, select Protect an Application, search for Partner Auth API and click Protect, as shown below.
Once created, copy the Integration key, Secret key, and API hostname.
4. Configure Duo API in Authelia Configuration
Open up Authelia's configuration.yml and add the following code block to it (replace # AUTHELIA_DUO_PLACEHOLDER).
# https://www.authelia.com/configuration/second-factor/duo/ duo_api: hostname: API_HOSTNAME # integration_key: INTEGRATION_KEY # secret_key: SECRET_KEY
Once again, you can specify the above details in 2 days: directly in configuration.yml and as environment variables (check for variable names to use).
Only the INTEGRATION_KEY and SECRET_KEY can be specified as a secrets (check for supported secrets). The four steps are exactly the same as described for Redis, with minor changes. Use AUTHELIA_DUO_API_INTEGRATION_KEY_FILE and AUTHELIA_DUO_API_SECRET_KEY_FILE for environment variable names and authelia_duo_api_integration_key and authelia_duo_api_secret_key for secret names, respectively.
Recreate Authelia for the changes to take effect.
5. Test Authelia Duo Push Notification
Try to access a Docker app behind Authelia. This time from Methods, choose Push Notification as shown below.
You should receive a push notification on your phone and all you need to do is approve with one click and your login should go through.
Final Thoughts on Authelia for Docker Traefik
It seemed like a lengthy process but in reality, implementing this Authelia Docker Compose tutorial shouldn't take more than an hour. I was very satisfied with Google OAuth. And Authelia is equally awesome or better depending on what is important to you.
I am not sure if Authelia offers more protection than Google OAuth but I feel like I have more control and obviously more privacy. And the duo push authorization made it simpler to use.
Authelia does offer support for hardware security keys. I have not explored those yet but if you do, then you are covered there as well.
If you have any piece of information that is missing in this Authelia Docker guide, please feel free to add in the comments to help others. Otherwise, I hope this Docker Compose for Authelia was useful in making your stack more secure.