Docudjeex
Advanced

Authentik

Install Authentik as a self-hosted identity provider, configure MFA and protect your services with SSO and reverse proxy authentication.
This is an advanced alternative to TinyAuth and Pocket ID: a single application handling both the forward-auth proxy and the OIDC provider roles, with built-in LDAP, SAML, and RBAC-style access policies (restricting who can reach which app, not just whether they're logged in) on top of its own admin UI for users, groups, and outposts. TinyAuth and Pocket ID stay lighter and simpler for a small homelab; Authentik is worth the extra setup once you need finer-grained access control or broader protocol support than OIDC alone.

Authentik is a single sign-on (SSO) tool that allows you to log in once to all platforms compatible with OpenID. It can also secure access to your exposed services by injecting itself via SWAG into requests to those services.

For example, if you're exposing Dockge online at dockge.mydomain.com, you’ll first land on an Authentik login page when accessing it. If you've already authenticated with another Authentik-protected service, you won’t need to log in again. This allows you to authenticate only once per day for all protected services.

Authentik also supports multi-factor authentication, including TOTP (a code generated by the authentication app of your choice). Additionally, it allows login through Microsoft or Google accounts, provided you've configured one of those applications.

It's a great alternative to VPNs for securely exposing services, especially ones that lack MFA or login protection (e.g., the SWAG dashboard).

Authentik has extensive documentation and great tutorials from Cooptonian. Here, we’ll cover the basics using Dockge as an example.

There are two main modes you should know:

  • The first allows apps with native support for OpenID-compatible SSO to connect directly to Authentik. This is the preferred method, as the app itself decides what’s public and what’s protected.

  • The second method injects Authentik authentication through SWAG before reaching the target service.

Both modes can be configured on a per-application basis.

Installation

  • /
    • srv
      • docker
        • authentik
          • .env
          • compose.yml
          • media
          • certs
          • custom-template
          • ssh

Create the folders

Terminal
sudo mkdir -p /srv/docker/authentik/media /srv/docker/authentik/certs /srv/docker/authentik/custom-template /srv/docker/authentik/ssh

Generate secrets

Navigate to the authentik folder via cd /srv/docker/authentik and generate a password and secret key to include in the .env file:

Terminal
sudo echo "PG_PASS=$(openssl rand 36 | base64)" >> .env
sudo echo "AUTHENTIK_SECRET_KEY=$(openssl rand 60 | base64)" >> .env
To generate the keys, we created the folders ahead of deployment using Dockge. Dockge will prevent you from creating a stack with the same name in these folders unless a compose.yml file exists. So, create an empty compose.yml so it appears as an inactive stack: bash [Terminal] sudo nano /srv/docker/authentik/compose.yml

Deploy the stack

Open Dockge and search for "authentik" in the inactive stacks. Name the stack authentik and paste the following configuration, replacing {AUTHENTIK_TAG:-2026.2} with the latest version of Authentik.

compose.yaml
---
services:

  postgresql:
    image: docker.io/library/postgres:16-alpine
    container_name: authentik-postgresql
    restart: unless-stopped
    healthcheck:
      test:
        - CMD-SHELL
        - pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 5s
    volumes:
      - database:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: ${PG_PASS:?database password required}
      POSTGRES_USER: ${PG_USER:-authentik}
      POSTGRES_DB: ${PG_DB:-authentik}
    env_file:
      - .env

  redis:
    image: docker.io/library/redis:alpine
    container_name: authentik-redis
    command: --save 60 1 --loglevel warning
    restart: unless-stopped
    healthcheck:
      test:
        - CMD-SHELL
        - redis-cli ping | grep PONG
      start_period: 20s
      interval: 30s
      retries: 5
      timeout: 3s
    volumes:
      - redis:/data
  
  server:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2}
    container_name: authentik-server
    restart: unless-stopped
    command: server
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    volumes:
      - ./media:/media
      - ./custom-templates:/templates
      - ./ssh:/authentik/.ssh
    env_file:
      - .env
    ports:
      - ${COMPOSE_PORT_HTTP:-9000}:9000
      - ${COMPOSE_PORT_HTTPS:-9443}:9443
    depends_on:
      - postgresql
      - redis

  worker:
    image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2026.2}
    container_name: authentik-worker
    restart: unless-stopped
    command: worker
    environment:
      AUTHENTIK_REDIS__HOST: redis
      AUTHENTIK_POSTGRESQL__HOST: postgresql
      AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik}
      AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik}
      AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS}
    # `user: root` and the docker socket volume are optional.
    # See more for the docker socket integration here:
    # https://goauthentik.io/docs/outposts/integrations/docker
    # Removing `user: root` also prevents the worker from fixing the permissions
    # on the mounted folders, so when removing this make sure the folders have the correct UID/GID
    # (1000:1000 by default)
    user: root
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./media:/media
      - ./certs:/certs
      - ./custom-templates:/templates
      - ./ssh:/authentik/.ssh
    env_file:
      - .env
    depends_on:
      - postgresql
      - redis

volumes:
  database:
    driver: local
  redis:
    driver: local

Begin the initial setup

In the .env file, the PG_PASS and AUTHENTIK_SECRET_KEY variables are already set. Deploy the stack.

You can then begin the initial setup by visiting:
http://yourserverip:9000/if/flow/initial-setup/

Warning: It’s recommended to create a new admin account and disable the default akadmin account.

Done !

Exposing Authentik

To use Authentik outside your local network, you must expose it.

📋 Prerequisites:

We assume you have already created a subdomain like auth.mydomain.com in your DNS zone, with a CNAME pointing to mydomain.com. Also, unless you're using Cloudflare Zero Trust, you must have already forwarded port 443 from your router to port 443 of your server in your NAT rules.

Verify authentik-server.conf

Open the authentik-server.conf file:

Tip for those who dislike terminals: You can use File Browser Quantum to navigate and edit files instead of using terminal commands.
Terminal
sudo nano /srv/docker/swag/config/nginx/authentik-server.conf

Verify that the following variables are set correctly:

authentik-server.conf
set $upstream_authentik authentik-server;
proxy_pass http://$upstream_authentik:9000;

If not, make the necessary changes, then save with Ctrl+O, Enter, and exit with Ctrl+X.

Create the subdomain.conf file

Create the auth.subdomain.conf file:

Terminal
sudo nano /srv/docker/swag/config/nginx/proxy-confs/auth.subdomain.conf

Paste the following configuration:

auth.subdomain.conf
## Version 2023/05/31
# Ensure your authentik container is named authentik-server
# Ensure your DNS has a CNAME for authentik

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name auth.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app authentik-server;
        set $upstream_port 9000;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }

    location ~ (/authentik)?/api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app authentik-server;
        set $upstream_port 9000;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}

Save with Ctrl+O, then Enter, and exit with Ctrl+X.

Add Authentik's network to SWAG

Go to Dockge, and edit the SWAG compose file to add the Authentik network:

compose.yaml
---
services:
  swag:
     container_name: # ...
      # ...
     networks:               # Attach the container to the custom network
      # ...           
      - authentik            # Name of the network declared in the stack

networks:                    # Define the custom network
  # ...
  authentik:                 # Name of the network declared in the stack
    name: authentik_default  # Actual name of the external network
    external: true           # Indicates it's an external network

Restart the stack and wait for SWAG to be fully operational.

Done !

You can now access Authentik via https://auth.mydomain.com

Enable Multifactor Authentication

The main value of Authentik is using multifactor authentication for all protected apps.

Log in to Authentik

Go to https://auth.mydomain.com and log in.

Register an MFA method

Go to Settings, click the MFA section, then Register. Choose a method like TOTP device (you'll need an authenticator app like Google Authenticator) and follow the steps.

Done !

You’ll now be prompted to enter a one-time code at every login.

Protecting a Native App

Authentik is natively compatible with several applications. You can find the list and support here.

Protecting an App via Reverse Proxy

SWAG lets you insert Authentik’s login page between a request and access to your service. To do this:

  • Configure the authentication provider in Authentik.
  • Edit the domain proxy file so SWAG can intercept the request.

Why do this when Dockge already has authentication? Because Dockge uses weak HTTP authentication. With Authentik, you get strong MFA authentication and automatic login to all apps protected by Authentik. This secures access to Dockge and other apps without needing a VPN.

Configuring Authentik

  • Go to Authentik
  • Open the admin panel
  • Select Applications then Create with wizard
  • Fill in the fields as shown:

  • At the next step, choose "Forward authentication (single application)" and configure it as shown (flows are important):

  • Next, go to the Outposts menu on the left and edit authentik Embedded Outpost:

  • Add the dockge application by moving it to the right column and save.

Configuring SWAG

Edit the file dockge.mydomain.com:

Terminal
sudo nano /srv/docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf

Uncomment the two lines #include /config/nginx/authentik-server.conf;

Press Ctrl+O, then Enter to save, and Ctrl+X to exit.

Tip: In Dockge's settings, you can disable Dockge's authentication to avoid double login. Warning: this means if the port is open on your local network, there will be no authentication at all.

Done !

Now when accessing https://dockge.mydomain.com, you’ll be redirected to the Authentik login screen.

Repeat this process for each app you want to protect (unless it has native integration with Authentik).

Your new architecture looks like this:

Protecting a Remote Server Service

For a native application (via OAuth 2.0 or other), nothing changes.

For a non-native app behind a reverse proxy, you must deploy an Outpost. An Outpost is a container acting as a local proxy. It's the target of your app's auth requests and the only one authorized to communicate with your Authentik API.

Prerequisites:
  • Install Docker on the remote server hosting the service.
  • If the app has no native integration, use a compatible reverse proxy. We will use SWAG here.

This container will forward requests to your main Authentik instance over the internet (or your local network). The server will perform checks and respond to the Outpost, which will allow or block access accordingly.

Configuring Authentik

Create your providers and applications as shown earlier.

Then, in the admin panel, go to Applications > Outposts, and create a new outpost.

Fill in as follows:

FieldValue
NameYour preferred name
TypeProxy
IntegrationLeave empty
ApplicationsSelect the applications you previously created

In the Advanced settings section, clear the existing content and enter:

log_level: info
docker_labels: null
authentik_host: https://your_authentik_server_domain/
object_naming_template: ak-outpost-%(name)s
authentik_host_insecure: false
container_image:
docker_network: null
docker_map_ports: true
docker_labels: null

Save with Ctrl+O, then Enter, and exit with Ctrl+X.

On the list of created outposts, locate the new one and click Show details at the end of the line. Carefully copy the access token.

We assume you’ve already installed Docker and SWAG on this remote machine. Here's how to configure it:

Create the stack folder

On your remote machine, use Dockge to create a stack named authentik-outpost.

If you haven’t installed Dockge, create a folder /srv/docker/authentik-outpost, or directly via command line:

Terminal
sudo mkdir -P /srv/docker/authentik-outpost
Tip for terminal-averse users: You can use File Browser Quantum to navigate and edit your files instead of using terminal commands.

Create the compose file

Create the compose.yaml file or paste the configuration directly into Dockge if installed.

Via command line:

Terminal
sudo nano /srv/docker/authentik-outpost/compose.yaml

Paste the following configuration, updating the version in {AUTHENTIK_TAG:proxy:2024.2.3} to match your Authentik server version.

compose.yaml
---
version: "3.5"
services:
  authentik_proxy:
    container_name: authentik-outpost
    image: ghcr.io/goauthentik/proxy:2024.2.3
    # Optionally specify which networks the container should be
    # might be needed to reach the core authentik server
    restart: unless-stopped
    env_file:
      - .env
    ports:
      - 9000:9000
      - 9443:9443
    environment:
      AUTHENTIK_HOST: ${HOST}
      AUTHENTIK_INSECURE: "false"
      AUTHENTIK_TOKEN: ${TOKEN}

Add the outpost network to SWAG

Go to the SWAG stack on the remote machine (or edit directly using Dockge) and add the authentik-outpost network in the configuration file like this (see networks section):

Terminal
sudo nano /srv/docker/swag/compose.yaml
compose.yaml
---
services:
  swag:
     container_name: #...
      # ... 
     networks:                      # Attach the container to the custom network

      - authentik-outpost           # Network name as declared in the stack

networks:                           # Define the custom network
  #...
  authentik-outpost:                # Name of the network declared in the stack
    name: authentik-outpost_default # Actual name of the external network
    external: true                  # Marks it as an external network

Press Ctrl+O, then Enter to save, and Ctrl+X to exit.

We assume the Dockge network name is authentik-outpost_default.

Restart SWAG

If using Dockge, restart SWAG.

Otherwise, via terminal:

Terminal
cd /srv/docker/swag/
sudo docker compose up -d

Set your environment variables

Create (or fill using Dockge) the .env file in the authentik-outpost directory:

Via command line:

Terminal
sudo nano /srv/docker/authentik-outpost/.env

Paste the following configuration:

.env
HOST=
TOKEN=

Fill in the values:

VariableValueExample
HOSTThe URL of your Authentik serverhttps://auth.domain.com
TOKENThe previously copied access tokenQ2pVEqsTNRkJSO9SkJzU3KZ2

Press Ctrl+O, then Enter to save, and Ctrl+X to exit.

Deploy the stack

If using Dockge, deploy the stack.

Otherwise, via terminal:

Terminal
cd /srv/docker/authentik-outpost/
sudo docker compose up -d

The container is now running. You can verify its status from your Authentik instance admin panel under Applications > Outposts.

Point SWAG at the outpost

Now, let’s configure SWAG.

Open the authentik-server.conf file:

Terminal
sudo nano /srv/docker/swag/config/nginx/authentik-server.conf

In the file, change authentik-server to authentik-outpost as shown:

authentik-server.conf
set $upstream_authentik authentik-outpost;
proxy_pass http://$upstream_authentik:9000;

Save with Ctrl+O, then Enter, and exit with Ctrl+X.

Done !

Then configure the applications to protect as you did on your main server, whether they are native or protected via reverse proxy.

Migrating an Authentik Database

The commands below assume the Postgres container is named authentik-postgresql, matching the Installation section above. Adjust it if you renamed yours.

Dump the database

On the source machine, dump the database:

Terminal
sudo docker exec authentik-postgresql pg_dump -U authentik -F t authentik > /path/to/mydb.tar

Transfer the dump

Transfer it to the target machine, then copy the file into the Docker container:

Terminal
cp /path/to/mydb.tar authentik-postgresql:/path/to/wherever

Purge existing tables

(Optional) Purge existing tables:

Terminal
sudo docker exec -i authentik-postgresql psql -U authentik -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = 'authentik' AND pid <> pg_backend_pid();" && sudo docker exec -i authentik-postgresql psql -U authentik -d postgres -c "DROP DATABASE IF EXISTS authentik;" && sudo docker exec -i authentik-postgresql psql -U authentik -d postgres -c "CREATE DATABASE authentik;"

Restore the database

Restore the database:

Terminal
sudo docker exec authentik-postgresql pg_restore -U authentik -d authentik /path/to/wherever/mydb.tar

Done !

Contributor:Djeex
Copyright © 2026