Beszel is a lightweight server monitoring hub that provides a simple web interface for monitoring multiple servers. It uses SSH to collect system metrics and displays them in an easy-to-read dashboard.
| File/Directory | Path | Purpose |
|---|---|---|
| Main config | /etc/beszel/config.yaml |
Main Beszel configuration |
| Database | /var/lib/beszel/beszel.db |
SQLite database |
| SSH keys | /var/lib/beszel/ssh/ |
SSH key storage |
| Logs | /var/log/beszel/ |
Beszel log files |
| Web assets | /usr/share/beszel/static/ |
Web interface assets |
| Systemd service | /etc/systemd/system/beszel.service |
Service definition |
| Environment | /etc/beszel/.env |
Environment variables |
# /etc/beszel/config.yaml
# ========================
# Server Settings
# ========================
server:
# Host and port for the web interface
host: 0.0.0.0
port: 8080
# Base URL (for reverse proxy)
base_url: ""
# Enable HTTPS
https:
enabled: false
cert_file: /etc/beszel/ssl/cert.pem
key_file: /etc/beszel/ssl/key.pem
# Session settings
session:
secret: your-session-secret-key-change-this
timeout: 86400 # 24 hours
cookie_secure: true
cookie_httponly: true
# ========================
# Database Settings
# ========================
database:
# Database type (sqlite, postgres, mysql)
type: sqlite
# SQLite configuration
sqlite:
path: /var/lib/beszel/beszel.db
# PostgreSQL configuration
postgres:
host: localhost
port: 5432
database: beszel
username: beszel
password: BeszelPassword123!
ssl_mode: disable
# MySQL configuration
mysql:
host: localhost
port: 3306
database: beszel
username: beszel
password: BeszelPassword123!
charset: utf8mb4
# Connection pool settings
pool:
max_open_conns: 25
max_idle_conns: 5
conn_max_lifetime: 300
# ========================
# Authentication
# ========================
auth:
# Enable authentication
enabled: true
# Authentication method (local, ldap, oauth)
method: local
# Local authentication settings
local:
# Allow user registration
allow_registration: false
# Password requirements
min_password_length: 8
require_uppercase: true
require_lowercase: true
require_digit: true
require_special: false
# Default user role
default_role: user
# LDAP authentication settings
ldap:
enabled: false
host: ldap.example.com
port: 389
use_tls: true
base_dn: dc=example,dc=com
bind_dn: cn=admin,dc=example,dc=com
bind_password: LdapPassword123!
user_filter: (uid={{username}})
user_attribute: uid
email_attribute: mail
admin_group: cn=beszel-admins,ou=groups,dc=example,dc=com
# OAuth settings
oauth:
enabled: false
provider: github # github, gitlab, google
client_id: your-oauth-client-id
client_secret: your-oauth-client-secret
redirect_url: https://beszel.example.com/auth/callback
scopes:
- read:user
- user:email
# ========================
# SSH Configuration
# ========================
ssh:
# Default SSH settings
default_port: 22
default_user: root
default_key_type: ed25519
# SSH key settings
keys:
# Path to store SSH keys
storage_path: /var/lib/beszel/ssh
# Key passphrase (optional)
passphrase: ""
# Key bits (for RSA)
rsa_bits: 4096
# Connection settings
connection:
timeout: 30
keepalive_interval: 60
keepalive_count_max: 3
# Retry settings
max_retries: 3
retry_delay: 5
# Security settings
security:
# Disable strict host key checking (not recommended)
disable_strict_host_key: false
# Known hosts file
known_hosts_file: /var/lib/beszel/ssh/known_hosts
# ========================
# Monitoring Settings
# ========================
monitoring:
# Collection interval (seconds)
collection_interval: 60
# Data retention
retention:
# High-resolution data (1-minute intervals)
high_res_days: 7
# Medium-resolution data (5-minute intervals)
medium_res_days: 30
# Low-resolution data (1-hour intervals)
low_res_days: 365
# Metrics to collect
metrics:
cpu: true
memory: true
disk: true
network: true
load: true
processes: true
users: true
uptime: true
temperature: false # Requires sensors
# Thresholds
thresholds:
cpu:
warning: 70
critical: 90
memory:
warning: 75
critical: 90
disk:
warning: 80
critical: 90
load:
warning: 2.0
critical: 5.0
# ========================
# Alert Configuration
# ========================
alerts:
# Enable alerts
enabled: true
# Alert check interval (seconds)
check_interval: 60
# Notification methods
notifications:
# Email notifications
email:
enabled: false
smtp_host: smtp.example.com
smtp_port: 587
smtp_user: beszel@example.com
smtp_password: EmailPassword123!
use_tls: true
from_address: beszel@example.com
recipients:
- admin@example.com
# Slack notifications
slack:
enabled: false
webhook_url: https://hooks.slack.com/services/XXX/YYY/ZZZ
channel: "#alerts"
username: Beszel
icon_emoji: ":warning:"
# Discord notifications
discord:
enabled: false
webhook_url: https://discord.com/api/webhooks/XXX/YYY
username: Beszel
# Webhook notifications
webhook:
enabled: false
url: https://api.example.com/alerts
method: POST
headers:
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
payload_template: |
{
"server": "{{server_name}}",
"metric": "{{metric_name}}",
"value": "{{metric_value}}",
"threshold": "{{threshold}}",
"status": "{{status}}",
"timestamp": "{{timestamp}}"
}
# Alert rules
rules:
- name: High CPU Usage
metric: cpu
condition: ">"
threshold: 90
duration: 300 # 5 minutes
severity: critical
notifications: [email, slack]
- name: High Memory Usage
metric: memory
condition: ">"
threshold: 85
duration: 300
severity: warning
notifications: [email]
- name: Disk Space Low
metric: disk
condition: ">"
threshold: 85
duration: 600
severity: warning
notifications: [email, slack]
- name: Server Down
metric: connectivity
condition: "=="
threshold: 0
duration: 60
severity: critical
notifications: [email, slack, discord]
# ========================
# Server Definitions
# ========================
servers:
# Example server configuration
- name: web-server-01
host: 192.168.1.10
port: 22
user: beszel
auth_type: key # password or key
key_file: /var/lib/beszel/ssh/beszel_key
# password: ServerPassword123! # Not recommended, use keys
groups:
- webservers
- production
tags:
- nginx
- php
metrics_overrides:
collection_interval: 30
enabled: true
- name: db-server-01
host: 192.168.1.20
port: 22
user: beszel
auth_type: key
key_file: /var/lib/beszel/ssh/beszel_key
groups:
- databases
- production
tags:
- mysql
- primary
enabled: true
- name: dev-server
host: 192.168.1.100
port: 22
user: beszel
auth_type: password
password: DevServerPassword123!
groups:
- development
tags:
- testing
enabled: true
# ========================
# Logging
# ========================
logging:
# Log level (debug, info, warn, error)
level: info
# Log format (json, text)
format: text
# Log output
output:
- file
- stdout
# File logging
file:
path: /var/log/beszel/beszel.log
max_size: 100 # MB
max_backups: 5
max_age: 30 # days
compress: true
# Syslog
syslog:
enabled: false
network: udp
address: localhost:514
facility: local0
# ========================
# Performance Settings
# ========================
performance:
# Worker threads
workers: 4
# Collection concurrency
collection_concurrency: 10
# Cache settings
cache:
enabled: true
type: memory # memory, redis
ttl: 60
# Redis cache (if type is redis)
redis:
host: localhost
port: 6379
password: ""
db: 0
# ========================
# API Settings
# ========================
api:
# Enable API
enabled: true
# API key authentication
api_keys:
- name: monitoring-system
key: your-api-key-here
permissions:
- read:servers
- read:metrics
- read:alerts
- name: automation
key: another-api-key-here
permissions:
- read:servers
- read:metrics
- write:servers
- write:alerts
# Rate limiting
rate_limit:
enabled: true
requests_per_minute: 100
burst: 20
# ========================
# UI Settings
# ========================
ui:
# Dashboard refresh interval (seconds)
refresh_interval: 30
# Default time range
default_time_range: 1h # 1h, 6h, 24h, 7d, 30d
# Theme
theme: auto # light, dark, auto
# Language
language: en
# Display settings
display:
show_server_groups: true
show_tags: true
show_alerts: true
graphs_type: line # line, area, bar
# Dashboard layout
dashboard:
columns: 3
show_cpu: true
show_memory: true
show_disk: true
show_network: true
show_load: true
# Server groups for organization
groups:
- name: production
description: Production servers
alert_notifications: [email, slack]
collection_interval: 60
- name: development
description: Development servers
alert_notifications: [email]
collection_interval: 300
- name: databases
description: Database servers
alert_notifications: [email, slack, pagerduty]
collection_interval: 30
- name: webservers
description: Web servers
alert_notifications: [email, slack]
collection_interval: 60
# Custom metrics collection
custom_metrics:
- name: nginx_connections
command: "curl -s http://localhost/nginx_status | grep 'Active connections' | awk '{print $3}'"
type: gauge
unit: connections
collection_interval: 30
- name: mysql_connections
command: "mysql -e \"SHOW STATUS LIKE 'Threads_connected'\" | awk 'NR==2 {print $2}'"
type: gauge
unit: connections
collection_interval: 60
- name: docker_containers
command: "docker ps -q | wc -l"
type: gauge
unit: containers
collection_interval: 60
- name: ssl_expiry
command: "echo | openssl s_client -connect localhost:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2"
type: gauge
unit: timestamp
collection_interval: 3600
# Email notification template
email_templates:
alert:
subject: "[{{severity}}] Beszel Alert: {{server_name}} - {{metric_name}}"
body: |
Beszel Monitoring Alert
Server: {{server_name}}
Metric: {{metric_name}}
Current Value: {{metric_value}}
Threshold: {{threshold}}
Condition: {{condition}}
Severity: {{severity}}
Duration: {{duration}}
Time: {{timestamp}}
Please investigate.
--
Beszel Monitoring System
{{dashboard_url}}
recovery:
subject: "[RECOVERED] Beszel Alert: {{server_name}} - {{metric_name}}"
body: |
Beszel Alert Recovered
Server: {{server_name}}
Metric: {{metric_name}}
Current Value: {{metric_value}}
Time: {{timestamp}}
--
Beszel Monitoring System
# Slack notification template
slack_templates:
alert:
attachments:
- color: "{{severity_color}}"
title: "Beszel Alert: {{severity}}"
fields:
- title: Server
value: "{{server_name}}"
short: true
- title: Metric
value: "{{metric_name}}"
short: true
- title: Current Value
value: "{{metric_value}}"
short: true
- title: Threshold
value: "{{threshold}}"
short: true
- title: Duration
value: "{{duration}}"
short: true
- title: Time
value: "{{timestamp}}"
short: false
footer: Beszel Monitoring
ts: "{{timestamp_unix}}"
# Validate configuration syntax
beszel config validate
# Check configuration
beszel config show
# Test database connection
beszel db test
# Test SSH connection to server
beszel ssh test web-server-01
# Restart Beszel service
sudo systemctl restart beszel
# Check service status
sudo systemctl status beszel
# View logs
sudo journalctl -u beszel -f
sudo tail -f /var/log/beszel/beszel.log
# Reload configuration without restart
sudo systemctl reload beszel
# Initialize database
beszel db init
# Backup database
beszel db backup /var/backups/beszel/
# Restore database
beszel db restore /var/backups/beszel/beszel-backup.db
# Clean old data
beszel db cleanup --older-than 365d
# Check service status
sudo systemctl status beszel
# Check if listening
sudo netstat -tlnp | grep 8080
# Check running processes
ps aux | grep beszel
# Access web interface
curl http://localhost:8080
# Check API health
curl http://localhost:8080/api/health
# Get server list
curl -H "Authorization: Bearer YOUR_API_KEY" http://localhost:8080/api/servers
# Test SSH connection
beszel ssh test web-server-01
# List connected servers
beszel servers list
# Get server metrics
beszel metrics get web-server-01 --metric cpu
# List alert rules
beszel alerts rules list
# Test alert notification
beszel alerts test --rule "High CPU Usage"
# View alert history
beszel alerts history
Running Beszel in regulated environments? We assist with:
Secure your deployment: office@linux-server-admin.com | Contact Page