--- title: Beszel description: Install Beszel to monitor server CPU, RAM, disk, and network metrics, including remote servers, with a lightweight web dashboard. --- :ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60} # Beszel ::note 🎯 __Objectives:__ - Install Beszel - Monitor the local server - Monitor a remote server - Expose Beszel with Swag :: [Beszel](https://beszel.dev/) is a container that gives you real-time access to hardware information from your servers and allows historical tracking. CPU activity, disk usage, temperatures, RAM: nothing escapes your monitoring. Beszel also lets you configure notifications and alerts when your predefined thresholds are exceeded. Beszel includes a hub with a web UI and an agent that collects data from your server or a remote server. ![Beszel](/img/serveex/beszel.png) ## Installation Folder structure ```text [Directory tree] root └── docker └── beszel ├── data └── socket ``` Open Dockge, click `compose`, name the stack `beszel`, and paste the following: ```yaml [compose.yaml] --- services: beszel: image: henrygd/beszel:latest container_name: beszel restart: unless-stopped ports: - ${PORT}:8090 volumes: - ./data:/beszel_data - ./socket:/beszel_socket beszel-agent: image: henrygd/beszel-agent:latest container_name: beszel-agent restart: unless-stopped network_mode: host volumes: - ./socket:/beszel_socket - /var/run/docker.sock:/var/run/docker.sock:ro environment: LISTEN: /beszel_socket/beszel.sock # Do not remove quotes around the key KEY: ${KEY} ``` ::tip{icon=""} ✨ __Tip:__ Add the Watchtower label to each container to automate updates. ```yaml [compose.yaml] services: beszel: #... labels: - com.centurylinklabs.watchtower.enable=true ``` :: Fill out the `.env` file, for example: ```properties [.env] PORT=8090 # web UI port KEY= # private key to retrieve from Beszel when adding a system ``` For the `KEY` value, you'll need to launch Beszel once to get it. Deploy the container and go to `http://yourserverip:8090`. Your Beszel web UI is now accessible! ::caution __If it fails:__ check your firewall rules. :: ### Add local server information Now that the web UI is accessible, you need to push local server information into it. Just add a machine via the web UI and configure it like this: ![Beszel add system](/img/serveex/beszel-add.png) Note the private key and confirm. Enter the key in your `.env` file in Dockge and redeploy the stack. Once done, your server will appear in the web UI: ![Beszel system](/img/serveex/beszel-system.png) ### Add a remote server You can also monitor a remote server. To do so, run the agent on the remote server. Add a new machine in Beszel and fill in: - The name displayed for your remote server - The IP address or domain name of the remote server - The listening port (e.g., `45876`) Beszel will suggest a `compose.yaml` to deploy on the remote server, or you can use: ```yaml [compose.yaml] --- services: beszel-agent: image: henrygd/beszel-agent container_name: beszel-agent restart: unless-stopped network_mode: host volumes: - /var/run/docker.sock:/var/run/docker.sock:ro environment: LISTEN: ${PORT} KEY: ${KEY} ``` And in `.env`: ```properties [.env] PORT=45876 # communication port between hub and remote agent KEY= # private key from Beszel when adding the system ``` Deploy the stack on the remote server. Data will begin flowing into the web UI after a few seconds. ::caution __If it fails:__ check your firewall rules. :: ## Expose Beszel with Swag ::warning Beszel does not support multi-factor authentication. Exposing it on the internet could compromise connected machines. Only do this if you're using a system like [TinyAuth](/serveex/security/tinyauth) or [Authentik](/serveex/advanced/authentik/). Otherwise, do not expose with SWAG. Use a VPN like [Wireguard](/serveex/security/wireguard) instead. :: If you want to access Beszel remotely from all your devices, expose it using Swag. ::note 📋 __Prerequisite:__

You must have created a DNS subdomain like `beszel.mydomain.com` with a `CNAME` pointing to `mydomain.com`. Unless you're using Cloudflare Zero Trust, you must also have forwarded port `443` on your router to your server’s `443` port via [NAT rules](/general/networking/nat). :: In Dockge, edit Swag's compose file and add Beszel’s network: ```yaml [compose.yaml] services: swag: container_name: # ... # ... networks: # ... - beszel # network declared in the stack networks: # ... beszel: name: beszel_default # actual external network name external: true ``` Redeploy the stack and wait for Swag to become fully operational. ::note We assume the network name is `beszel_default`. You can check connectivity by visiting Swag's dashboard at `http://yourserverip:81`. :: In Swag’s config folders, create `beszel.subdomain.conf`. ::tip{icon=""} ✨ __Tip:__ Use [File Browser Quantum](/serveex/files/file-browser-quantum) to browse and edit files instead of terminal commands. :: ```bash [Terminal] sudo nano /docker/swag/config/nginx/proxy-confs/beszel.subdomain.conf ``` Paste: ```nginx [beszel.subdomain.conf] ## Version 2023/12/19 server { listen 443 ssl; listen [::]:443 ssl; server_name beszel.*; include /config/nginx/ssl.conf; client_max_body_size 0; #if ($lan-ip = yes) { set $geo-whitelist yes; } #if ($geo-whitelist = no) { return 404; } if ($geo-blacklist = no) { return 404; } # enable for ldap auth #include /config/nginx/ldap-server.conf; # enable for Authelia #include /config/nginx/authelia-server.conf; # enable for Authentik #include /config/nginx/authentik-server.conf; location / { #auth_basic "Restricted"; #auth_basic_user_file /config/nginx/.htpasswd; #include /config/nginx/ldap-location.conf; #include /config/nginx/authelia-location.conf; #include /config/nginx/authentik-location.conf; include /config/nginx/proxy.conf; include /config/nginx/resolver.conf; set $upstream_app beszel; set $upstream_port 8090; set $upstream_proto http; proxy_pass $upstream_proto://$upstream_app:$upstream_port; } } ``` Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit. That’s it! Beszel is now exposed! ## Protecting Beszel with TinyAuth Add [TinyAuth](/serveex/security/tinyauth)'s forward-auth check directly to `beszel.subdomain.conf`, the same way as [the TinyAuth guide](/serveex/security/tinyauth#protecting-an-app-via-reverse-proxy): ```nginx [beszel.subdomain.conf]{26-38,41-42} ## Version 2023/12/19 server { listen 443 ssl; listen [::]:443 ssl; server_name beszel.*; include /config/nginx/ssl.conf; client_max_body_size 0; #if ($lan-ip = yes) { set $geo-whitelist yes; } #if ($geo-whitelist = no) { return 404; } if ($geo-blacklist = no) { return 404; } # enable for ldap auth #include /config/nginx/ldap-server.conf; # enable for Authelia #include /config/nginx/authelia-server.conf; # enable for Authentik #include /config/nginx/authentik-server.conf; location /tinyauth { internal; proxy_pass http://tinyauth:3000/api/auth/nginx; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Uri $request_uri; } location @tinyauth_login { return 302 https://tinyauth.mydomain.com/login?redirect_uri=$scheme://$http_host$request_uri; } location / { auth_request /tinyauth; error_page 401 = @tinyauth_login; #auth_basic "Restricted"; #auth_basic_user_file /config/nginx/.htpasswd; #include /config/nginx/ldap-location.conf; #include /config/nginx/authelia-location.conf; #include /config/nginx/authentik-location.conf; include /config/nginx/proxy.conf; include /config/nginx/resolver.conf; set $upstream_app beszel; set $upstream_port 8090; set $upstream_proto http; proxy_pass $upstream_proto://$upstream_app:$upstream_port; } } ``` ::note The `location /tinyauth` block runs inside SWAG's own container, so SWAG needs to be on TinyAuth's Docker network to reach it by name (`tinyauth` here). This should already be set up from [exposing TinyAuth itself](/serveex/security/tinyauth#exposing-tinyauth-with-swag). If you run into an error, double-check SWAG's compose file still has that network attached. :: ::tip ✨ You can protect this app with Authentik instead of TinyAuth by opening `beszel.subdomain.conf` and removing the `#` in front of `include /config/nginx/authentik-server.conf;` and `include /config/nginx/authentik-location.conf;`. Don’t forget to [create an application and provider in Authentik](/serveex/advanced/authentik#protecting-an-app-via-reverse-proxy). ::