Deploy and Configure Authentik on Ubuntu with Docker Compose
Authentik is an open-source identity provider (IdP) that supports OAuth 2.0, OpenID Connect (OIDC), and SAML. By deploying Authentik on a Cloud Compute instance, you maintain full control over authentication, enable single sign-on (SSO) across your internal applications, and store user data securely within your own infrastructure.
This guide explains how to install Authentik using Docker Compose, secure it with HTTPS behind a reverse proxy such as Caddy or NGINX, harden your Ubuntu 24.04 server, and configure an OAuth 2.0 client to protect a sample web app. After completing all steps, you will have a production-ready, self-hosted authentication system.
Prerequisites
Before you begin, make sure you have the following requirements in place:
- Access to an Ubuntu 24.04 server as a non-root user with
sudoprivileges. - A DNS A record pointing to your server’s IP address (e.g., auth.example.com). Replace all mentions of this domain with your actual one.
- Docker and Docker Compose installed on your server.
Deploy Authentik Using Docker Compose
Create a dedicated project folder for Authentik inside your home directory.
$ mkdir ~/authentik && cd ~/authentik
Generate a Secret Key
Create a 64-character hexadecimal secret key for Authentik.
$ openssl rand -hex 32
Copy the generated key for use in the next step.
Create a .env File
Store your configuration secrets inside a .env file.
$ nano .env
Add the following content to define environment variables:
# Database configuration
PG_DB=authentik
PG_USER=authentik
PG_PASS=<POSTGRES_USER_PASSWORD>
# Authentik secret key
AUTHENTIK_SECRET_KEY=<64_CHAR_SECRET_KEY>
# Optional: pin a specific image tag
# AUTHENTIK_TAG=2025.8.4
# Local port bindings
COMPOSE_PORT_HTTP=127.0.0.1:9000
COMPOSE_PORT_HTTPS=127.0.0.1:9443
Replace <POSTGRES_USER_PASSWORD> and <64_CHAR_SECRET_KEY> with your own secure password and generated key. Save the file when finished.
Download the Docker Compose Manifest
Fetch the official docker-compose.yml file from Authentik’s documentation repository.
$ wget -O docker-compose.yml https://docs.goauthentik.io/docker-compose.yml
Start the Containers
Launch Authentik and its dependencies in detached mode.
$ sudo docker compose up -d
Verify Running Services
List all containers and confirm that every service is healthy.
$ sudo docker compose ps
Example Output:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS authentik-postgresql-1 docker.io/library/postgres:16-alpine "docker-entrypoint.s…" postgresql 25 min ago Up (healthy) 5432/tcp authentik-redis-1 docker.io/library/redis:alpine "docker-entrypoint.s…" redis 25 min ago Up (healthy) 6379/tcp authentik-server-1 ghcr.io/goauthentik/server:2025.8.4 "dumb-init -- ak ser…" server 25 min ago Up (healthy) 127.0.0.1:9000->9000/tcp, 127.0.0.1:9443->9443/tcp authentik-worker-1 ghcr.io/goauthentik/server:2025.8.4 "dumb-init -- ak wor…" worker 25 min ago Up (healthy)
Configure Caddy or NGINX with HTTPS
Ensure that your domain correctly resolves to the public IP address of your instance running Authentik. TLS certificate creation will fail if DNS is misconfigured or the necessary ports are blocked.
Check the Firewall Status
View the current status of your Uncomplicated Firewall (UFW).
$ sudo ufw status
If the firewall shows as inactive, enable it and allow SSH access:
$ sudo ufw enable && sudo ufw allow 22
Allow HTTP and HTTPS Ports
Open ports 80 (HTTP) and 443 (HTTPS) to enable web access and secure traffic.
$ sudo ufw allow 80
$ sudo ufw allow 443
View the Detailed Firewall Status
$ sudo ufw status verbose
Install the Caddy Web Server
Use the package manager to install Caddy, which will act as the reverse proxy for Authentik.
$ sudo apt update
$ sudo apt install -y caddy
Create and Configure the Caddyfile
Edit the Caddy configuration file to proxy incoming HTTPS traffic to the Authentik service.
$ sudo nano /etc/caddy/Caddyfile
Delete the default configuration and add the following:
auth.example.com {
reverse_proxy 127.0.0.1:9000
}
Save and close the file when finished.
Format and Validate the Configuration
Use Caddy’s built-in tools to format and validate the configuration file.
$ sudo caddy fmt --overwrite /etc/caddy/Caddyfile
$ sudo caddy validate --config /etc/caddy/Caddyfile
Reload the Caddy Service
Reload the Caddy web server to apply the changes.
$ sudo systemctl reload caddy
Caddy will automatically issue and renew TLS certificates when your DNS is properly configured and ports 80/443 are reachable.
Perform the Initial Authentik Setup
After deployment, open the setup page in your browser to create the first administrator account.
https://auth.example.com/if/flow/initial-setup/
Enter your email and a strong password to finalize the administrator configuration and access the Authentik dashboard.
Troubleshooting Caddy Startup
If Authentik does not load in your browser, review the Caddy logs for possible configuration errors.
$ sudo journalctl -u caddy --no-pager -n 100
Check for errors related to DNS resolution, SSL certificates, or misconfigured proxy routes.
Connect a Sample Application to Authentik
In this section, you will register an OAuth 2.0 client in Authentik and configure a lightweight Node.js app to test authentication via OAuth2.
Register an OAuth2 Client
Sign in to the Authentik Admin interface:
https://auth.example.com/if/admin/
Create an OAuth2/OpenID Provider for your test application by navigating through the following path:
Applications → Providers → Create → OAuth2/OpenID Provider
- Name: Sample App Provider
- Authorization Flow: default-provider-authorization-explicit-consent
Under the Protocol Settings section, configure:
- Client Type: Confidential
- Redirect URIs/Origins (RegEx): https://app.example.com/auth/callback
Generate and save the Client ID and Client Secret.
Then, under Advanced Flow Settings:
- Authentication Flow: default-authentication-flow
- Invalidation Flow: leave as default (optional)
Under Advanced Protocol Settings:
- Subject Mode: Based on the user’s hashed ID
Now create a corresponding application linked to this provider:
Applications → Applications → Create
- Name: Sample Web App
- Slug: sample-web-app
- Provider: Select Sample App Provider
- Policy Engine Mode: ANY
- Launch URL: https://auth.example.com
Sample Node.js OAuth2 Integration Application
Follow these steps to configure and verify a minimal web application that authenticates against Authentik using the Authorization Code flow.
Download the Example Project
$ git clone https://github.com/example/code-samples.git
$ cd code-samples/authentik-oauth2-demo-app
Install npm
$ sudo apt install -y npm
Install Project Dependencies
$ npm install
Generate a Session Secret
$ openssl rand -hex 32
Configure Environment Variables
$ nano .env
Insert the following configuration into the file:
AUTHENTIK_URL=https://auth.example.com
PUBLIC_BASE_URL=https://app.example.com
CLIENT_ID=<CLIENT_ID_FROM_AUTHENTIK_PROVIDER>
CLIENT_SECRET=<CLIENT_SECRET_FROM_AUTHENTIK_PROVIDER>
SESSION_SECRET=<RANDOM_SESSION_SECRET_GENERATED_ABOVE>
PORT=3000
Replace each placeholder with the appropriate values from your Authentik setup:
AUTHENTIK_URL→ URL of your Authentik instancePUBLIC_BASE_URL→ URL of your demo appCLIENT_IDandCLIENT_SECRET→ credentials from your Authentik providerSESSION_SECRET→ random key generated in the previous step
Start the Application
$ npm start &
Set up a reverse proxy and SSL for the sample app similar to your main Authentik configuration, but using port 3000.
Then open your browser and navigate to:
Click Login with Authentik, enter your credentials, and you’ll be redirected to the protected page after successful authentication.
Troubleshooting
If your app fails to connect or authenticate properly, follow these troubleshooting steps:
- Ensure that your Authentik Provider and Application settings are configured correctly, especially the Redirect URI (
https://app.example.com/auth/callback). - Inspect the Authentik logs to identify issues during login or token exchange:
$ sudo docker compose logs -f server
- Look for warnings or errors related to OAuth2 flows, redirect URIs, or authentication failures.
- Check that your reverse proxy (Caddy or NGINX) correctly forwards traffic to
127.0.0.1:9000and that HTTPS is configured properly. - If you encounter OAuth2 state mismatches, clear session cookies or test using a private browsing window.
Conclusion
You’ve successfully deployed a self-hosted Authentik identity provider using Docker Compose, secured it with HTTPS, and connected a Node.js application using OAuth2 SSO. With this foundation, you can expand to additional applications, enable email-based authentication flows, and scale your identity infrastructure—all while maintaining full control over your users’ data.


