On the authentik vs keycloak question for a homelab, pick authentik. Its official compose file starts three containers, it does forward auth for apps that have no login of their own, and it can serve LDAP and RADIUS to the NAS and the Wi-Fi. Pick Keycloak only if you need realms, enterprise federation, or you are learning it for work.
Both are full identity providers, which is already more than many homelabs need. If you only want a 2FA prompt in front of six apps, Authelia is lighter; the three-way breakdown is in Keycloak vs authentik vs Authelia. And if everything sits behind your tailnet and you are the only user, an identity provider buys you a login page and another database to back up. Still here? Then this is the right fight.
How they were compared
Everything below comes from each project’s own documentation: authentik 2026.8.3, the tag pinned in authentik’s official compose file, and Keycloak 26.8.0, the current release on the Keycloak downloads page. Nothing was benchmarked for this post. The memory rows are published requirements that measure different things: authentik asks for a host with at least 2 CPU cores and 2 GB of RAM, while Keycloak’s container guide recommends a 2 GB memory limit for the Keycloak container alone, database not included. Don’t read the table as a race.
| authentik | Keycloak | |
|---|---|---|
| Version referenced | 2026.8.3 | 26.8.0 |
| License | MIT core, enterprise directory under its own license | Apache 2.0 |
| Paid tier | Enterprise, priced per user | None from the project |
| Official container setup | Compose file: PostgreSQL, server, worker | docker run examples |
| Database | PostgreSQL | PostgreSQL, MySQL, MariaDB, SQL Server, Oracle |
| Redis | Removed in 2025.10 | Not used |
| Documented floor | Host with 2 CPU cores, 2 GB RAM | 2 GB container limit recommended |
| Protocols (free) | OIDC, SAML, LDAP, SCIM, RADIUS, Kerberos, Proxy | OpenID Connect, OAuth 2.0, SAML |
| Forward auth | Built in, via embedded outpost | External, e.g. oauth2-proxy |
| Serves LDAP to apps | Yes, read-only LDAP provider | No; consumes LDAP/AD via user federation |
| Isolation unit | No realm equivalent | Realms |
Where authentik wins
Forward auth ships in the box. The server container includes an embedded outpost that runs proxy providers “without deploying a separate outpost”. Forward auth keeps your reverse proxy in the data path and only asks authentik whether a request is allowed, with documented configs for nginx, Traefik, Caddy, Envoy and HAProxy. Domain-level mode puts one login in front of a whole parent domain but can’t apply per-app rules; single-application mode can. For a homelab full of dashboards that never shipped a login page, this feature alone decides it.
It speaks the protocols your boring devices speak. The free tier, per the authentik pricing page, “Supports OIDC, SAML, LDAP, SCIM, RADIUS, Kerberos, and Proxy.” The LDAP provider exposes authentik users and groups through an outpost as a read-only directory, which is how the NAS, an LDAP-only app and Linux hosts via SSSD end up on one password. Keycloak can read a directory. It won’t be one.
Fewer knobs. The official compose runs postgres:16-alpine plus server and worker, with a Postgres healthcheck and restart: unless-stopped already set. Server and worker read one AUTHENTIK_TAG variable, so they never drift apart.
The costs are real. Release 2025.10 removed Redis, which is nice, but also flipped the default email_verified claim from true to false, which surprises any app that rejects unverified addresses. Read release notes before every tag bump; this is not a Watchtower project. The official worker also runs as root with /var/run/docker.sock mounted so authentik can manage outpost containers, and those docs warn that socket access “can also result in possible root escalation on the host system.” Put docker-socket-proxy in front of it, or drop the mount and deploy outposts by hand.
Where Keycloak wins
Realms are a hard boundary. Family accounts, a lab realm you break on purpose and a side-project realm can share one server without seeing each other. authentik has nothing that maps cleanly. Realm and client decisions are the expensive ones to undo, so read Keycloak realms, clients and token design before you create the second realm.
Federation is the core product. The Keycloak project lists LDAP and Active Directory user federation, brokering to “existing OpenID Connect or SAML 2.0 Identity Providers,” and fine-grained authorization services. It is a CNCF incubation project, licensed Apache 2.0, with no paid edition holding features back. If you homelab to practise for work, realms, clients, mappers and brokering are the more portable skills.
Database choice. The database guide covers PostgreSQL, MySQL, MariaDB, SQL Server and Oracle. authentik wants PostgreSQL.
The costs: no forward auth, so apps without OIDC need oauth2-proxy and its keycloak-oidc provider, one more service to configure and patch. Production mode requires an explicit hostname, and most first-week failures are hostname and proxy errors rather than Keycloak bugs. The reverse proxy guide says to keep /admin/ and the master realm internal and never proxy management port 9000. The image strips curl, so healthchecks need the bash /dev/tcp trick from the health docs. And it is a JVM whose heap defaults to 70% of the container limit; Keycloak memory usage and heap sizing does the arithmetic.
A Keycloak compose file for one mini-PC
authentik hands you a compose file. Keycloak hands you docker run. This is the minimum shape for a single box (an N100 mini-PC is plenty) with a reverse proxy on the host terminating TLS. Put PG_PASS and KC_ADMIN_PASS in .env.
services:
postgres:
image: docker.io/library/postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: ${PG_PASS:?set PG_PASS in .env}
volumes:
- ./pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U keycloak -d keycloak"]
interval: 30s
retries: 5
start_period: 20s
keycloak:
image: quay.io/keycloak/keycloak:26.8.0
command: start
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
environment:
KC_DB: postgres
KC_DB_URL_HOST: postgres
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: ${PG_PASS}
KC_HOSTNAME: https://auth.example.com
KC_HTTP_ENABLED: "true"
KC_PROXY_HEADERS: xforwarded
KC_HEALTH_ENABLED: "true"
KC_BOOTSTRAP_ADMIN_USERNAME: admin
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_ADMIN_PASS:?set KC_ADMIN_PASS in .env}
ports:
- "127.0.0.1:8080:8080"
mem_limit: 2g
healthcheck:
test: ["CMD", "bash", "-c", "{ printf 'HEAD /health/ready HTTP/1.0\\r\\n\\r\\n' >&0; grep -q 'HTTP/1.0 200'; } 0<>/dev/tcp/localhost/9000"]
interval: 30s
retries: 5
start_period: 90s
Port 8080 binds to localhost so only the host’s proxy reaches it, and 9000 is never published. KC_HTTP_ENABLED is there because TLS ends at the proxy, and xforwarded assumes your proxy sends X-Forwarded-* headers. Pin the tag rather than latest, keep pgdata on the mini-PC’s SSD rather than a NAS share, and swap the bootstrap admin for a permanent one after first login.
Backups: the part that bites at month nine
For authentik, the backup guide says PostgreSQL “stores all persistent authentik data, including users, policies, flows, and configuration.” Dump it, and also copy /data, /certs, custom templates and custom blueprints. On restore, bring the database back before starting authentik.
For Keycloak, the database is the backup. The import/export guide recommends stopping all nodes before kc.sh export, notes that exports exclude “user and admin events, persisted sessions, workflow state or revoked tokens,” and says admin console exports “are not suitable for backups.” An occasional CLI export in git makes a readable diff of realm config; pg_dump does the real work.
A nightly script on the mini-PC writing to an NFS or SMB share on the NAS covers both. Call it from cron as a script, because a bare % in a crontab line is read as a newline:
#!/bin/sh
docker compose -f /opt/authentik/compose.yml exec -T postgresql \
pg_dump -U authentik -Fc authentik > /mnt/nas/backup/authentik-$(date +%F).dump
docker compose -f /opt/keycloak/compose.yml exec -T postgres \
pg_dump -U keycloak -Fc keycloak > /mnt/nas/backup/keycloak-$(date +%F).dump
The restore drill: once a quarter, pg_restore the latest dump into a throwaway compose project on another port, log in, and complete one OIDC login against a test client. A backup you have never restored is a theory.
Which one to pick
Pick authentik if you run a mix of OIDC-capable apps and apps with no auth at all, want the NAS and Linux boxes on one password via LDAP, and are the only admin. That describes most homelabs. Pin the tag, read the release notes, fence off the Docker socket.
Pick Keycloak if every app you care about already speaks OIDC or SAML, you want separate realms, you are practising for a job that runs it, or you want Apache 2.0 with no enterprise tier in sight. Budget a weekend for proxy config, and add oauth2-proxy for the stragglers.
Either way, only OIDC client registrations move cleanly between the two. Flows, mappers and policies don’t, so switching later means rebuilding the login experience. Choose once.
FAQ
is authentik easier to set up than keycloak
Yes, for most homelabs. authentik’s documented install is to download one compose file, generate a database password and secret key into .env, and run docker compose up, with initial setup on port 9000. Keycloak’s container guide documents docker run instead, and production mode requires an explicit hostname, so expect more proxy debugging.
does authentik still need redis
No. authentik 2025.10 moved caching, the embedded outpost session store and WebSocket traffic to PostgreSQL and removed Redis entirely, so current compose files run PostgreSQL, a server and a worker. The trade-off, per the release notes, is roughly 50% more database connections, which matters if several apps share one Postgres instance.
can keycloak do forward auth like authentik
Not by itself. Keycloak is an OpenID Connect, OAuth 2.0 and SAML server with no built-in forward-auth outpost, so the usual pattern is oauth2-proxy in front of the app using its keycloak-oidc provider, with allowed-role or allowed-group flags for authorization. It works, but it is one more service to configure, secure and update.
is authentik free for home use
Yes. The open source tier is free and covers OIDC, SAML, LDAP, SCIM, RADIUS, Kerberos and proxy providers, which is everything a homelab realistically uses. Enterprise costs $5 per internal user per month, billed annually, and adds Google Workspace and Microsoft Entra ID integration, mTLS client certificates and enhanced audit logging.
how much ram does keycloak need on a mini pc
Plan for a 2 GB container limit, which is Keycloak’s documented recommendation for smaller production deployments. The image sizes the JVM heap at 70% of the container limit, so always set one, or the heap can grow toward 70% of the host’s RAM. The documented floor for approximating the old 512 MB heap is 750 MB.
Related across the network
- How to Self Host Nextcloud on Raspberry Pi — selfhostrealm.com
- Best Self-Hosted Password Manager in 2026 — selfhostrealm.com