Self-hosted • Privacy-first • No tracking
Home / Homelab / Authentik 2026.8 Self-Hosted SSO: Complete Docker Compose Deployment Guide
Homelab #homelab#docker-compose#authentik#sso#oauth2 ⏱ 13 min • 👁 1 • Aug 30, 2026

Authentik 2026.8 Self-Hosted SSO: Complete Docker Compose Deployment Guide

Step-by-step production-ready Authentik 2026.8 deployment with Docker Compose, reverse proxy setup, backup strategies, and troubleshooting for common SSO pitfalls.

AdSense — Top (970x90) • Responsive
Authentik 2026.8 Self-Hosted SSO: Complete Docker Compose Deployment Guide

Introduction

Centralized authentication is the backbone of any serious homelab. As your self-hosted services grow from a single dashboard to a dozen interlinked applications, managing separate user databases and passwords becomes a security liability and an operational headache. Authentik solves this by acting as a single source of truth for identity, providing Single Sign-On (SSO), Multi-Factor Authentication (MFA), and fine-grained access control for all your applications.

Unlike heavier enterprise options like Keycloak, Authentik is designed with a focus on ease of deployment and a clean, modern web UI. It integrates seamlessly with reverse proxies like Nginx Proxy Manager, Traefik, or Caddy, and supports standard protocols including OAuth2/OIDC, SAML, and LDAP. This makes it a versatile drop-in replacement for the authentication layer of nearly any self-hosted tool, from Grafana and Gitea to Nextcloud and Proxmox.

This guide walks you through a production-grade deployment of the latest official release, Authentik 2026.8.0, using Docker Compose. We will cover everything from initial prerequisites and environment configuration to advanced topics like reverse proxy setup, automated backups, and security hardening. You will also find a comprehensive troubleshooting section to help you resolve common issues quickly and safely.

By the end of this guide, you will have a fully functional Authentik instance running behind your reverse proxy, ready to manage your users and secure your entire homelab ecosystem. All commands are copy-paste ready, and every configuration file is complete and unambiguous.

Prerequisites / Requirements

Before you begin, ensure your host system meets the following baseline requirements. These are typical values based on community reports; actual consumption depends heavily on the number of concurrent users, the frequency of authentication events, and whether you enable resource-intensive features like policy evaluation with external providers.

Component Minimum Requirement Recommended for Homelab Notes
CPU 1 vCPU 2 vCPU or more The control plane (Go) and worker (Python) processes benefit from multiple cores, especially during LDAP syncs or complex policy runs.
RAM 2 GB 4 GB or more PostgreSQL and Redis are the primary consumers. Expect 1-2 GB for the core stack, plus overhead for the OS and reverse proxy.
Storage 10 GB free 20 GB or more Used for Docker images, PostgreSQL data volume, and media files (custom logos, certificates). SSD is strongly recommended for database performance.
Software Docker Engine 24+ & Docker Compose v2 Latest stable You must have docker and docker compose (the v2 plugin) installed. Check with docker --version and docker compose version.
OS Linux (Debian/Ubuntu, Fedora, Arch) Linux macOS and Windows are possible but not covered here. Ensure your kernel supports overlay2 storage driver.
DNS A record pointing to your host e.g. auth.yourdomain.com You will need a domain name or a local DNS entry for HTTPS to work correctly with your reverse proxy.

Step-by-Step Installation Guide

Step 1: Create Project Directory and .env File

Create a dedicated directory for Authentik and navigate into it. This isolates the deployment and simplifies backups.

mkdir -p ~/authentik && cd ~/authentik

Now, create the .env file. This file holds all your secrets and configuration variables. Never commit this file to Git or share it publicly. It contains your database passwords and the secret key used to sign sessions.

touch .env

Open .env with your preferred editor and populate it with the following content. Replace the placeholder values with strong, unique passwords generated by a tool like openssl rand -hex 32.

# Authentik Domain
AUTHENTIK_HOST=auth.yourdomain.com

# PostgreSQL Database
POSTGRES_DB=authentik
POSTGRES_USER=authentik
POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-change_this_to_a_long_random_string}

# Redis (no password by default, but you can set one)
# REDIS_PASSWORD=change_this_too

# Authentik Secret Key (used for cryptographic signing)
AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY:-change_this_to_another_long_random_string}

# Authentik Bootstrap Token (for initial API access)
AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN:-change_this_to_a_third_long_random_string}

Generate the random strings using the command below and paste them into your .env.

openssl rand -hex 32 && openssl rand -hex 32 && openssl rand -hex 32

Step 2: Create the Docker Compose File

Create a file named docker-compose.yml in the same directory. This file defines the three core services: the server (control plane), the worker (background tasks), and the required databases (PostgreSQL and Redis).

version: "3.8"

services:
  postgresql:
    image: postgres:16-alpine
    restart: unless-stopped
    volumes:
      - pg_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    command: --appendonly yes
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

  server:
    image: ghcr.io/goauthentik/server:${AUTHENTIK_VERSION:-2026.8.0}
    restart: unless-stopped
    command: server
    environment:
      - AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
      - AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}
      - AUTHENTIK_HOST=${AUTHENTIK_HOST}
      - AUTHENTIK_REDIS__HOST=redis
      - AUTHENTIK_POSTGRESQL__HOST=postgresql
      - AUTHENTIK_POSTGRESQL__USER=${POSTGRES_USER}
      - AUTHENTIK_POSTGRESQL__NAME=${POSTGRES_DB}
      - AUTHENTIK_POSTGRESQL__PASSWORD=${POSTGRES_PASSWORD}
    ports:
      - "9000:9000"
      - "9443:9443"
    volumes:
      - media:/media
      - custom_templates:/templates
    depends_on:
      postgresql:
        condition: service_healthy
      redis:
        condition: service_healthy

  worker:
    image: ghcr.io/goauthentik/server:${AUTHENTIK_VERSION:-2026.8.0}
    restart: unless-stopped
    command: worker
    environment:
      - AUTHENTIK_SECRET_KEY=${AUTHENTIK_SECRET_KEY}
      - AUTHENTIK_BOOTSTRAP_TOKEN=${AUTHENTIK_BOOTSTRAP_TOKEN}
      - AUTHENTIK_HOST=${AUTHENTIK_HOST}
      - AUTHENTIK_REDIS__HOST=redis
      - AUTHENTIK_POSTGRESQL__HOST=postgresql
      - AUTHENTIK_POSTGRESQL__USER=${POSTGRES_USER}
      - AUTHENTIK_POSTGRESQL__NAME=${POSTGRES_DB}
      - AUTHENTIK_POSTGRESQL__PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - media:/media
      - custom_templates:/templates
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      postgresql:
        condition: service_healthy
      redis:
        condition: service_healthy

volumes:
  pg_data:
  redis_data:
  media:
  custom_templates:

Step 3: Launch the Stack

Pull the images and start the containers in detached mode. The first run will initialize the database and run migrations, which can take a few minutes.

docker compose up -d

Monitor the logs of the server service to ensure migrations complete successfully.

docker compose logs -f server

Wait until you see a log line indicating the server is running and listening on port 9000. This typically takes 2-5 minutes on a typical homelab hardware.

Step 4: Create the Initial Admin User

The bootstrap token from your .env file is used to create the first superuser. Run the following command inside the server container. Replace youremail@example.com with your actual email address.

docker compose exec server ak create_admin --email youremail@example.com --password 'YourStrongAdminPassword'

Alternatively, you can set the password via an environment variable to avoid exposing it in the shell history. The command above is sufficient for a local homelab. Write down these credentials; you will need them to log in for the first time.

Step 5: Access the Web UI

Authentik is now running. Access the web UI by navigating to http://your-server-ip:9000 (or https://your-server-ip:9443 for the self-signed TLS port). You will see the login page. Log in with the admin credentials you just created.

Step 6: Configure the Default Flow

Upon first login, Authentik will prompt you to complete the initial setup wizard. This wizard guides you through creating your first user group, an application, and an authentication flow. Follow the on-screen instructions. For a basic homelab setup, accept the defaults and create a simple authorization flow.

Step 7: Set Up Your Reverse Proxy (Nginx Proxy Manager Example)

While Authentik is accessible directly, you should put it behind a reverse proxy for proper SSL termination and to avoid exposing the raw port. Here's how to configure it with Nginx Proxy Manager (NPM).

First, ensure port 80 and 443 on your host are free or already handled by NPM. Then, in the NPM admin UI:

  1. Add a new Proxy Host.
  2. Domain Names: auth.yourdomain.com.
  3. Forward Hostname/IP: authentik-server (or the IP of your Docker host).
  4. Forward Port: 9000.
  5. Enable WebSockets Support. This is critical for the Authentik UI to function correctly.
  6. Under the SSL tab, request a new Let's Encrypt certificate and force SSL.

Step 8: Update the Authentik Host URL

After your reverse proxy is live, you must update the AUTHENTIK_HOST variable in your .env file to match your public domain (auth.yourdomain.com). Then, restart the stack.

cd ~/authentik && sed -i 's/AUTHENTIK_HOST=.*/AUTHENTIK_HOST=auth.yourdomain.com/' .env && docker compose up -d

Step 9: Verify the Installation

Navigate to https://auth.yourdomain.com. You should see the Authentik login page. Log in and navigate to the Admin Interface. Under System > Overview, you should see that all components (server, worker, PostgreSQL, Redis) are healthy and the version is 2026.8.0.

Step 10: Create Your First Application Integration

Now that the core is running, integrate your first application. In the Admin Interface, go to Applications > Applications and click Create. Choose a name and slug. Then, under Provider, create a new OAuth2/OIDC provider. Set the redirect URI to the callback URL of your target application (e.g., https://grafana.yourdomain.com/login/generic_oauth). Authentik will generate a Client ID and Secret for you to paste into your application's configuration.

Advanced Setup & Optimization

Reverse Proxy & SSL

The example above uses NPM. For Traefik, you can add labels to the server service in your docker-compose.yml to enable automatic HTTPS. For Caddy, use a Caddyfile to reverse proxy to server:9000. In all cases, ensure WebSocket support is enabled and that you pass the X-Forwarded-* headers correctly. Authentik respects these headers to generate correct URLs in redirects.

Backups

A proper backup strategy is non-negotiable. You must back up two things: the PostgreSQL database and the .env file. The media volume is for custom logos and certificates; it's nice to back up but not critical.

Create a script that dumps the database and copies the .env file to a safe location. Run it via a cron job.

#!/bin/bash
cd ~/authentik && docker compose exec -T postgresql pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} | gzip > /backup/authentik_db_$(date +%Y%m%d_%H%M%S).sql.gz && cp .env /backup/authentik_env_$(date +%Y%m%d_%H%M%S).env

Optional Hardening

Warning: The following settings are advanced and may break your deployment if applied without understanding your specific environment. Do not copy-paste these blindly. Test each change in a staging environment first.

You can add the following to your docker-compose.yml to improve container security. This restricts the container's filesystem and drops Linux capabilities that are not needed.

  server:
    # ... other settings
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    read_only: true
    tmpfs:
      - /tmp

Explanation: read_only: true makes the root filesystem read-only, preventing an attacker from writing to the container's filesystem. cap_drop: ALL removes all Linux capabilities, and cap_add: NET_BIND_SERVICE allows binding to port 80/443 if you ever run the server directly on those ports. The tmpfs mount provides a writable /tmp directory, which is required by many Python frameworks. This configuration is commonly reported to work, but you must verify that your specific deployment does not require writing to other paths (e.g., /media or /templates). If you use custom media uploads, you may need to adjust the volume mounts accordingly.

Troubleshooting Common Issues

Error / Symptom Likely Cause Solution
502 Bad Gateway from reverse proxy The server container is not running or is not healthy. Run docker compose ps to check status. Then docker compose logs server to see errors. Ensure PostgreSQL and Redis are healthy.
Web UI loads but CSS/JS is broken WebSockets are not enabled in your reverse proxy. Enable Websockets Support in NPM, or configure the appropriate headers in Traefik/Caddy.
Login fails with Invalid credentials User exists but password is wrong, or the flow is misconfigured. Check the worker logs for password validation errors. Resetting the password via docker compose exec server ak reset_password --username <user> is often faster.
Migration failed during startup Incompatible PostgreSQL version or corrupted data volume. Ensure you are using postgres:16-alpine as specified. If the error persists, restore from a backup. Do not run multiple migrations simultaneously.
ERR_TOO_MANY_REDIRECTS The AUTHENTIK_HOST variable does not match the URL you are accessing. Update the .env file with the correct public domain and restart the stack with docker compose up -d. Clear your browser cache.
Worker container keeps restarting The Docker socket mount is missing or permissions are wrong. Check the worker service logs. Ensure /var/run/docker.sock exists on the host and is passed correctly in the compose file.

Conclusion & FAQ

Deploying Authentik 2026.8.0 is a straightforward process that pays massive dividends in security and usability for your homelab. By centralizing authentication, you reduce the attack surface, enforce consistent MFA policies, and simplify user management across all your services. The Docker Compose setup provided here is complete and production-ready, and the troubleshooting section covers the most common pitfalls you will encounter.

Remember that security is an ongoing process. Regularly update your Authentik image by pulling the latest version and restarting the stack. Always keep a recent backup of your .env file and database. With this foundation, you can confidently expand your homelab, knowing that access control is handled by a robust, self-hosted solution.

FAQ

1. How do I update Authentik to a newer version?

To update, change the AUTHENTIK_VERSION variable in your .env file. For example, set it to 2026.8.1 when that release is published. Then run docker compose pull && docker compose up -d. Always check the official release notes for any breaking changes or manual migration steps before upgrading.

2. Can I use Authentik with LDAP-based applications?

Yes. Authentik has a built-in LDAP provider. You can create an LDAP source to connect to an existing directory, or use Authentik's LDAP outpost to expose its users to applications that only support LDAP. This is configured under Applications > Providers in the admin interface.

3. What is the difference between the server and worker containers?

The server container handles the web UI, API requests, and session management. The worker container processes background tasks like sending emails, running scheduled policies, and executing outpost updates. Both are required for a functional deployment.

4. How do I enable MFA for my users?

Navigate to Security > Flow Stages and edit the authentication flow. Add a Authenticator Validate Stage for TOTP (like Google Authenticator) or WebAuthn (like YubiKey). You can make MFA mandatory for all users or only for specific groups through policies.

5. My reverse proxy is on a different host than Authentik. What IP should I use?

Use the IP address of the Docker host where Authentik is running. If the reverse proxy is also a Docker container on the same host, you can use the container name server if they are on the same Docker network. Otherwise, use the host's LAN IP and ensure port 9000 is reachable from the proxy host.

AdSense — In-article (responsive)

Related Guides