Authentik is an open-source identity and access management (IAM) solution designed to streamline user authentication and authorization. This Authentik Docker Compose tutorial is going to show you how to easily add a secure multi-factor authentication to your infrastructure.
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 [VIDEO] [2024]
- Nginx Proxy Manager Docker Compose Guide: Simplest Reverse Proxy [coming soon]
- Ultimate Traefik v3 Docker Compose Guide: Best Reverse Proxy [VIDEO] [2024]
- Authelia Docker Compose Guide: Secure 2-Factor Authentication [VIDEO] [2024]
- Ultimate Authentik Docker Compose Guide with Traefik [2025]
- 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: 110+ Apps (Traefik, Authentik, and more) 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 Authentik (self-hosted), Authelia (self-hosted), or Google OAuth (if you trust Google).
While I have covered Authelia and Google OAuth many times in the past, I have stayed away from Authentik because it felt too complex for a homelab environment.
Well, I finally cracked it and made it work with my Docker Traefik stack (thanks to brokenscripts), which you may be familiar with. It is therefore time to share my learnings and help you setup Authentik using Docker Compose.
Table of Contents
- What is Authentik?
- Authentik Docker Setup
- Authentik Configuration
- Enabling Authentication and Conditional Bypassing
- Final Thoughts on Authentik for Docker Traefik
What is Authentik?
Built with a modern and user-friendly approach, Authentik offers powerful features for managing user identities, supporting various authentication protocols like OAuth2, OpenID Connect, SAML, and LDAP.
It is designed for flexibility and scalability, making it a great choice for both homelabbers and organizations.
The schematic below shows how Authentik fits into the grand scheme of things.
I strongly urge that you familiarize yourself with at least Authentik Terminology and Authentik architecture.
Authentik Features
Here are some key features of Authentik:
- Self-Hosted Identity Management: Authentik provides a robust, self-hosted solution for managing user authentication and access control, ideal for homelab environments where you want complete control over your services and security.
- Single Sign-On (SSO): Simplify authentication across multiple services in your homelab. Authentik enables Single Sign-On (SSO), so you can use a single set of credentials to access all your apps and services, reducing login fatigue.
- Multi-Protocol Support: Authentik supports OAuth2, OpenID Connect (OIDC), and SAML, enabling you to integrate with a variety of homelab applications like Nextcloud, Home Assistant, or self-hosted Git services.
- Multi-Factor Authentication (MFA): Enhance the security of your homelab with MFA, using methods such as TOTP, WebAuthn, or U2F, ensuring that your critical applications are better protected from unauthorized access.
- User Federation: Integrate with existing identity providers like LDAP or Active Directory, making it easier to manage users and authentication without duplicating efforts, particularly in larger homelabs with multiple services.
- Access Control: Set up fine-grained access control policies, specifying which users or groups can access certain services in your homelab, offering a customizable security model.
- Customizable Authentication Flows: Tailor the login experience to suit your homelab's needs. Authentik lets you create and modify authentication workflows, such as adding custom branding or adjusting the login flow.
- Audit Logging: Track who is accessing what in your homelab with detailed audit logs, helping you monitor user activity and troubleshoot authentication-related issues.
- Web Interface: Simplifies configuration and managing authentication.
Authentik Alternatives
Are there alternatives to Authentik? Sure, there are many replacements for Authentik: Authelia, Google OAuth, Keycloak, and Zitadel. But Authentik has been growing in popularity among homelabbers.
Authentik vs Authelia
Among self-hosters, this would be the biggest conundrum. Authentik has been gaining a lot of traction as a replacement for Authelia. But Authentik appears to be geared more towards enterprise environments.
Consequently, it offers more features and integrations and is also more complex to setup. For example, Authelia requires just one docker container whereas Authentik requires multiple. One advantage of Authentik over Authelia, in my opinion, is the web interface for administration.
As with everything. Once you figure it out, it gets easier and the opinion changes.
Authentik 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 a private authentication layer that is open-source fascinates you, then Authentik is a strong candidate to consider.
Authentik vs Others
I have personally not administered Keycloak but have used it as a user and spoken to others that administer it. In my limited knowledge, Keycloak involves a complex setup. To be fair, I thought the same thing about Authentik too until recently.
Zitadel is a relatively new player in the space and I do not know much about it to compare. So if you have an opinion to share, please share your thoughts in the comments section below.
Authentik Docker Setup
As mentioned before, Authentik is one of the more complex docker-based authentication/identity-providers to setup. This is because it requires 4 different services:
- Authentik Server: The server container consists of two sub-components, the actual server itself and the embedded outpost. Together they handle the logic, flows, SSO requests, API requests, etc.
- Authentik Worker: The worker executes background tasks, such as sending emails, notifications, etc.
- PostgreSQL: Database to store all configuration data.
- Redis: Cache non-persistent data, such as session details. Improves responsiveness, in a high activity environment.
Automated Authentik Setup
If you have not heard of Deployarr, then you should consider checking out this detailed walkthrough.
Deployarr makes it very easy to setup and activate Authentik in just under 5 minutes. Check it out:
Of course, Deployarr can do a lot more than just installing Authentik.
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 does should be possible by following this guide without paying for Deployarr. But my hope is that you continue to support my work by becoming a member.
Docker Environment
I am going to assume that you already have Docker and Docker Environment setup. If not, here are the guides to follow:
To recap, here is how our docker folder structure looks like:
- /home/user/docker - Docker root folder is the folder that houses all the files related to our Docker stack, like the compose files, secrets, etc.
- /home/user/docker/compose/hostname - Folder that contain all the individual compose files for various apps. hostname is the name of your docker host. If you followed Anand's Docker Media Server guide, this may be UDMS, as set in the .env file.
- /home/user/docker/docker-compose-hostname.yml - The master docker compose file that brings all the individual compose files together.
- /home/user/docker/.env - The environmental variables file.
- /home/user/docker/secrets - The Docker secrets folder to house some of the sensitive info.
You can find a more detailed description of various Docker files and folders here.
Creating Variables and Secrets
Now that our Docker environment is ready, let's create some variables and secrets for Redis, PostgreSQL, and Authentik. These will be used in the Docker compose files discussed later in this Authentik Docker guide.
Variables for Authentik Stack
Open .env file in your Docker folder and add the following variables:
REDIS_PORT='6379' POSTGRES_USER='postgres_user' POSTGRESQL_PORT='5432' AUTHENTIK_REDIS__HOST='redis' AUTHENTIK_POSTGRESQL__HOST='postgresql' AUTHENTIK_POSTGRESQL__NAME='authentik' AUTHENTIK_POSTGRESQL__USER='file:///run/secrets/authentik_postgresql_user' AUTHENTIK_POSTGRESQL__PASSWORD='file:///run/secrets/authentik_postgresql_password' AUTHENTIK_SECRET_KEY='file:///run/secrets/authentik_secret_key'
- REDIS_PORT: The default Redis port is 6379. You can leave it at that unless you know for sure that you need a different port.
- POSTGRES_USER: The default admin user for PostgreSQL database. Change it if you prefer.
- POSTGRES_PORT: The default port for PostgreSQL is 5432. You can leave it at that.
- AUTHENTIK_REDIS__HOST: The host name of the Redis service. If you are following this guide, that will be just redis.
- AUTHENTIK_POSTGRESQL__HOST: This is the host name of the PostgreSQL service, which is postgresql in this guide.
- AUTHENTIK_POSTGRESQL__NAME: Name for the Authentik database. We can just call it authentik.
- AUTHENTIK_POSTGRESQL__USER: Username for the authentik PostgreSQL database. We will create this as a secret later on. For now, just set it to file:///run/secrets/authentik_postgresql_user.
- AUTHENTIK_POSTGRESQL__PASSWORD: We will generate this secret later on. For now, just set it to file:///run/secrets/authentik_postgresql_password.
- AUTHENTIK_SECRET_KEY: This will be also be generated and set as a Docker secret later on. For now, just set it to file:///run/secrets/authentik_secret_key.
In addition, DOCKERDIR should be a variable that is set to point to your desired Docker root folder as described in my Docker guide (e.g. /home/anand/docker).
Docker Secrets for Authentik Stack
Next, let us create the required secrets. If you are reading about Authentik, then you probably already know what a Docker secret is. If not, follow my Docker guide.
First, elevate yourself with sudo and navigate to the secrets folder inside the Docker root folder. Then, run the following commands:
openssl rand -base64 36 | tr -d '\n' | sudo tee postgres_default_password echo "authentik_db_user" | sudo tee authentik_postgresql_user openssl rand -base64 60 | tr -d '\n' | sudo tee authentik_postgresql_password openssl rand -base64 60 | tr -d '\n' | sudo tee authentik_secret_key
You do not really need to customize anything. But, if you wish you can change the name of the Authentik PostgreSQL user to something other than authentik_db_user.
I have found that with Authentik running as a non-root user, it cannot read the secrets with permission 600, which is expected. So, we will have to change the permissions of all the Authentik secrets to 644 using the following command. While inside the secrets folder, use:
sudo chmod 644 authentik_*
That's about it for variables and secrets for Authentik stack.
Call Docker Secrets in the Compose File
To complete the inclusion/recognition of the secrets by Docker compose files, we will have to call the secrets in the Docker compose files. If you have been following my way, then add the following to the master docker compose file.
... secrets: postgres_default_passwd: file: $DOCKERDIR/secrets/postgres_default_passwd authentik_postgresql_user: file: $DOCKERDIR/secrets/authentik_postgresql_user authentik_postgresql_password: file: $DOCKERDIR/secrets/authentik_postgresql_password authentik_secret_key: file: $DOCKERDIR/secrets/authentik_secret_key ...
If you created a new docker compose stack for Authentik, you can still copy-paste the above. If you already have an existing secrets: section then just add the 4 secrets we created to the existing list.
Be the 1 in 200,000. Help us sustain what we do.You will gain benefits such as Deployarr access, discord roles, exclusive content, ad-free browsing, and more.🔥 Holiday Sale! 25% Off Platinum Membership$399.99$299.99 (ends December 31).Join the Geek Army (starting from just $1.67/month)
Authentik Docker Compose Stack
Next, we are ready to build our Authentik stack. There are many ways to do this. Some people prefer to keep all services in one docker compose file. Some people also like to create a separate database for each service that requires it and so on.
As shown above, I like to split my services into individual compose files and include them in the main Docker compose file. In addition, I try to reuse existing database service when possible to keep things as lean as possible. Whichever way you choose, this Authentik Docker compose guide should be sufficient.
Redis Docker Compose Setup
First, let's start with Redis. I covered Redis docker compose setup in a separate guide. For now, below is the Docker compose to use for Redis:
services: # Redis - Key-value Store redis: image: docker.io/library/redis:alpine container_name: redis security_opt: - no-new-privileges:true restart: unless-stopped profiles: ["core", "all"] command: --save 60 1 --loglevel warning healthcheck: test: ["CMD-SHELL", "redis-cli ping | grep PONG"] start_period: 20s interval: 30s retries: 5 timeout: 3s networks: - default ports: - "$REDIS_PORT:6379" volumes: - $DOCKERDIR/appdata/redis:/data
If you have read/followed my Docker guide or video, then most of above lines should be obvious.
We have already set REDIS_PORT and DOCKERDIR variables. While Docker can auto create missing folders, let's pre-create it to ensure proper permissions. In this case, the only folder that is needed is $DOCKERDIR/appdata/redis. If we assume $DOCKERDIR refers to /home/anand/docker then the commands are:
mkdir -p /home/anand/docker/appdata/redis sudo chown -R anand:anand /home/anand/docker/appdata/redis
Now if you have a master docker compose file, you may include Redis into that as I show in my Docker guides and videos:
... include: - compose/$HOSTNAME/redis.yml ...
In the above case, I assumed that you stored the redis.yml file inside the folder compose/$HOSTNAME in the Docker root folder. $HOSTNAME will be automatically set to the hostname (e.g. UDMS if you followed my guides) of your Docker machine.
At this point, you may start redis and ensure that it works, using the following commands:
sudo docker compose -f /home/anand/docker/docker-compose-udms.yml up -d redis sudo docker compose -f /home/anand/docker/docker-compose-udms.yml logs redis
Or, you may use my Docker Bash Aliases to simplify the commands and make your Docker management easier.
If everything goes well, the logs should look like what is shown below.
PostgreSQL Docker Compose Setup
Next, let's create the PostgreSQL docker compose file. Add it to the existing Docker compose file, or create a new compose file with the name postgresql.yml inside compose/$HOSTNAME as we did with Redis.
services: # PostgreSQL - Database postgresql: container_name: postgresql image: postgres:16-alpine security_opt: - no-new-privileges:true restart: unless-stopped profiles: ["core", "all"] healthcheck: test: ["CMD-SHELL", "pg_isready -d postgres -U $${POSTGRES_USER}"] start_period: 20s interval: 30s retries: 5 timeout: 5s networks: - default ports: - "$POSTGRESQL_PORT:5432" volumes: - $DOCKERDIR/appdata/postgresql:/var/lib/postgresql/data environment: - POSTGRES_USER=$POSTGRES_USER - POSTGRES_PASSWORD_FILE=/run/secrets/postgres_default_passwd secrets: - postgres_default_passwd
We already defined all the environment variables and docker secrets in the previous steps. So there is nothing to change here as well. As we did with Redis, let's pre-create folders with proper permissions.
mkdir -p /home/anand/docker/appdata/postgresql sudo chown -R anand: /home/anand/docker/appdata/postgresql
Again, you can start and test PostgreSQL at this point as we did with Redis above. The logs should say listening on port 5432 and ready to accept connections as shown below.
Authentik Server Docker Compose Setup
With both Redis and PostgreSQL running, we are now ready to create the Docker Compose for Authentik. Let's start with the Authentik server. We are going to call it just Authentik.
Below is the compose file to use for Authentik server. There is a lot going on here so hold on.
services: authentik: image: ghcr.io/goauthentik/server:2024.12.0 container_name: authentik security_opt: - no-new-privileges:true restart: unless-stopped profiles: ["core", "all"] networks: - default - t3_proxy ports: - "9000:9000" # - "9443:9443" # HTTPS command: server user: ${PUID}:${PGID} depends_on: postgresql: condition: service_healthy redis: condition: service_healthy environment: - AUTHENTIK_REDIS__HOST - AUTHENTIK_POSTGRESQL__HOST - AUTHENTIK_POSTGRESQL__NAME - AUTHENTIK_POSTGRESQL__USER - AUTHENTIK_POSTGRESQL__PASSWORD - AUTHENTIK_SECRET_KEY - AUTHENTIK_LOG_LEVEL=info # debug, info, warning, error, trace - AUTHENTIK_DISABLE_STARTUP_ANALYTICS=true - AUTHENTIK_DISABLE_UPDATE_CHECK=false - AUTHENTIK_ERROR_REPORTING__ENABLED=false secrets: - authentik_postgresql_user - authentik_postgresql_password - authentik_secret_key volumes: - $DOCKERDIR/appdata/authentik/media:/media - $DOCKERDIR/appdata/authentik/custom-templates:/templates # - $DOCKERDIR/appdata/authentik/geoip/data:/geoip # requires geoipupdate labels: - "traefik.enable=true" # HTTP Routers - "traefik.http.routers.authentik-rtr.entrypoints=websecure" - "traefik.http.routers.authentik-rtr.rule=Host(`authentik.$DOMAINNAME_1`)" # Middlewares - "traefik.http.routers.authentik-rtr.middlewares=chain-no-auth@file" # Catch any subdomain using individual application forward authentication - "traefik.http.routers.authentik-output-rtr.rule=HostRegexp(`{subdomain:[a-z0-9-]+}.${DOMAINNAME_1}`) && PathPrefix(`/outpost.goauthentik.io/`)" # HTTP Services - "traefik.http.routers.authentik-rtr.service=authentik-svc" - "traefik.http.services.authentik-svc.loadbalancer.server.port=9000"
Here are some notes about the Authentik Docker Compose file:
- We are calling Authentik server, just authentik. You may see some other documentation call it "authentik_server".
- Version is pinned to 2024.12.0, which is the latest at the time of writing this guide. It is a good idea to pin the version as Authentik usually has frequent break changes in new versions.
- Authentik server container will belong to two networks: 1) default network which gives access postgresql and redis containers and 2) t3_proxy network so Authentik can be integrated with Traefik reverse proxy as we will see later on.
- We only need the HTTPS port (9000) for Traefik integration so 9443 is commented out.
- The command starts an Authentik server inside the container.
- Authentik server container will run as the normal user instead of root.
- With depends_on we are forcing Authentik to start only after PostgreSQL and Redis containers have started and are in "healthy" status.
- Environment variables are self-explanatory and we defined them previously. Similarly, the three secrets were defined previously.
- Authentik requires two folders /media and /templates and we are mounting them persistently on the docker host. The /geoip folder is only required if you plan to use GeoIP feature of Authentik.
- Lastly, we are providing Traefik labels as explained in my Traefik guide. We are also providing a regex to catch any subdomains. As we did with Authelia, we are applying chain-no-auth middleware chain as described in my Traefik guide. Alternatively, you can comment out the middleware section if your setup does not follow my way.
- DOMAINNAME_1 is the variable name for your domain (as explained in my Traefik guide).
Do not start Authentik server container yet. We will add the worker and then test them both at the same time.
Authentik Worker Docker Compose Setup
The only thing that is left is the Authentik worker docker compose. It is going to be essentially the same as the server, except the command: here will be set to worker instead of server.
So here it goes:
services: authentik-worker: image: ghcr.io/goauthentik/server:2024.12.0 container_name: authentik-worker security_opt: - no-new-privileges:true restart: unless-stopped profiles: ["core", "all"] networks: - default - t3_proxy - socket_proxy command: worker user: ${PUID}:${PGID} depends_on: postgresql: condition: service_healthy redis: condition: service_healthy environment: - DOCKER_HOST - AUTHENTIK_REDIS__HOST - AUTHENTIK_POSTGRESQL__HOST - AUTHENTIK_POSTGRESQL__NAME - AUTHENTIK_POSTGRESQL__USER - AUTHENTIK_POSTGRESQL__PASSWORD - AUTHENTIK_SECRET_KEY - AUTHENTIK_LOG_LEVEL=info # debug, info, warning, error, trace - AUTHENTIK_DISABLE_STARTUP_ANALYTICS=true - AUTHENTIK_DISABLE_UPDATE_CHECK=false - AUTHENTIK_ERROR_REPORTING__ENABLED=false secrets: - authentik_postgresql_user - authentik_postgresql_password - authentik_secret_key volumes: - $DOCKERDIR/appdata/authentik/media:/media - $DOCKERDIR/appdata/authentik/custom-templates:/templates # - $DOCKERDIR/appdata/authentik/geoip/data:/geoip # requires geoipupdate # - /var/run/docker.sock:/var/run/docker.sock # Uncomment if NOT using socket-proxy # - $DOCKERDIR/appdata/traefik3/cert_export:/certs:ro # If NOT using reverse proxy, manually map in certificates
Pretty much everything about the Authentik worker docker compose has been explained under the Authentik server section above, except the last two lines. Docker socket access is needed only if you want Authentik to autocreate managed outposts. If that does not make sense, then leave it commented out.
The last line is used if you plan to use your own SSL certificate, instead of the one pulled from LetsEncrypt by Traefik.
Authentik Traefik Configuration
Next, let's create some middlewares to use with Traefik. If you do not know what middleware is or how it is used, be sure to read my Traefik guide or watch my Traefik video.
In the Traefik rules folder (e.g. /home/anand/docker/appdata/traefik3/rules/udms if you followed my guides and videos), create a file called middlewares-authentik.yml. Add the following contents to it:
http: middlewares: # https://github.com/goauthentik/authentik/issues/2366 middlewares-authentik: forwardAuth: address: "http://authentik:9000/outpost.goauthentik.io/auth/traefik" trustForwardHeader: true authResponseHeaders: - X-authentik-username - X-authentik-groups - X-authentik-email - X-authentik-name - X-authentik-uid - X-authentik-jwt - X-authentik-meta-jwks - X-authentik-meta-outpost - X-authentik-meta-provider - X-authentik-meta-app - X-authentik-meta-version
What the middleware does is to pass some important information in the request header to the browser and receiving apps.
If you have multiple middlewares, for example, rate limitting or secure headers like I describe in my Traefik guide, then I suggest creating chains. This step, of course, is optional. But to be aligned with my Traefik guide, let's do it.
In the rules folder, create chain-authentik.yml and add the following it depending on the middlewares you would like to form a chain with:
http: middlewares: chain-authentik: chain: middlewares: - middlewares-rate-limit - middlewares-secure-headers - middlewares-authentik
Thats about it for configuring the Traefik part. We will see how to put apps behind Authentik a bit later in this guide.
Starting and Accessing Authentik
At this point, we are ready to start Authentik server and worker and check the logs.
Let's start the Authentik docker stack using the following command:
sudo docker compose -f /home/anand/docker/docker-compose-udms.yml up -d redis postgresql authentik authentik-worker
Now this time, we are going to "follow" or "tail" logs in real time. Since the worker is the one doing a lot of work during initial setup, we will follow the worker logs using the following command:
sudo docker compose -f /home/anand/docker/docker-compose-udms.yml logs -tf --tail="50" authentik-worker
You will notice that something that looks like what is shown below as the worker sets up many things:
Eventually (in my case it took about 3 min), you will see system check identified no issues. This is a good sign.
At this point, almost all commandline work is done and it is time to check Authentik web interface.
Be the 1 in 200,000. Help us sustain what we do.You will gain benefits such as Deployarr access, discord roles, exclusive content, ad-free browsing, and more.🔥 Holiday Sale! 25% Off Platinum Membership$399.99$299.99 (ends December 31).Join the Geek Army (starting from just $1.67/month)
Authentik Configuration
One of the biggest benefits of Authentik over Authelia is the configuration options available via the web interface. Let's access Authentik web interface using https://authentik.domain.com/if/flow/initial-setup/.
You should be greeted with the option to create the admin user, as shown below.
Create an Application and Provider
After logging in, click on Admin interface, as shown below.
Under Applications, use the Wizard to create an application.
In the Application details screen, the only information needed is the Name. I am calling it Area 51 (keep it generic as this will be visible to the world on the login screen).
Slug is auto populated. Leave everything as-is and hit next.
Choose Proxy Provider for provider type.
Next, under proxy provider configuration, select the explicit-consent option. This will require the user to click a button to proceed (additional level of human verification).
Scroll down and pick Forward auth (domain level). Authentication URL should be prefilled with https://authentik.domain.com. Enter just the base domain name for Cookie domain. Hit next.
No configuration is needed in the bind policy screen. Just hit next.
Verify the information and hit Submit to create the new application.
Configure Outpost
Once the application is created, we need to add it to the "outpost" to activate it. To do that, while still on the Admin interface, go to Outposts and hit the edit icon for authentik Embedded Outpost, as shown below.
Highlight the application and hit the right arrow icon to select the application, as shown below.
Hit Update and you are done. At this point you may stop with Authentik configuration and proceed to enabling Authentik for apps. But I suggest 2 more optional configurations.
Change Username
Authentik comes with a default admin username: akadmin. It is always a good idea to change the default username. While still on the Admin interface, under Directory->Users, edit the user akadmin, as shown below.
Change the username to your preference and hit Update.
Don't Be a Jimmy!
If you attempt to change the username while not on Admin interface, you will see "Not allowed to change username" error.
Enable Multi-Factor Authentication
By default MFA is disabled on Authentik. Authentik supports many MFA, including, TOTP, Duo, SMS, and many more. We are going enable the simple TOTP option. Check out Authentik docs for other options.
To enable TOTP, go to Flows and Stages->Stages and find default-authentication-mfa-validation.
Force the user to configure and authenticator and enable TOTP as shown above.
Logout and login again and the user should be forced to create a time-based one-time passcode (TOTP) using an authenticator app.
Enabling Authentication and Conditional Bypassing
Now that we have Authentik working, let's look at ways to protect apps and also some ways to conditionally bypass authentication. This can be done either using Docker labels or file providers.
Using Docker Labels
If you created the authentik traefik middleware and middleware chain discussed above, then putting docker services behind Authentik authentication is simple. All you need to do is add the following middleware (chain-authentik or middlewares-authentik) to docker-compose labels:
## Middlewares - "traefik.http.routers.service-rtr.middlewares=chain-authentik@file"
service-rtr could be different for different services. Since Docker labels are not dynamic, you will have to restart the service for the changes to take effect.
Using File Providers
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 authentication (chain-no-auth). Putting it behind Authentik is as simple as specifying to chain-authentik for middleware, as shown below:
http: routers: adguard-rtr: rule: "Host(`ag.{{env "DOMAINNAME_1"}}`)" entryPoints: - websecure middlewares: - chain-authentik 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 rules directory, we have created the route. You should be able to connect to AdGuard Home behind Authentik, without restarting Traefik!
Bypassing Authentik
Many authentication apps have built-in methods to bypass authentication for certain situations. I prefer doing this at the reverse proxy level.
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.
Final Thoughts on Authentik for Docker Traefik
That was it. I am willing to bet that this the most comprehensive Authentik-Traefik guide you might find on the internet. It really took a lot of work. So please consider becoming a member if it helped out.
It seemed like a lengthy process but in reality, implementing this Authentik Docker Compose tutorial shouldn't take more than an hour. I was very satisfied with Google OAuth. I have been hesitant to move to Authentik but I successfully made the jump.
I am not sure if Authentik offers more protection than Google OAuth but I feel like I have more control and obviously more privacy. Adding the duo push authorization instead of TOTP would make it even simpler.
If you have any piece of information that is missing in this Authentik Docker Traefik guide, please feel free to add in the comments to help others. Otherwise, I hope this Docker Compose for Authentik was useful in making your stack more secure.