How to Set Up Authelia SSO for Your Homelab: A Beginner's Complete Guide
Step-by-step guide to setting up Authelia single sign-on with 2FA for your homelab. Protect Jellyfin, Nextcloud, and every self-hosted app with one login.
Author
David Okonkwo
*This article contains affiliate links. If you purchase through these links, we may earn a commission at no additional cost to you. We only recommend products we've tested and trust for homelab use.*
Key Takeaways
- Authelia is a free, self-hosted single sign-on (SSO) portal that adds authentication and two-factor protection to every app in your homelab
- You can protect Jellyfin, Nextcloud, Pi-hole, Grafana, and any other web app behind a single login page with one set of credentials
- The setup takes about 30 minutes with Docker Compose - no LDAP or Active Directory required
- Authelia supports TOTP (Google Authenticator), WebAuthn (hardware keys), and push notifications
- Pairing Authelia with a reverse proxy like Nginx Proxy Manager or Caddy gives you enterprise-grade security without enterprise complexity
Why Every Homelab Needs an Authentication Layer
Here's a scenario most homelabbers recognize: you've got five or six self-hosted services running - Jellyfin for media, Nextcloud for files, Pi-hole for DNS, Grafana for monitoring, Uptime Kuma for health checks. Each one has its own login page. Some you configured with weak passwords because "it's just my homelab." Some have no authentication at all because you assumed the local network was safe enough.
I was in this exact situation about two years ago. I had eight services running, each with a different login. I knew three of the passwords by heart. The other five? I'd click "forgot password" every time I needed to log in. That's not a security strategy - that's a disaster waiting to happen.
That's a problem. Not because someone is going to hack your Plex server tomorrow, but because:
- Your homelab is probably accessible from the internet - if you set up a Cloudflare Tunnel, VPN, or port forwarding, those services are one compromised credential away from exposure
- Default configs are insecure - many self-hosted apps ship with weak defaults or no authentication at all. Jellyfin, for example, lets anyone on your network access everything by default
- Password fatigue leads to bad habits - when you're managing 10 different logins, you start reusing passwords or skipping them entirely
- Family members complicate things - when your partner or kids need access to Jellyfin, do you really want to set up separate accounts on every single service?
- Guest access is messy - want to let a friend use your Plex? Now you're creating accounts on multiple systems, managing permissions across apps, and remembering to revoke access later
Authelia solves all of this by sitting in front of your apps (via your reverse proxy) and demanding authentication before anyone - including you - can access them. One login, one set of credentials, two-factor protection on everything.
Think of it as a bouncer at the door of your homelab. Every app is a room in a building, and Authelia is the security guard checking IDs before letting anyone in. Instead of putting a lock on every individual room (which you'd forget to do on some of them), you put one lock on the front door. When your friend wants to watch a movie on Jellyfin, they log in once through Authelia and they're set. When they leave, you disable their Authelia account and they're locked out of everything. Clean, simple, secure.
What You'll Need
Before we start, gather these things:
- A server running Docker and Docker Compose - any Linux machine works (Raspberry Pi 4+, old laptop, mini PC). If you're starting from scratch, a used Dell Optiplex or a Raspberry Pi 5 makes a great homelab foundation
- A reverse proxy already running - Nginx Proxy Manager, Caddy, Traefik, or Nginx. Authelia doesn't work standalone - it needs a reverse proxy to sit in front of. If you don't have one yet, check our Nginx Proxy Manager vs Caddy vs Traefik comparison to pick one
- A domain name pointed at your homelab - even a free DuckDNS or No-IP domain works for local use. Authelia needs a domain to set authentication cookies properly
- About 30 minutes - genuinely, that's all this takes if you follow along step by step
- A phone with an authenticator app - Google Authenticator, Authy, or Raivo (iOS) for the two-factor setup
I recommend having your reverse proxy already configured and working with at least one app before starting this guide. That way you can test Authelia on a service you know works, which makes troubleshooting much easier.
If you're brand new to Docker, our Docker for Homelabs guide covers everything you need to know before starting this tutorial.
Step 1 - Create the Authelia Directory Structure
First, let's set up a clean directory for all Authelia files. This keeps things organized and makes backups straightforward.
``bash
mkdir -p ~/authelia/{config,data,notifications}
# Navigate into itcd ~/authelia
`
Why a dedicated directory? Authelia stores configuration, user databases, and encryption keys in files. Keeping everything in one place means you can back up your entire auth system by copying a single folder. Trust me on this - you'll thank yourself later.
Step 2 - Generate Authelia Secrets
Authelia needs three secret values for security. We'll generate them using OpenSSL, which is already installed on most Linux systems.
`bash
# Generate the JWT secret (session encryption key)
openssl rand -hex 32
# Generate the session secret
openssl rand -hex 32
# Generate the storage encryption key
openssl rand -hex 32
`
Each command will output a long hex string like
a1b2c3d4e5f6.... Copy all three - you'll paste them into the configuration file in the next step. Do not skip this step. Authelia will refuse to start with default or weak secrets, and for good reason - these keys protect your entire authentication system.
Save these secrets somewhere safe - a password manager entry for "Authelia Secrets" works well. You'll need them again if you ever rebuild your Authelia container from scratch or move to a new server.
Step 3 - Create the Configuration File
This is the core of the setup. Create a file called
configuration.yml in your Authelia directory:
`bash
nano ~/authelia/config/configuration.yml
`
Paste this configuration, replacing the placeholder secrets with the ones you generated:
`yaml
# Authelia Configuration for Homelab
# Docs: https://docs.authelia.com/
# The server configuration
server:
address: 'tcp://0.0.0.0:9091'
# Logging
log:
level: info
# Theme (dark, light, or auto)
theme: dark
# The URL/Authelia domain - replace with your actual domain
domain: 'homelab.yourdomain.com'
# Default policy for protected resources
default_policy: two_factor
# Auth session configuration
jwt_secret: 'YOUR_JWT_SECRET_HERE'
# Storage configuration (SQLite for simplicity)
storage:
encryption_key: 'YOUR_STORAGE_ENCRYPTION_KEY_HERE'
local:
path: /config/data/db.sqlite3
# Access control rules
access_control:
# Default policy
default_policy: two_factor
# Rules for specific apps (optional - you can protect individual paths)
rules:
# Protect everything by default with two_factor
- domain: '*'
policy: two_factor
# Notification provider (for 2FA registration emails)
# Using filesystem for simplicity - no email server needed for setup
notifier:
filesystem:
filename: /config/notifications/notification.txt
# Identity validation (for password reset, 2FA registration)
identity_validation:
reset_password:
jwt_secret: 'YOUR_SESSION_SECRET_HERE'
# TOTP (Time-based One-Time Password) configuration
totp:
disable: false
issuer: 'homelab'
# WebAuthn configuration (hardware security keys)
webauthn:
disable: false
display_name: 'Homelab Auth'
attestation_conveyance_preference: indirect
# Password policy
password_policy:
zxcvbn:
enabled: true
min_score: 3
`
Let me explain the important parts:
domain - This must match the domain your reverse proxy uses. If your apps are at jellyfin.homelab.local, set this to homelab.local
default_policy: two_factor - This means every app requires both password AND a second factor (like Google Authenticator). You can relax this to one_factor for trusted networks later
storage.local.path - This is where Authelia stores its user database. Back up this file regularly
notifier.filesystem - We're using file-based notifications to avoid setting up an email server. Authelia writes registration links to a text file instead
Step 4 - Create the User Database
Authelia needs at least one user account. We'll use the Authelia CLI to create one.
First, add this temporary entry to your
configuration.yml for user management:
`yaml
# Add this temporarily for user creation
authentication_backend:
file:
path: /config/users_database.yml
password:
algorithm: argon2id
iterations: 3
memory: 65536
parallelism: 4
key_length: 32
salt_length: 16
`
Then create the
users_database.yml file:
`bash
nano ~/authelia/config/users_database.yml
`
Add your first user (replace with your actual details):
`yaml
users:
yourusername:
disabled: false
displayname: "Your Name"
password: ""
email: your@email.com
groups:
- admins
`
We'll generate the password hash in the next step. Don't put a plaintext password here - Authelia uses Argon2id hashing, which is one of the most secure password hashing algorithms available.
Step 5 - Generate the Password Hash
Authelia needs a hashed password, not a plaintext one. Use this Docker one-liner to generate it:
`bash
docker run --rm authelia/authelia:latest authelia crypto hash generate argon2 --password 'YourSecurePassword123!'
`
Replace
YourSecurePassword123! with your actual password. The command will output something like $argon2id$v=19$m=65536$t=3$p=4$salt$hash. Copy that entire string and paste it as the password value in your users_database.yml file.
Important: Choose a strong password. This is the master key to your entire homelab. Use a password manager to generate and store it. If you don't have a password manager yet, check our guide on self-hosted password managers - running your own is one of the best things you can do for security.
Step 6 - Create the Docker Compose File
Now let's tie it all together with Docker Compose. Create
docker-compose.yml in your Authelia directory:
`bash
nano ~/authelia/docker-compose.yml
`
`yaml
version: '3.8'
services:
authelia:
image: authelia/authelia:latest
container_name: authelia
restart: unless-stopped
ports:
- "9091:9091"
volumes:
- ./config:/config
- ./data:/data
- ./notifications:/config/notifications
environment:
TZ: UTC
networks:
- authelia-net
networks:
authelia-net:
driver: bridge
`
Why this network setup matters: Authelia needs to communicate with your reverse proxy. If your reverse proxy is already running, you'll need to connect both containers to the same Docker network. Check your existing reverse proxy's docker-compose.yml for its network name, and add authelia-net as an external network, or add Authelia to the same network.
For example, if your Nginx Proxy Manager uses a network called
nginx-proxy:
`yaml
networks:
authelia-net:
external: true
name: nginx-proxy
`
Start Authelia:
`bash
cd ~/authelia
docker compose up -d
docker compose logs -f
`
You should see Authelia start and listen on port 9091. Visit
http://your-server-ip:9091 in your browser. You should see the Authelia login page. Log in with the credentials you created.
Step 7 - Register Your First 2FA Device
After logging in for the first time, Authelia will prompt you to register a two-factor authentication method. Here's what to do:
- Install an authenticator app on your phone - Google Authenticator, Authy, or Raivo (iOS) all work
- Open the Authelia portal in your browser
- Click "Register" next to the TOTP option
- Scan the QR code with your authenticator app
- Enter the 6-digit code from your app to verify
That's it - your first app is now protected with two-factor authentication. For the TOTP secret, Authelia writes it to
/config/notifications/notification.txt since we're not using email. Check that file if you need the secret to manually add it to your authenticator app.
Step 8 - Connect Authelia to Your Reverse Proxy
This is where Authelia actually starts protecting your apps. The integration depends on which reverse proxy you're using.
Nginx Proxy Manager Integration
If you're using Nginx Proxy Manager (the most popular choice for homelabs), here's how to connect it:
- Get Authelia's container IP:
`bash
docker inspect authelia | grep IPAddress
`
- In Nginx Proxy Manager's web UI:
- Go to Advanced tab on your proxy host
- Add these Custom Nginx Configuration lines:
`nginx
# Authelia SSO Integration
location /authelia {
internal;
set $upstream_authelia http://AUTHelia_CONTAINER_IP:9091/api/verify;
proxy_pass $upstream_authelia;
# Timeout if the Authelia backend takes too long to respond
proxy_connect_timeout 5s;
proxy_read_timeout 5s;
proxy_send_timeout 5s;
}
# Auth request for the protected app
auth_request /authelia;
# Set variables from Authelia response
auth_request_set $target_url $scheme://$http_host$request_uri;
auth_request_set $user $upstream_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
auth_request_set $name $upstream_http_remote_name;
auth_request_set $email $upstream_http_remote_email;
# Redirect to Authelia login on failure
error_page 401 =302 https://authelia.yourdomain.com/?rd=$target_url;
# Pass user info to your backend app
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
proxy_set_header Remote-Name $name;
proxy_set_header Remote-Email $email;
`
Replace
AUTHelia_CONTAINER_IP with the actual IP from step 1.
Pro tip: Instead of using the container IP (which can change on restart), use Docker's internal DNS. If both Authelia and Nginx Proxy Manager are on the same Docker network, you can use http://authelia:9091 instead of the IP address. This is more reliable and survives container restarts.
Caddy Integration
If you're using Caddy, add this to your Caddyfile for each protected site:
`
jellyfin.yourdomain.com {
reverse_proxy http://jellyfin:8096 {
header_up Remote-User {http.auth响应.remote_user}
}
forward_auth https://authelia.yourdomain.com:9091 {
uri /api/verify?rd=https://authelia.yourdomain.com/
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
}
`
Traefik Integration
For Traefik users, add this middleware to your dynamic configuration:
`yaml
http:
middlewares:
authelia:
forwardAuth:
address: "http://authelia:9091/api/verify?rd=https://authelia.yourdomain.com/"
trustForwardHeader: true
authResponseHeaders:
- Remote-User
- Remote-Groups
- Remote-Name
- Remote-Email
`
Then apply the middleware to your services in your Docker labels or Traefik config.
Step 9 - Protect Your First App
Let's protect a real app. We'll use Jellyfin as an example, but the process is identical for any app.
- Make sure Jellyfin is already running and accessible through your reverse proxy
- Open Nginx Proxy Manager and edit Jellyfin's proxy host
- Go to the Advanced tab and add the Authelia nginx configuration from Step 8
- Save and test by opening Jellyfin in your browser
You should be redirected to the Authelia login page before you can access Jellyfin. Log in with your Authelia credentials, complete the 2FA check, and you'll be redirected back to Jellyfin.
Repeat this for every app you want to protect. The beauty of this setup is that once you've configured the Authelia middleware once, applying it to additional apps is just a few clicks in your reverse proxy.
Common Mistakes to Avoid
1. Forgetting to restart the reverse proxy after configuration changes
After adding Authelia integration to Nginx Proxy Manager, you need to apply the configuration. If it doesn't work, try restarting the Nginx Proxy Manager container entirely.
2. Wrong domain in the Authelia config
The
domain in your Authelia configuration.yml must exactly match what your reverse proxy uses. If your apps are at *.homelab.local, your Authelia domain must be homelab.local. A mismatch causes silent authentication failures.
3. Not backing up the users_database.yml and configuration.yml files
These files contain your entire authentication setup. If you lose them, you lose access to all your protected apps. Back up the entire
~/authelia directory regularly. Our homelab backup guide covers backup strategies that work well for this.
4. Using weak secrets
The JWT secret, session secret, and storage encryption key protect your authentication system. Generate them with
openssl rand -hex 32 and never reuse defaults.
5. Exposing Authelia's port 9091 directly
Your reverse proxy should handle external access. Authelia's port should only be accessible from within your Docker network, not from the internet. Remove the port mapping (
9091:9091) from your docker-compose.yml once you've confirmed it works, and let your reverse proxy route traffic to it.
Authelia vs Authentik - Which Should You Choose?
You'll often see Authentik recommended alongside Authelia. Both are excellent, but they solve slightly different problems. Here's the honest breakdown based on actually running both:
Choose Authelia if:
- You want something lightweight and fast (starts in under 2 seconds)
- You're comfortable with YAML configuration files
- You don't need an identity provider (IdP) for complex enterprise setups
- You want minimal resource usage (Authelia uses ~30MB RAM vs Authentik's ~200-300MB)
- You prefer simplicity over features
- You're the only admin of your homelab
- You want battle-tested, stable software with a smaller attack surface
Choose Authentik if:
- You want a web-based admin UI for managing users and groups
- You need complex authorization policies (application-specific rules, group-based access)
- You want a built-in LDAP directory without separate software
- You're running a larger setup with multiple administrators
- You want outposts that can run alongside your apps for distributed authentication
- You don't mind higher resource usage and more moving parts
- You need SAML support alongside OIDC
My recommendation: Start with Authelia. If you later find yourself needing more complex features, migrating to Authentik is straightforward because both support the same authentication protocols. There's no penalty for starting simple.
For a deeper look at protecting your homelab overall, check our Homelab Security Best Practices guide which covers Authelia in the context of a complete security strategy.
What to Learn Next
Once Authelia is running and protecting your apps, consider these next steps:
- Set up email notifications - Replace the filesystem notifier with SMTP or a notification service like Gotify so you get alerts for new device registrations and security events
- Add more 2FA methods - Register WebAuthn (hardware security keys like YubiKey) for even stronger protection. TOTP is great, but hardware keys are phishing-resistant
- Fine-tune access rules - You can create different policies for different apps. For example, one-factor authentication for your local dashboard but two-factor for anything accessible remotely
- Set up Authelia's password reset flow - Configure email-based password reset so family members can recover their own accounts without asking you to manually edit YAML files
- Protect your reverse proxy admin interface - Put Authelia in front of Nginx Proxy Manager's admin panel too. There's no reason to leave your admin interface exposed
- Configure session management - Authelia lets you set session expiration times, remember-me durations, and cookie security settings. Fine-tune these based on your security requirements
- Set up a second factor backup - Register a backup TOTP device (like a second phone or a printed backup code) so you don't get locked out if you lose your primary device
Our Homelab Networking Basics guide covers the networking concepts that make all of this work together.
Frequently Asked Questions
Can I use Authelia without a domain name?
Yes, but it's more complicated. Authelia works best with a domain because it needs to set cookies for authentication. For local-only setups without a domain, you can use
.local mDNS domains or self-signed certificates. However, you'll need HTTPS for secure cookie handling. Most homelabbers use a free DuckDNS domain, which works perfectly.
What happens if Authelia goes down - do I lose access to all my apps?
No. Authelia's forward auth design means that if Authelia is unreachable, the default behavior depends on your reverse proxy configuration. You can set it to fail open (allow access without auth) or fail closed (deny access). For homelabs, failing open is usually the right choice - you don't want to be locked out of your own services because one container crashed.
Does Authelia slow down my apps?
The performance impact is minimal. Authelia adds roughly 5-15ms of latency per request because your reverse proxy makes a quick internal check to Authelia before serving the page. On a homelab running on a Raspberry Pi 4 or better, this is completely unnoticeable. Even on a busy reverse proxy handling hundreds of requests per second, the overhead is negligible.
Can I use Authelia with Docker Swarm or Kubernetes?
Yes. Authelia works in any Docker environment. In Swarm or Kubernetes, you'll need to ensure the reverse proxy can reach Authelia's service endpoint. The Docker Compose setup in this guide translates directly to a Swarm stack file, and for Kubernetes, you'd deploy Authelia as a Deployment with a Service resource.
How do I add new users after the initial setup?
Edit the
users_database.yml` file to add new users, then restart the Authelia container. Each new user will need to register their 2FA device through the Authelia portal on their first login. For larger setups, consider switching to an LDAP backend so you can manage users through a directory service.
Is Authelia secure enough for internet-facing services?
Yes, when configured correctly. Authelia uses industry-standard algorithms: Argon2id for password hashing, AES-256-GCM for encryption, and standard TOTP/WebAuthn for 2FA. The biggest security risk isn't Authelia itself - it's weak passwords and outdated configurations. Keep Authelia updated, use strong secrets, and enable two-factor authentication for all users.
---
*David Okonkwo is a DevOps engineer and open-source advocate who writes about self-hosting, security, and privacy at HomelabAddiction.com. He's been running Authelia in his own homelab for over two years and has never looked back.*
