homelab-blueprint/docker-compose-files/beszel-hub
Brian Pooe d20500c5be feat(beszel-hub): support SSO-only login via OIDC with PKCE
Add DISABLE_PASSWORD_AUTH and USER_CREATION env toggles and document
the Zitadel PKCE provider setup.
2026-07-03 18:31:11 +02:00
..
.env.sample feat(beszel-hub): support SSO-only login via OIDC with PKCE 2026-07-03 18:31:11 +02:00
README.md feat(beszel-hub): support SSO-only login via OIDC with PKCE 2026-07-03 18:31:11 +02:00
template.yaml feat(beszel-hub): support SSO-only login via OIDC with PKCE 2026-07-03 18:31:11 +02:00

Beszel Hub

Central web dashboard for Beszel server monitoring. Agents (see beszel-agent) connect to this hub and report host and Docker container metrics.

Persistent Data

All hub state (PocketBase database, system records, alert config) is stored in the Docker-managed named volume beszel_hub_data.

Installation

  1. Create .env if it does not exist:

    cp -n .env.sample .env
    
  2. Adjust the values in .env if needed:

    TZ=Africa/Johannesburg
    BESZEL_HUB_PORT=8090
    BESZEL_HUB_MEM_LIMIT=256m
    
    DOCKERLOGGING_MAXFILE=3
    DOCKERLOGGING_MAXSIZE=10m
    
  3. Deploy with make:

    make deploy-beszel-hub
    

    Manual equivalent:

    ./substitute_env.sh docker-compose-files/beszel-hub/template.yaml docker-compose.beszel-hub.yml .env
    docker compose -f docker-compose.beszel-hub.yml config --quiet
    docker compose -f docker-compose.beszel-hub.yml up -d
    
  4. Open http://<host-ip>:8090 and create the admin account.

Connecting Agents

  1. In the hub, click Add System and enter the agent host's IP and port (default 45876).

  2. Copy the public key / token shown in the dialog into the agent's .env (BESZEL_AGENT_KEY, BESZEL_AGENT_TOKEN, and BESZEL_AGENT_HUB_URL=http://<hub-ip>:8090), then deploy the agent:

    make deploy-beszel
    

SSO via OIDC (Zitadel, PKCE)

Beszel authenticates through PocketBase, which supports any OIDC provider. The flow below uses Zitadel with PKCE (public client, no client secret).

Zitadel application setup

  1. In the Zitadel console, add an Application → type Web, Authentication Method: None (PKCE).
  2. Add the redirect URI: https://beszel.<domain>/api/oauth2-redirect
  3. Note the Client ID (no secret is needed with PKCE).

Hub configuration

  1. Set in .env and redeploy:

    BESZEL_HUB_DISABLE_PASSWORD_AUTH=true
    BESZEL_HUB_USER_CREATION=false
    
  2. Create a PocketBase superuser (used for the /_/ admin UI, unaffected by DISABLE_PASSWORD_AUTH):

    docker compose -f docker-compose.beszel-hub.yml exec beszel-hub \
      /beszel superuser upsert <email> <password>
    
  3. In https://beszel.<domain>/_/Collections → users → Edit (gear) → Options → OAuth2, enable OAuth2 and add an OpenID Connect provider:

    Field Value
    Client ID <zitadel-client-id>
    Client secret (leave empty — PKCE)
    Display name Zitadel
    Auth URL https://zitadel.<domain>/oauth/v2/authorize
    Token URL https://zitadel.<domain>/oauth/v2/token
    User info URL https://zitadel.<domain>/oidc/v1/userinfo

    PocketBase enables PKCE by default and requests the openid email profile scopes.

  4. With USER_CREATION=false, OAuth sign-in only matches existing hub users by verified email — create the admin user first (Collections → users → New record, role admin, verified). Set BESZEL_HUB_USER_CREATION=true instead to auto-create users on first login (anyone your Zitadel instance authorizes can then sign in).

Reverse Proxy

The Caddyfile proxies beszel.<domain> to this host on port 8090. After changing the port, update docker-compose-files/caddy/Caddyfile_template and run make reload-caddy.

Backup

Back up the beszel_hub_data named volume:

docker run --rm \
  -v beszel_hub_data:/data:ro \
  -v /opt/backups/beszel-hub:/backup \
  busybox tar czf /backup/beszel-hub-$(date +%Y%m%d).tar.gz -C /data .

Useful Commands

# Tail logs
docker compose -f docker-compose.beszel-hub.yml logs -f beszel-hub

# Recreate after an image update
docker compose -f docker-compose.beszel-hub.yml pull
docker compose -f docker-compose.beszel-hub.yml up -d