Introduction Link to heading
If you’re running multiple applications behind Traefik, you probably want a login screen. This guide shows how to set up Pocket ID (identity provider) and TinyAuth (forward auth proxy) for centralized authentication.
Why this approach:
- One login for all apps - Users log in once, access everything
- Works with any app - OIDC apps authenticate directly; others get protected by TinyAuth
- No code changes - All configuration via Docker labels
- Centralized user management - All users in Pocket ID
How It Works Link to heading
Pocket ID is your identity provider—a centralized login server where all your users are stored.
TinyAuth is a “forward auth” proxy that intercepts requests and checks for valid login sessions. If no session exists, it redirects to Pocket ID. This works with any app, even those without built-in auth.
OIDC-capable apps skip TinyAuth and authenticate directly with Pocket ID.
Setup Guide Link to heading
If the above approach sounds good, here’s how to implement it.
Prerequisites Link to heading
- Traefik already running and routing your applications - This is the foundation. Both Pocket ID and TinyAuth integrate with Traefik via labels and middleware.
- HTTPS/TLS configured in Traefik - Both Pocket ID and TinyAuth must be served over HTTPS. Ensure your Traefik instance has TLS certificates configured (via Let’s Encrypt, self-signed, or your cert provider).
- A domain name with subdomains (e.g.,
id.example.com,auth.example.com) - TinyAuth must run on the same Docker network as Traefik - TinyAuth acts as a Traefik middleware, so it needs to communicate with Traefik via your shared Docker network (whatever network your Traefik instance uses—e.g.,
traefik,proxy,backend, etc.). Both the compose files reference this as thetraefiknetwork, but you’ll replace it with your actual network name. - Pocket ID can run anywhere (same host or a different server—just needs to be accessible by domain)
Step 1: Deploy Pocket ID Link to heading
Pocket ID is your identity provider. It stores users and handles logins.
Create a new directory and set up the compose files. Start by creating the directory structure:
mkdir -p idp
Then create these files:
File: idp/docker-compose.yml
services:
pocket-id:
image: ghcr.io/pocket-id/pocket-id:v1
restart: unless-stopped
env_file: .env
volumes:
- "./data:/app/data"
labels:
- "traefik.enable=true"
- "traefik.http.routers.pocket-id.rule=Host(`id.example.com`)"
- "traefik.http.services.pocket-id.loadbalancer.server.port=1411"
networks:
traefik:
networks:
traefik:
external: true
File: idp/.env
# The external HTTPS URL where Pocket ID will be accessible
APP_URL=https://id.example.com
# Encryption key for Pocket ID's database
# Generate a key with: openssl rand -base64 32
ENCRYPTION_KEY=<YOUR_GENERATED_KEY>
# Trust X-Forwarded-* headers from Traefik
# This is required since Traefik is the reverse proxy
TRUST_PROXY=true
To generate the ENCRYPTION_KEY, run:
openssl rand -base64 32
Then paste the output into your .env file.
Step 2: Deploy TinyAuth Link to heading
TinyAuth is the authentication gateway. It checks if users are logged in and guards your apps.
Create a separate compose file for TinyAuth (you’ll add the .env file in Step 3). Start by creating the directory:
mkdir -p tinyauth
Alternatively, you can add this service directly to your existing reverse-proxy/compose.yaml file.
File: tinyauth/docker-compose.yml
services:
tinyauth:
image: ghcr.io/steveiliop56/tinyauth:v4
restart: unless-stopped
environment:
# TinyAuth's own URL
- APP_URL=https://auth.example.com
# Pocket ID OIDC client credentials
# (obtain these from Pocket ID admin panel)
- PROVIDERS_POCKETID_CLIENT_ID=${POCKETID_CLIENT_ID}
- PROVIDERS_POCKETID_CLIENT_SECRET=${POCKETID_CLIENT_SECRET}
# Pocket ID OIDC endpoints
- PROVIDERS_POCKETID_AUTH_URL=${POCKETID_URL}/authorize
- PROVIDERS_POCKETID_TOKEN_URL=${POCKETID_URL}/api/oidc/token
- PROVIDERS_POCKETID_USER_INFO_URL=${POCKETID_URL}/api/oidc/userinfo
- PROVIDERS_POCKETID_REDIRECT_URL=https://auth.example.com/api/oauth/callback/pocketid
# Scopes to request from Pocket ID
- PROVIDERS_POCKETID_SCOPES=openid email profile groups
# Human-readable provider name
- PROVIDERS_POCKETID_NAME=Pocket ID
# Auto-redirect to Pocket ID if no provider is specified
- OAUTH_AUTO_REDIRECT=pocketid
labels:
- "traefik.enable=true"
- "traefik.http.routers.tinyauth.rule=Host(`auth.example.com`)"
# Tell Traefik where to reach TinyAuth's auth endpoint
- "traefik.http.middlewares.tinyauth.forwardauth.address=http://tinyauth:3000/api/auth/traefik"
volumes:
- tinyauth:/data
networks:
traefik:
volumes:
tinyauth:
networks:
traefik:
external: true
Step 3: Configure Pocket ID and TinyAuth to Work Together Link to heading
There are five tasks here. The first three are required and sequential: initialize Pocket ID, create credentials for TinyAuth, then configure TinyAuth. Setting up groups is optional but useful for access control later. Finally, test the connection.
Initialize Pocket ID Link to heading
- Start Pocket ID by running
docker compose up -din theidp/directory - Wait 10-15 seconds for the container to start, then visit
https://id.example.com/setupin your browser - Create an admin account (this is your first user and admin for Pocket ID)
- Log in with the admin account
Create a Pocket ID OIDC Client for TinyAuth Link to heading
Once logged in:
- Go to Admin Panel → OIDC Clients (or OAuth Clients)
- Click Create New Client or Add Client
- Fill in the following:
- Client Name:
TinyAuth(or any name you prefer) - Redirect URI:
https://auth.example.com/api/oauth/callback/pocketid(this must match exactly) - Allowed Scopes: Select
openid,email,profile, andgroups
- Client Name:
- Click Save or Create
- Copy the Client ID and Client Secret (save these for the next step)
- Verify the client appears in your OIDC Clients list
Configure TinyAuth with Pocket ID Credentials Link to heading
Create a .env file in your tinyauth/ directory with these credentials:
POCKETID_URL=https://id.example.com
POCKETID_CLIENT_ID=<YOUR_CLIENT_ID>
POCKETID_CLIENT_SECRET=<YOUR_CLIENT_SECRET>
Now start TinyAuth by running docker compose up -d in the tinyauth/ directory.
(Optional) Set Up Groups in Pocket ID Link to heading
If you want to restrict access to apps by group membership, set up groups now. First add users to Pocket ID (in Admin Panel → Users), then:
- Go to Admin Panel → Groups (or Teams)
- Create groups like
staff,admin,developers, etc. - Add your users to the appropriate groups
You’ll reference these group names in TinyAuth access control labels later.
Test the Connection Link to heading
Visit https://auth.example.com in your browser. You should see a login screen with a “Login with Pocket ID” button. Try logging in with your admin account. If successful, you’ll see your username, email, and group memberships displayed—this confirms TinyAuth is correctly connected to Pocket ID.
Step 4: Protect Your Applications Link to heading
You have two options depending on whether your app supports OIDC:
Option A: Apps with OIDC Support Link to heading
Apps like Nextcloud, Gitea, or Bookstack can authenticate directly with Pocket ID. No TinyAuth needed. When a user accesses the app, they’re redirected to Pocket ID to log in, then redirected back to the app—all handled internally by the app.
- Register the app as an OIDC client in Pocket ID
- Configure the app with the Pocket ID OIDC settings
- Users log in directly through the app’s login form
(See your app’s documentation for OIDC setup instructions)
Option B: Apps Without OIDC Support Link to heading
For apps that don’t support OIDC (most simple apps), use TinyAuth by adding the middleware label to Docker:
services:
myapp:
image: example/myapp
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.myapp.rule=Host(`myapp.example.com`)"
- "traefik.http.routers.myapp.middlewares=tinyauth@docker" # ← Add this for non-OIDC apps
networks:
traefik:
external: true
Users will be required to log in before accessing myapp.example.com.
Access Control: Restricting Who Can Access an App Link to heading
By default, anyone who logs in to Pocket ID can access TinyAuth-protected apps. If you want to restrict access, choose one of the methods below:
Which method should you use?
- Group-based restriction (recommended): Use this if you set up groups in Step 3. It scales well as your homelab grows—just manage group membership in Pocket ID. This is the best approach for most setups.
- Email-based restriction: Use this only for quick, one-off access control (1-2 people per app). For anything beyond that, groups are easier to maintain.
Restrict by Pocket ID Group (recommended):
services:
admin-dashboard:
image: example/admin
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.admin.rule=Host(`admin.example.com`)"
- "traefik.http.routers.admin.middlewares=tinyauth@docker"
- "tinyauth.apps.admin.oauth.groups=staff" # Only staff group
networks:
traefik:
external: true
Restrict by Email Address:
In the admin-dashboard service’s labels: array, replace the tinyauth.apps.admin.oauth.groups=staff line with:
See the TinyAuth Access Controls documentation for more options (IP-based, path-based, etc.).
Apps with Built-in HTTP Basic Auth Link to heading
Some services (like Prometheus, Grafana, or Servarr apps) have built-in HTTP Basic Auth with no way to disable it. When protecting these with TinyAuth, automatically inject credentials so authenticated users don’t face a separate basic auth prompt:
services:
prometheus:
image: prom/prometheus
networks:
- traefik
labels:
- "traefik.enable=true"
- "traefik.http.routers.prometheus.rule=Host(`prometheus.example.com`)"
- "traefik.http.routers.prometheus.middlewares=tinyauth@docker"
# TinyAuth injects these credentials automatically
- "tinyauth.apps.prometheus.response.basicauth.username=promuser"
- "tinyauth.apps.prometheus.response.basicauth.password=prompass123"
networks:
traefik:
external: true
When a user logs in through TinyAuth and accesses the app, TinyAuth automatically injects the Basic Auth credentials. The app receives the request as if the user had already entered the username and password.
See the TinyAuth Docker Labels Reference for more options.
Troubleshooting Link to heading
Pocket ID Won’t Start Link to heading
Check the logs:
cd idp/
docker compose logs pocket-id
Common issues:
- Port 1411 already in use: Change the port in the Traefik label
loadbalancer.server.portto an available port - Data directory permission denied: Docker should auto-create
./data, but if you see permission errors, runmkdir data && chmod 755 data - Invalid
ENCRYPTION_KEY: Verify you generated it withopenssl rand -base64 32
TinyAuth Login Fails or Redirects in Circles Link to heading
This usually means TinyAuth can’t reach Pocket ID:
- Verify
POCKETID_URLintinyauth/.envis accessible from your browser (e.g.,https://id.example.com) - Check TinyAuth logs:
cd tinyauth/ docker compose logs tinyauth - Verify the Redirect URI in Pocket ID matches exactly:
https://auth.example.com/api/oauth/callback/pocketid - Double-check that
POCKETID_CLIENT_IDandPOCKETID_CLIENT_SECRETare correct intinyauth/.env
Group Restrictions Aren’t Working Link to heading
- Verify the
groupsscope is inPROVIDERS_POCKETID_SCOPESin TinyAuth’s compose file - Confirm users are actually assigned to the group in Pocket ID
- Check the label syntax:
tinyauth.apps.admin.oauth.groups=staff(notgroups.allowor other variants) - Restart TinyAuth after changing labels:
docker compose restartin thetinyauth/directory
Advanced Options Link to heading
Local User Accounts (Alternative to OIDC) Link to heading
Not everyone wants to set up a full OIDC provider. TinyAuth also supports local user accounts.
To create a local user, use the TinyAuth container:
# Create a local user
docker compose -f tinyauth/docker-compose.yml exec tinyauth tinyauth create-user
# Username: john
# Password: [enter password]
# Output: john:$2y$12$abcdef1234567890abcdef1234567890abcdef1234567890abcdef
Copy the entire output (username:hash) to your tinyauth/.env file:
USERS=john:$2y$12$abcdef1234567890abcdef1234567890abcdef1234567890abcdef,jane:$2y$12$1234567890abcdef1234567890abcdef1234567890abcdef123456
Then restart TinyAuth by running docker compose up -d in the tinyauth/ directory. You can mix local users and OIDC users in the same system.
Security Considerations Link to heading
Back Up Your Data Link to heading
Pocket ID stores all user accounts and configuration in the ./data directory. Back this up regularly:
# Run this in your idp/ directory
cp -r data data.backup.$(date +%Y-%m-%d)
TinyAuth also stores session data in its Docker volume (tinyauth:/data). While users can simply log in again if needed, you may want to back this up too. Set up automated backups to a separate server or cloud storage for both.
Protect Your .env Files
Link to heading
Your .env files contain sensitive secrets:
ENCRYPTION_KEY(Pocket ID)POCKETID_CLIENT_SECRET(TinyAuth)
Never commit these to version control. Add to .gitignore:
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
HTTPS Required Link to heading
Both Pocket ID and TinyAuth must be served over HTTPS. Your reverse proxy (Traefik) should handle this automatically if you’ve set up TLS certificates (via Let’s Encrypt or similar).
Limit User Access Link to heading
Use TinyAuth’s access control features (user allow-lists, group restrictions) to limit which users can access each application. See the “Restricting Who Can Access an App” section under Step 4 for examples.
Keep Containers Updated Link to heading
Periodically update your container images:
docker compose pull
docker compose up -d
Conclusion Link to heading
With Pocket ID and TinyAuth, adding authentication to your routes is simple:
- Deploy Pocket ID once (stores all your users)
- Deploy TinyAuth once (guards your apps)
- Add the TinyAuth middleware label to any app you want to protect
No code changes needed. No complex configuration. Just Docker labels.
For more details, see:
Pocket ID
TinyAuth