Install Beszel for Lightweight Server Monitoring With Docker Compose
Run Beszel when you want quick visibility into server health without committing to a full Prometheus stack, then keep the first deployment honest about the difference between the hub and the agent.
How to run the Beszel hub locally, register the first monitored machine, and add the agent without mixing up the install paths.
Small operators who want CPU, memory, disk, and container visibility with less setup weight than a traditional metrics stack.
The most common early mistake is copying hub steps onto a remote node or pasting the wrong socket and key values into the agent config.
Before you begin
- A Docker host with Compose v2.
- A private admin path or reverse proxy plan for the Beszel hub UI.
- One monitored machine to start with. It can be the same machine as the hub for a first test.
- A decision to keep the first rollout simple instead of trying to cover every remote host on day one.
Beszel separates the monitoring UI and data store into the hub, then runs a small agent on each monitored machine. The current upstream docs still present those as separate installation paths. Treating them as different roles keeps the first setup much less confusing.
Step 1: Deploy the Beszel hub
Create the stack directory and save this as compose.yaml:
mkdir -p /opt/stacks/beszel
cd /opt/stacks/beszel
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
environment:
APP_URL: http://localhost:8090
ports:
- 127.0.0.1:8090:8090
volumes:
- ./beszel_data:/beszel_data
- ./beszel_socket:/beszel_socket
beszel-agent:
image: henrygd/beszel-agent:latest
container_name: beszel-agent
restart: unless-stopped
network_mode: host
volumes:
- ./beszel_agent_data:/var/lib/beszel-agent
- ./beszel_socket:/beszel_socket
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
LISTEN: /beszel_socket/beszel.sock
HUB_URL: http://localhost:8090
TOKEN: paste-a-token-from-settings-tokens
KEY: paste-the-public-key-from-add-system
Binding the hub to 127.0.0.1 keeps the dashboard private by default. The agent uses host networking because that is the current
upstream-recommended path for full host metrics, and the unix socket keeps the local agent-to-hub connection cleaner than trying to force
localhost across container boundaries.
Start the hub:
docker compose up -d
docker compose ps
docker compose logs --tail 50 beszel
Step 2: Complete first-login setup
Reach the hub through SSH port forwarding or your private reverse proxy, then finish the first-login flow in the browser. Beszel's current docs still guide you through creating the initial admin account from the web UI.
After login, open Settings > Tokens and create a token for the agent. Then use Add System in the hub UI to get the
public key for the monitored machine. Do not invent either value manually. Copy them from the UI so the registration key, token, and expected
socket path stay in sync with the current Beszel flow.
Step 3: Add the first Beszel agent
For a simple same-host test, keep the bundled local-agent layout above and paste the exact token and public key values into the existing
compose.yaml. Current Beszel docs recommend using the unix socket path when the hub and agent live on the same Docker host.
cd /opt/stacks/beszel
docker compose up -d
Back in the Beszel web UI, add the system and set Host / IP to /beszel_socket/beszel.sock. If you are monitoring a
different machine, switch to Beszel's current remote-agent instructions instead of forcing the local-socket pattern onto a separate host.
Bring up the agent and watch the logs:
docker compose ps
docker compose logs -f beszel-agent
Step 4: Verify metrics and alerts
Back in the Beszel hub UI, confirm the system shows up as online and reports at least these basics:
- CPU load and current utilization
- Memory usage
- Disk usage
- Container status for the local Docker host
Set one low-stakes test alert, such as a high disk threshold, so you prove notification behavior before you depend on it during a real incident.
Step 5: Update and operate the stack
Routine checks:
docker compose ps
docker compose logs --tail 50 beszel
docker compose logs --tail 50 beszel-agent
When updating, change one layer at a time:
cd /opt/stacks/beszel
docker compose pull beszel
docker compose up -d beszel
docker compose pull beszel-agent
docker compose up -d beszel-agent
Updating the hub and every agent in one blind wave is avoidable risk. Prove the hub still works, then move the agents.
Rollback notes
If an upgrade causes trouble, revert the image tag or restore the previous Compose file on the hub first. Because the hub stores the main data,
protect the beszel_data volume before major changes.
For agent problems, it is usually safe to recreate the agent container after fixing the key, socket, or volume mapping because the agent does not hold the dashboard state itself.
Troubleshooting
The hub UI loads, but no systems appear online.
Check that the agent is using the registration key copied from the hub and that you did not mix local-socket instructions with a remote-host install.
The agent starts, then disconnects quickly.
Review the exact socket path, volume mappings, and whether the agent can read the Docker socket on that machine.
You can reach Beszel publicly without protection.
Change the bind address back to localhost or place it behind an authenticated private admin path immediately.
You want deep historical analytics across many hosts.
Beszel is intentionally lighter than a full metrics stack. That is a feature, not a bug. Move up to heavier tooling only if the lightweight path stops serving the job.