homelab-blueprint/docker-compose-files/beszel-hub/README.md
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

136 lines
3.8 KiB
Markdown

# Beszel Hub
Central web dashboard for Beszel server monitoring. Agents (see
[beszel-agent](../beszel-agent/README.md)) 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:
```bash
cp -n .env.sample .env
```
2. Adjust the values in `.env` if needed:
```dotenv
TZ=Africa/Johannesburg
BESZEL_HUB_PORT=8090
BESZEL_HUB_MEM_LIMIT=256m
DOCKERLOGGING_MAXFILE=3
DOCKERLOGGING_MAXSIZE=10m
```
3. Deploy with `make`:
```bash
make deploy-beszel-hub
```
Manual equivalent:
```bash
./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:
```bash
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:
```dotenv
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`):
```bash
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:
```bash
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
```bash
# 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
```