Deployment guide

Beszel

Overview

Beszel is an open-source, lightweight server and container monitoring hub. Its clean web dashboard shows historical CPU, memory, disk, network and temperature metrics, configurable alerts and a multi-system overview. Lightweight agents report metrics back to the hub, including Docker container statistics, and the whole stack can be deployed entirely within your own VNet.

The Beszel hub is a single Go binary that serves both the REST API and the web UI. It is a PocketBase application with an embedded SQLite datastore. The SecureAnyCloud image runs the hub behind an nginx reverse proxy. The hub listens on 127.0.0.1:8090 and is reached through nginx on port 80 (and 443 once you add TLS). A Beszel agent is also preinstalled, so you can monitor the server itself out of the box once you add it in the dashboard.

On the first boot of every VM, a one-shot service recreates the datastore, which yields fresh per-instance signing keys, and creates a single administrator account with a per-VM password. The login is written to /root/beszel-credentials.txt with mode 0600. Beszel has no default administrator, and no shared credentials ship in the image.

What you get:

  • Beszel hub v0.18 (single Go binary at /usr/local/bin/beszel) behind an nginx reverse proxy on :80 (hub bound to loopback :8090)
  • A preinstalled Beszel agent (beszel-agent.service) so this host can monitor itself once you add it in the dashboard
  • A dedicated Azure data disk at /var/lib/beszel holding pb_data (the embedded SQLite metrics database, PocketBase config and per-instance signing keys), separate from the OS disk and re-provisioned with every VM
  • A per-VM administrator login generated at first boot, in a root-only file
  • beszel.service and nginx.service as systemd units, enabled and active
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size. Scale up when you monitor many systems.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network, and 80/tcp (plus 443/tcp once you enable TLS) from the networks your users reach the dashboard on.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure portal, choose Create a resource, search the Marketplace for Beszel by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).

Review the dedicated data disk on the Disks tab, then select Review + create and Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:beszel-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name beszel \
  --image sac1647283583153:beszel-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name beszel --port 80 --priority 1010

First-boot initialization takes under a minute after the VM reaches the Running state.

Step 3 - Connect and retrieve the administrator login

Connect over SSH as azureuser (or the administrator account you chose) with the VM's public IP:

ssh azureuser@<vm-public-ip>

The administrator email and password are generated uniquely on this VM during first boot and written to a root-only file. Retrieve them with:

sudo cat /root/beszel-credentials.txt

The file contains the hub URL, the administrator email (beszel.admin.user) and the per-VM password (beszel.admin.pass). Keep these somewhere safe.

Step 4 - Confirm the services are running

Beszel runs as two systemd services: the hub (beszel.service) and the nginx reverse proxy (nginx.service). A Beszel agent (beszel-agent.service) is also installed so that the host can monitor itself. Confirm that the hub and proxy are active:

systemctl is-active beszel.service nginx.service

Both report active. Next, confirm the hub binary version:

/usr/local/bin/beszel --version

The command prints beszel version 0.18.7. The hub exposes an open health endpoint through nginx. Check that it returns HTTP 200 with a healthy message:

curl -s http://localhost/api/health

The response is {"message":"API is healthy.","code":200,"data":{}}. Finally, confirm the listening sockets: nginx on port 80 and the hub bound to loopback on 8090.

sudo ss -tlnp | grep -E ':80|:8090'

Step 5 - Sign in to the web dashboard

Browse to http://<vm-public-ip>/. The Beszel sign-in page appears. Enter the administrator email and password from /root/beszel-credentials.txt and select Sign in.

After you sign in, the All Systems dashboard opens. It is empty until you add your first system.

Step 6 - Add the preinstalled local agent

A Beszel agent is already installed on this host as beszel-agent.service. To monitor the server itself, add it as a system in the dashboard. Beszel issues a unique public key and token for each system you add, so you do this step in the web UI rather than in the image.

In the dashboard, select Add System. In the dialog, choose the Binary tab, enter a Name (for example This Host), set Host / IP to localhost, and leave the Port as 45876. The dialog shows a Public Key and a Token for this system. Copy both.

On the VM, write the key and token into the agent's environment file. Edit /etc/beszel-agent.env as root and set the KEY and TOKEN values to the ones that the dialog showed you. The file already contains commented-out entries for both.

KEY=ssh-ed25519 AAAA...the public key from the dialog... TOKEN=...the token from the dialog... LISTEN=45876

Then restart the agent so that it picks up the key:

sudo systemctl restart beszel-agent

Back in the dialog, select Add System. Within a few seconds, the system appears in the dashboard and reports live CPU, memory, disk, network and load metrics. Select the system name to open its detail view with historical charts.

To monitor other servers, install the Beszel agent on each one. The Beszel project provides agent packages and a Docker image. Add a new system in the dashboard for each server, and pair it with the issued key and token in the same way.

Step 7 - Configure alerts and settings

Beszel can alert you when a system goes down or a metric crosses a threshold. Open a system's detail view to use its alert controls. You can also manage notification channels and display preferences from Settings.

The Settings area covers general display options, notification channels, tokens and fingerprints, alert history and a YAML configuration view.

Step 8 - Use the REST API

Because the hub is a PocketBase application, it exposes a REST API under /api/. The health endpoint is open, and most other endpoints require authentication. Authenticate as the administrator (a PocketBase superuser) to obtain a token. First read the login into shell variables, so that the password never appears in your shell history. Then request a token:

BZ_USER=$(sudo grep '^beszel.admin.user=' /root/beszel-credentials.txt | cut -d= -f2-)
BZ_PASS=$(sudo grep '^beszel.admin.pass=' /root/beszel-credentials.txt | cut -d= -f2-)
curl -s -H 'Content-Type: application/json' \
  -d "{\"identity\":\"$BZ_USER\",\"password\":\"$BZ_PASS\"}" \
  http://localhost/api/collections/_superusers/auth-with-password | head -c 80

A successful authentication returns a JSON document with a token field. Pass it as an Authorization header on subsequent API calls.

Enabling HTTPS

For production use, terminate TLS in front of Beszel. The simplest approach is to point a DNS name at the VM's public IP and use Let's Encrypt with Certbot. Install Certbot and the nginx plugin, then request a certificate for your domain. Replace your-domain.example.com with your DNS name:

sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com

Certbot edits the nginx configuration to serve Beszel over HTTPS on port 443 and sets up automatic renewal. Make sure that your NSG allows inbound 443/tcp from your users' networks.

Backup and maintenance

All Beszel state lives under /var/lib/beszel/pb_data. That includes the embedded SQLite metrics database, the PocketBase configuration and the per-instance signing keys. The directory is mounted on a dedicated Azure data disk, separate from the operating system disk. Confirm that the data disk is mounted:

df -h /var/lib/beszel | tail -1

To back up Beszel, snapshot the data disk in Azure, or stop the hub briefly and archive /var/lib/beszel/pb_data. To grow storage, expand the data disk and the filesystem. No reinstall is required, because the data lives on its own disk.

Read the service logs through journald:

sudo journalctl -u beszel.service --no-pager | tail -20

Keep the OS patched with sudo apt update && sudo apt upgrade. Restart the hub cleanly with sudo systemctl restart beszel.

Support

This image is backed by 24/7 SecureAnyCloud support covering deployment, upgrades, integrations, TLS termination and adding agents. Beszel is open source software distributed under the MIT license. This image repackages it for convenient deployment on Azure.

All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch Beszel on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure