How to Self-Host Beszel on a VPS (Complete Guide)
Beszel is a self-hosted server monitoring dashboard that gives you real-time visibility into CPU, RAM, disk, and network metrics across multiple servers. It is extremely lightweight (runs on 512 MB RAM), uses SQLite for storage, and can be deployed in minutes via Docker. This guide covers everything from choosing a VPS to monitoring your first remote server.
Prerequisites
Before starting, you need:
- A VPS โ 1 GB RAM, 1 vCPU, 10 GB storage minimum. Recommended providers:
- Hetzner Cloud โ 4.15 EUR/mo, 4 GB RAM, 40 GB NVMe (best value EU)
- Contabo VPS โ 5.99 EUR/mo, 8 GB RAM, 200 GB NVMe (best storage)
- DigitalOcean โ 6 USD/mo, 1 GB RAM (beginner-friendly)
- Ubuntu 22.04 or Debian 12 installed on the VPS.
- SSH access to the VPS.
- Docker (or download the Beszel binary directly).
- Port 8090 open in your firewall.
Step 1: Connect to Your VPS
ssh root@your-vps-ip
Update packages:
apt update && apt upgrade -y
Step 2: Install Docker
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
Verify Docker is running:
docker --version
Step 3: Open Firewall Port 8090
On Ubuntu with UFW:
ufw allow 8090/tcp
ufw reload
On Debian with iptables:
iptables -A INPUT -p tcp --dport 8090 -j ACCEPT
Step 4: Deploy the Beszel Hub
Option A: Docker Run (Quick Start)
docker run -d \
--name beszel \
--restart unless-stopped \
-p 8090:8090 \
-v beszel_data:/beszel_data \
henrygd/beszel
Option B: Docker Compose (Recommended)
Create a project directory:
mkdir -p /opt/beszel && cd /opt/beszel
Create docker-compose.yml:
services:
beszel:
image: henrygd/beszel:latest
container_name: beszel
restart: unless-stopped
ports:
- "8090:8090"
volumes:
- beszel_data:/beszel_data
volumes:
beszel_data:
Start the service:
docker compose up -d
Confirm it is running:
docker compose ps
docker compose logs -f
Option C: Binary Install (No Docker)
Download the latest release for your architecture:
curl -sL https://api.github.com/repos/henrygd/beszel/releases/latest \
| grep "browser_download_url.*linux_amd64" \
| cut -d '"' -f 4 \
| xargs curl -Lo /usr/local/bin/beszel
chmod +x /usr/local/bin/beszel
Create a systemd service at /etc/systemd/system/beszel.service:
[Unit]
Description=Beszel monitoring hub
After=network.target
[Service]
ExecStart=/usr/local/bin/beszel serve
WorkingDirectory=/var/lib/beszel
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Enable and start:
mkdir -p /var/lib/beszel
systemctl daemon-reload
systemctl enable --now beszel
Step 5: First Login
Open your browser and navigate to:
http://your-vps-ip:8090
You will be prompted to create an admin account on first launch. Set a strong password. This creates the initial user in the SQLite database.
Step 6: Add Servers to Monitor
Beszel uses a lightweight agent installed on each server you want to monitor.
6.1 Generate an Agent Key
In the Beszel dashboard:
- Click Add Server.
- Enter a name and the serverโs hostname or IP.
- Copy the generated Agent Key โ you will need this on the monitored server.
6.2 Install the Agent on the Target Server
SSH into the server you want to monitor, then run:
Docker:
docker run -d \
--name beszel-agent \
--restart unless-stopped \
--network host \
-e KEY="<paste-your-agent-key-here>" \
henrygd/beszel-agent
Binary:
curl -sL https://api.github.com/repos/henrygd/beszel/releases/latest \
| grep "browser_download_url.*beszel-agent.*linux_amd64" \
| cut -d '"' -f 4 \
| xargs curl -Lo /usr/local/bin/beszel-agent
chmod +x /usr/local/bin/beszel-agent
Create /etc/systemd/system/beszel-agent.service:
[Unit]
Description=Beszel monitoring agent
After=network.target
[Service]
ExecStart=/usr/local/bin/beszel-agent
Environment=KEY=<your-agent-key>
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Enable and start:
systemctl daemon-reload
systemctl enable --now beszel-agent
Within a few seconds the server should appear as Connected in the Beszel dashboard.
Step 7: (Optional) Put Beszel Behind a Reverse Proxy
For HTTPS access, configure Caddy or Nginx in front of Beszel.
Caddy example (/etc/caddy/Caddyfile):
monitor.yourdomain.com {
reverse_proxy localhost:8090
}
Nginx example (/etc/nginx/sites-available/beszel):
server {
listen 80;
server_name monitor.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name monitor.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/monitor.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monitor.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:8090;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Troubleshooting
| Problem | Fix |
|---|---|
| Dashboard unreachable | Check firewall (ufw status), confirm container is running (docker ps) |
| Agent not connecting | Verify the KEY env var is correct, check agent logs (docker logs beszel-agent) |
| High disk usage | Reduce metrics retention interval in Beszel settings |
| Container not starting | Check logs: docker compose logs beszel |
FAQs
How do I back up Beszel data?
The entire Beszel state is in the Docker volume beszel_data (or /var/lib/beszel for binary installs). Back up the SQLite database file with:
docker exec beszel sqlite3 /beszel_data/beszel.db ".backup /beszel_data/beszel.db.bak"
Then copy /beszel_data/beszel.db.bak off the server with rsync or scp.
Can I monitor Windows servers with Beszel?
The Beszel agent supports Linux, macOS, and Windows. Install the Windows binary and register it as a Windows service, then point your Beszel hub at it.
Does Beszel require an internet connection?
No. Beszel is fully self-contained. The hub and agents communicate only with each other, with no external calls required. It works entirely on a private network or VPN.