What you are setting up
Single sign-on means your team signs in once and every connected app trusts that sign-in. authentik is the piece in the middle, called an identity provider. Your wiki, Git server or dashboards send people to it, it checks who they are, and it tells the app. It speaks the common languages apps expect: OpenID Connect and OAuth2, SAML, and LDAP or RADIUS for older software.
How someone signs in is up to you. authentik calls each sign-in process a flow, built from small steps called stages: ask for a username, check the password, start the session. You can add or reorder steps later without touching the apps.
Under the hood the official Compose file runs three containers: a server that answers web requests, a worker that sends email and handles background jobs, and a PostgreSQL database that holds every user, group and setting.
How big a server does it need?
Less than you might fear. authentik's install guide asks for 2 GB of memory and at least two CPU cores, and says the Docker Compose method fits test setups and small production setups. It does not publish numbers per user, so treat anything beyond the minimum as headroom you choose.
- Memory is where we would spend first. The database keeps its busiest data in memory, and the Compose file gives the server container and the worker each a shared-memory area of up to 512 MB.
- Cores help when a lot of people sign in at the same moment, such as the start of a working day.
- Disk needs room for the database and for the dumps you keep, including the fresh one you take before every upgrade.
Even the smallest machines on our dedicated server page are above that minimum, and because a login service is something everything else depends on, it is worth giving it a server of its own rather than squeezing it next to the apps it protects.
Up and running, in the safe order
The trap with a new authentik install is that it listens on ports 9000 and 9443, and Docker opens published ports by itself, past the ufw firewall and on both IPv4 and IPv6. So close the doors first, then tell Docker to listen only on the server itself (127.0.0.1). Writing an address into the port variables is our own use of a setting the docs provide for changing ports.
- Install Docker with Compose v2, then allow SSH in ufw and switch ufw on.
- Make a folder for authentik and download the official compose.yml into it.
- Create an empty
.env, lock it withchmod 600so only root can read it, then add the database password and secret key the docs generate withopenssl. - Add the two port lines that pin authentik to 127.0.0.1.
- Pull the images and start everything, then check that nothing listens on a public address.
sudo ufw allow OpenSSH
sudo ufw enable
sudo mkdir -p /opt/authentik
cd /opt/authentik
sudo curl -O https://docs.goauthentik.io/compose.yml
sudo install -m 600 /dev/null .env
sudo sh -c 'echo "PG_PASS=$(openssl rand -base64 36 | tr -d "\n")" >> .env'
sudo sh -c 'echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60 | tr -d "\n")" >> .env'
sudo sh -c 'printf "COMPOSE_PORT_HTTP=127.0.0.1:9000\nCOMPOSE_PORT_HTTPS=127.0.0.1:9443\n" >> .env'
sudo chmod 600 .env
sudo docker compose pull
sudo docker compose up -d
sudo ss -tlnp | grep -E '9000|9443'
The docs warn against mounting /etc/timezone or /etc/localtime into the containers. authentik works in UTC inside and shows local times in the browser; a mounted timezone causes OAuth and SAML errors.
Set the admin password before anyone else can
A brand-new authentik has one account, akadmin, and no password on it. The first person who opens the initial setup page chooses that password, with no questions asked. Because your ports are on 127.0.0.1, only someone logged in to the server can reach it, so you do this step through an SSH tunnel with your own user.
- On your laptop, run
ssh -N -L 9001:127.0.0.1:9000 yourname@server-ipand leave it open. - In your browser, go to
http://localhost:9001/if/flow/initial-setup/. - Choose an email and a strong password for akadmin, sign in, and make yourself a named admin account.
- Only now point a domain name and a reverse proxy at the server.
Stuck on a blank setup page? authentik's troubleshooting guide suggests restarting the containers, and only if that fails, running ak changepassword akadmin inside the server container (through docker compose exec) to set it from the command line.
Giving it a proper address
Your team should reach authentik at something like sso.yourcompany.com over HTTPS, with nginx or Traefik passing visits on to port 9000 as a reverse proxy. Whatever proxy you pick, authentik's docs ask for four things:
- At least HTTP/1.1, since outposts keep a websocket open.
- The original
Host(orX-Forwarded-Host) passed through. X-Forwarded-ProtoandX-Forwarded-For, so authentik knows the visit was HTTPS and who made it.- The
UpgradeandConnectionheaders, so websockets can start.
A proxy on the same server connects from an address authentik already trusts by default, so you should not need to change its trusted-proxy list. Open ports 80 and 443 in ufw once the proxy is running. If the login page spins forever, the proxy is usually not telling authentik the visit came in over HTTPS.
Keeping everyone's accounts safe
If the database goes, every user, group, flow and setting goes with it, and the authentik backup guide says exactly that. Dump it nightly with PostgreSQL's own tools and keep a copy on another machine. Alongside it, save the data, certs and custom-templates folders and your .env, which holds both secrets, so store that archive with root-only permissions. Using your own blueprints? Save the /blueprints folder as well.
#!/bin/sh
# /etc/cron.daily/authentik-backup (chmod 700; -T because cron has no terminal)
cd /opt/authentik || exit 1
day=$(date +%F)
docker compose exec -T postgresql pg_dump -U authentik -d authentik -cC > /root/authentik-db-$day.sql
tar czf /root/authentik-files-$day.tgz data certs custom-templates .env
chmod 600 /root/authentik-db-$day.sql /root/authentik-files-$day.tgz
Upgrades are just as plain: fetch the newest compose.yml, then pull and start again. Take a fresh dump first, because authentik cannot be rolled back to an older version, and do not skip a major version: move to the latest minor release of each major version before going on to the next. If you run any outposts, update them at the same time so their version matches.
Why a whole server suits a login service
When the login service is down, nobody gets into anything, so you want it on hardware nobody else is using. With a Primcast dedicated server you get the whole machine and root access, an unmetered port, one IPv4 address and free IPv6. You can reinstall the operating system yourself from the control panel if a test goes wrong. A ready server is handed over within 30 minutes of payment approval, terms are month to month, and our chat replies within seconds with an AI assistant that can check your account and server; type that you want a human and someone from the team joins. You run authentik; we look after the hardware and network.
Comparing options? Our Keycloak guide covers the other well-known open-source login server, and once sign-in works, a self-hosted Gitea or Vaultwarden is a natural next app to connect.
If a single machine is too fragile for you
Everything here runs on a single machine, so if that machine stops, sign-in stops for every app. For a team that cannot accept that, authentik documents Kubernetes and high-availability setups. Also know that the worker can manage outposts because the Compose file hands it the Docker socket, which the docs call a security risk; you can put a socket proxy in between, or remove that line and deploy outposts yourself.
Questions people ask
- Which of my apps can sign in through authentik?
- Any app that supports OpenID Connect/OAuth2 or SAML can hand its logins to authentik. Older software that only knows LDAP or RADIUS can use an outpost, and apps with no login support at all can sit behind authentik's proxy provider.
- How much memory should I give authentik?
- The documented minimum is 2 GB with 2 CPU cores. The docs do not give a per-user figure, so go above the minimum if you can, mostly so the database has room to cache what it reads often.
- Why can't I just open port 9000 and log in?
- Because the first visitor to the initial setup page sets the admin password. If the port is public, that first visitor might not be you. Keep it on 127.0.0.1, finish setup over an SSH tunnel, then put a proxy in front.
- What should my backup include?
- A dump of the PostgreSQL database first, since it holds every user and setting. Then the data, certs and custom-templates folders and the .env file with your secrets, kept somewhere only you can read.
- Will changing the secret key lock people out?
- It signs people out. The configuration docs say changing AUTHENTIK_SECRET_KEY invalidates active sessions, so everyone signs in again. Keep the original in your backup and do not change it casually.