Vultr DocsLatest Content

How to deploy a Self-Hosted OAuth2 Provider on Vultr Using Authentik and Docker Compose

Updated on 29 October, 2025
Deploy Authentik on Vultr with Docker Compose to enable secure, self-hosted OAuth2 and SSO authentication across applications.
How to deploy a Self-Hosted OAuth2 Provider on Vultr Using Authentik and Docker Compose header image

Authentik is an open-source identity provider (IdP) that implements OAuth 2.0, OpenID Connect (OIDC), and SAML. Deploying Authentik on a Vultr Cloud Compute instance gives you full control over authentication, enables single sign-on (SSO) across internal tools, and keeps user data on your own infrastructure.

In this guide, you deploy Authentik with Docker Compose, secure it behind a reverse proxy (Caddy or NGINX) with HTTPS, harden the server, and register an OAuth 2.0 client to protect a sample web application. When you finish, you’ll have a production-ready, self-hosted authentication service running on Vultr.

Prerequisites

Before you begin,

Deploy Authentik Using Docker Compose

  1. Create a dedicated project directory for Authentik in your home directory.

    console
    $ mkdir ~/authentik && cd ~/authentik
    
  2. Generate a 64-character hexadecimal secret key for Authentik.

    console
    $ openssl rand -hex 32
    

    Copy the generated key for use in the next step.

  3. Create a .env file to store the secrets.

    console
    $ nano .env
    

    Add the following content in the .env file:

    ini
    # Database (mapped by the Compose file to AUTHENTIK_POSTGRESQL__*)
    PG_DB=authentik
    PG_USER=authentik
    PG_PASS=<POSTGRES_USER_PASSWORD>
    
    # Authentik secret key (required)
    AUTHENTIK_SECRET_KEY=<64_CHAR_SECRET_KEY>
    
    # Optional: Pin image tag (defaults provided in compose)
    # AUTHENTIK_TAG=2025.8.4
    
    # Use ip:hostport format to avoid exposing ports publicly
    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 the alphanumeric password and the secret key you generated earlier, respectively.

    Save and exit the file.

  4. Download the official docker-compose.yml manifest for Authentik.

    console
    $ wget -O docker-compose.yml https://docs.goauthentik.io/docker-compose.yml
    
  5. Start the stack in detached mode.

    console
    $ sudo docker compose up -d
    
  6. List the running services and verify that all services are healthy.

    console
    $ sudo docker compose ps
    

    Output:

    NAME                     IMAGE                                  COMMAND                  SERVICE      CREATED          STATUS                    PORTS
    authentik-postgresql-1   docker.io/library/postgres:16-alpine   "docker-entrypoint.s…"   postgresql   25 minutes ago   Up 25 minutes (healthy)   5432/tcp
    authentik-redis-1        docker.io/library/redis:alpine         "docker-entrypoint.s…"   redis        25 minutes ago   Up 25 minutes (healthy)   6379/tcp
    authentik-server-1       ghcr.io/goauthentik/server:2025.8.4    "dumb-init -- ak ser…"   server       25 minutes ago   Up 25 minutes (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 minutes ago   Up 25 minutes (healthy)   

Configure NGINX or Caddy with HTTPS

Ensure your domain resolves to the public IP of your Vultr instance that runs Authentik. TLS issuance will fail if DNS is wrong or ports are closed.

  1. View the ufw status.

    console
    $ sudo ufw status
    
    • If the status of ufw displays inactive then run the below command.

      console
      $ sudo ufw enable && sudo ufw allow 22
      
  2. Allow the required HTTP and HTTPS ports.

    console
    $ sudo ufw allow 80
    $ sudo ufw allow 443
    
  3. View the ufw status.

    console
    $ sudo ufw status verbose
    
Using Caddy Web Server
  1. Install the Caddy web server using apt.

    console
    $ sudo apt update
    $ sudo apt install -y caddy
    
  2. Create and configure the Caddyfile to reverse proxy to Authentik.

    console
    $ sudo nano /etc/caddy/Caddyfile
    

    Remove the existing content and add the following:

    ini
    auth.example.com {
        reverse_proxy 127.0.0.1:9000
    }
    

    Save and exit the file.

  3. Format the Caddyfile configuration file.

    console
    $ sudo caddy fmt --overwrite /etc/caddy/Caddyfile
    
  4. Validate the configuration and reload the Caddy service.

    console
    $ sudo caddy validate --config /etc/caddy/Caddyfile
    $ sudo systemctl reload caddy
    

    Caddy automatically issues and renews TLS certificates when DNS is correctly configured and ports 80/443 are accessible.

  5. Open the Initial Setup flow to create the first administrator account.

    https://auth.example.com/if/flow/initial-setup/

    On the setup page, enter your email and a strong password to complete the admin account setup.

    If the application is not reachable, check the Caddy web server logs.

    console
    $ sudo journalctl -u caddy --no-pager -n 100
    

Connect a Sample App to Authentik

In this section, you’ll register an OAuth 2.0 client in Authentik, then run a minimal Node.js app that uses it to validate authentication.

Register an OAuth2 Client

  1. Sign in to the Authentik Admin UI.

    https://auth.example.com/if/admin/
  2. Create an OAuth2/OpenID Provider for the sample application.

    • Navigate: Applications > Providers > Create > OAuth2/OpenID Provider
    • At the top, set:
      • Name: Sample App Provider
      • Authorization flow: default-provider-authorization-explicit-consent
    • Under Protocol settings:
      • Client type: Confidential
      • Redirect URIs/Origins (RegEx): https://app.example.com/auth/callback
      • Generate and save the Client ID and Client Secret
    • Under Advanced flow settings:
      • Authentication flow: default-authentication-flow
      • Invalidation flow: leave default (optional)
    • Under Advanced protocol settings:
      • Subject mode: Based on the User's hashed ID
  3. Create the application and link it to the provider you just created.

    • Navigate: Applications > Applications > Create
    • Name: Sample Web App
    • Slug: sample-web-app
    • Provider: select Sample App Provider
    • Policy engine mode: ANY
    • Under UI settings:
      • Launch URL: https://auth.example.com

Sample Node.js OAuth2 Integration Application

Follow the steps below to provision a minimal web application and validate the Authorization Code flow against Authentik.

  1. Clone the sample repository and enter the project directory.

    console
    $ git clone https://github.com/vultr-marketing/code-samples.git
    $ cd code-samples/authentik-oauth2-demo-app
    
  2. Install npm.

    console
    $ sudo apt install -y npm
    
  3. Install runtime dependencies.

    console
    $ npm install
    
  4. Generate a session secret.

    console
    $ openssl rand -hex 32
    
  5. Configure environment variables.

    console
    $ nano .env
    

    Paste the following and set the values precisely:

    ini
    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
    

    In the above file:

    • Replace https://auth.example.com with the URL of your Authentik instance.
    • Replace https://app.example.com with the URL where your sample app will run.
    • Replace <CLIENT_ID_FROM_AUTHENTIK_PROVIDER> and <CLIENT_SECRET_FROM_AUTHENTIK_PROVIDER> with the values generated when you created the OAuth2/OpenID Provider in Authentik.
    • Replace <RANDOM_SESSION_SECRET_GENERATED_ABOVE> with the session secret you generated in the previous step.

    Make sure all values are set correctly before starting the application.

  6. Start the application.

    console
    $ npm start &
    

    Ensure that you configure a reverse proxy and SSL for the app, similar to how you configured auth.example.com but for port 3000.

  7. Navigate to https://app.example.com and click Login with Authentik.

    Login with Authentik

  8. Enter your OAuth2 user credentials.

    image.png

  9. After authentication, the app exchanges the authorization code for tokens and redirects to /protected.

    Application After Login

Troubleshooting

If you encounter issues while connecting your sample app to Authentik, follow these steps:

  1. Check the OAuth2 Provider and Application settings,eEnsure that your Authentik Provider and Application are configured correctly, particularly the Redirect URI.

    https://app.example.com/auth/callback
  2. Authentik server logs can provide insight into errors during login or token exchange. Use the following command to view the logs in real-time.

    console
    $ sudo docker compose logs -f server
    

    Look for any warnings or errors related to OAuth2 flows, redirect URIs, or authentication failures.

  3. Confirm that your reverse proxy (Caddy or NGINX) forwards requests correctly to 127.0.0.1:9000 and that HTTPS is properly configured. Misconfigured proxy settings can prevent callback URLs from reaching Authentik.

  4. OAuth2 state mismatches may occur due to stale sessions. Try logging in using a private or incognito browser window to ensure a clean session.

Conclusion

You successfully deployed a self-hosted Authentik instance on Vultr with Docker Compose, secured it behind HTTPS, and verified OAuth2 SSO with a sample Node.js app. With this foundation, you can now onboard additional applications, enable email flows, and scale your authentication infrastructure while keeping full control over user data.

Comments