🔥 Holiday Sale! 25% Off Platinum Membership and up to 50% Off on Deployarr (ends December 31).

Ultimate Authentik Docker Compose Guide with Traefik 2025

Authentik, together with Traefik can give one of the best dynamic authentication layers for your homelab. This Authentik Docker Compose guide shows exactly that.

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.

Note: If you prefer the convenience of automating Authentik setup + more (e.g. Traefik, Backups, Portainer, Homepage, Arr apps, etc.), then check out Deployarr.

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:
  1. Ultimate Docker Server: Getting Started with OS Preparation [VIDEO] [2024]
  2. Docker Media Server Ubuntu/Debian with 60+ Awesome Apps [VIDEO] [2024]
  3. ZeroTier VPN Ubuntu, Docker, Synology, Windows: Secure on-the-go access [VIDEO] [2024]
  4. Nginx Proxy Manager Docker Compose Guide: Simplest Reverse Proxy [coming soon]
  5. Ultimate Traefik v3 Docker Compose Guide: Best Reverse Proxy [VIDEO] [2024]
  6. Authelia Docker Compose Guide: Secure 2-Factor Authentication [VIDEO] [2024]
  7. Ultimate Authentik Docker Compose Guide with Traefik [2025]
  8. Google OAuth Docker Compose Guide: Multi-Factor Authentication [VIDEO] [2024]
  9. Docker Security Practices for Homelab: Secrets, Firewall, and more
  10. Cloudflare Settings for Docker Traefik Stacks
  11. Implementing a Backup System for Docker Traefik Stack [coming soon]
  12. Automate Homelab Setup Deployarr: 110+ Apps (Traefik, Authentik, and more) in Minutes
It is best to follow the series from the beginning so you not only understand WHAT to do but also WHY we do it.

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.

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.

I do not claim to be an expert on all the features that Authentik offers. This guide will focus on using the Domain-level forward authentication feature of Authentik, with Traefik reverse proxy.

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.

Authentik Schematic
Authentik Schematic

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.

Which authentication system do you prefer or use for your Docker stack?

View Results

Loading ... Loading ...

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 Architecture
Authentik Architecture

  • 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:

Deployarr 5 Intro: Docker Homelab in Minutes🚀

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'
Note that the double underscore in Authetik variable names (e.g. AUTHENTIK_REDIS__HOST) is not a typo. The same way the triple forward slashes in secret file paths (e.g. file:///run/secrets/authentik_secret_key) are not a typo. Pay attention to those.
  • 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_*
Permission of 644 is not ideal as anyone can read Authentik secrets. But with 600, Authentik fails to start due to denied permissions. If someone knows how to address this let me know in the comments section.

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.
130 / 150 by Dec 31, 2024
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.

You will find templates for all Docker compose files in Deployarr Github Repo.

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.

If you prefer, you may also create a new docker compose file and add all 4 services to it to make it an authentik-specific stack. Note that if you choose to put all services in one file, then you only need one service: tag in the compose file.

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.

Redis Logs (Don'T Worry About The Memory Overcommit Warning)
Redis Logs (Don't Worry About The Memory Overcommit Warning)

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.

Postgresql Logs
Postgresql Logs

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.

Authentik takes about 3-4 minutes during the first start as the worker does a lot of initial configurations in the background. Don't Panic!!!

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:

Authentik Docker Compose Logs
Authentik Worker Initial Setup

Eventually (in my case it took about 3 min), you will see system check identified no issues. This is a good sign.

Authentik Worker Initial Setup Complete
Authentik Worker Initial Setup Complete

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.
130 / 150 by Dec 31, 2024
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 must visit the URL path /if/flow/initial-setup/, using the fully qualified domain name, to complete initial setup.

You should be greeted with the option to create the admin user, as shown below.

Authentik Create Admin User
Authentik Create Admin User

Create an Application and Provider

After logging in, click on Admin interface, as shown below.

Go To Authentik Admin Interface
Go To Authentik Admin Interface

Under Applications, use the Wizard to create an application.

Create An Application Using The Wizard
Create An Application Using The Wizard

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.

Provide Application Details
Provide Application Details

Choose Proxy Provider for provider type.

Proxy Provider is available starting Authentik version 2024.12.0. In previous versions, pick Forward Auth (Domain Level).

Choose Proxy Provider
Choose Proxy Provider

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).

Pick Explicit Consent For Authorization Flow
Pick Explicit Consent For Authorization Flow

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.

Setup Forward Auth At Domain Level
Setup Forward Auth At Domain Level

No configuration is needed in the bind policy screen. Just hit next.

Leave Bind Policies As-Is
Leave Bind Policies As-Is

Verify the information and hit Submit to create the new application.

Submit Authentik Application
Submit Authentik 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.

Edit Authentik Embedded Outpost
Edit Authentik Embedded Outpost

Highlight the application and hit the right arrow icon to select the application, as shown below.

Enable The Created Application
Enable The Created Application

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.

Authentik Change Default Username
Change Default Authentik Username

Change the username to your preference and hit Update.

Don't Be a Jimmy!

Authentik - Not Allowed To Change Username
Authentik - Not Allowed To Change Username

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.

Authentik Totp Configuration
Authentik Totp Configuration

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.

Be the 1 in 200,000. Help us sustain what we do.
130 / 150 by Dec 31, 2024
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)

Anand

Anand is a self-learned computer enthusiast, hopeless tinkerer (if it ain't broke, fix it), a part-time blogger, and a Scientist during the day. He has been blogging since 2010 on Linux, Ubuntu, Home/Media/File Servers, Smart Home Automation, and related HOW-TOs.

Holiday Sale