---
title: "Monitor Your Server Like a Pro: Beszel & Uptime Kuma Setup on Dokploy"
description: "Complete guide to setting up Beszel for resource monitoring (CPU, memory, disk, Docker) and Uptime Kuma for uptime checks on Dokploy with SMTP alerts."
date: 2025-12-05
categories: ["vps"]
tags: ["self-hosted","docker","monitoring"]
---

import YouTubeEmbed from "../../layouts/components/widgets/YouTubeEmbed.astro";
import Button from "../../layouts/components/widgets/Button.astro";
import { Image } from "astro:assets";
import Notice from "@components/widgets/Notice.astro";
import ListCheck from "@components/widgets/ListCheck.astro";
import Accordion from "@components/widgets/Accordion.astro";

import beszel1 from "../../assets/images/24/11/beszel1.jpeg";
import beszel2 from "../../assets/images/24/11/beszel2.jpeg";

Monitoring your self-hosted infrastructure matters. Whether you're running a simple VPS or a cluster of servers, knowing when a service goes down or when a disk is full matters. You need visibility into what's happening inside your servers (resources) and confirmation that services are accessible from the outside (uptime).

Server monitoring tracks server performance metrics. This helps maintain system reliability and prevent issues before they impact services. Server monitoring includes:

- **Resource utilization**: CPU, memory, disk, network
- **Application performance**: Response times, error rates
- **Service availability**: Uptime checks, health endpoints
- **Container health**: Docker container stats and performance

In this guide, we'll set up monitoring using [Dokploy](https://www.bitdoze.com/dokploy-install/). We'll deploy **Beszel** for internal resource monitoring (CPU, memory, disk, Docker stats) and **Uptime Kuma** for external uptime checks (HTTP/DNS).

<Notice type="info" title="More Monitoring Options">
For a broader look at monitoring options like Netdata or Prometheus + Grafana, check out our comprehensive guide on [Server Monitoring Tools](https://www.bitdoze.com/sever-monitoring/).
</Notice>

<YouTubeEmbed
  url="https://www.youtube.com/embed/T7izljcBFeE"
  label="Monitor Your Server Like a Pro: Beszel & Uptime Kuma Setup on Dokploy"
/>

## Understanding Key Monitoring Metrics

Before setting up monitoring tools, understand what metrics matter:

### Essential Server Metrics

| Metric Category | What to Monitor | Why It Matters |
|-----------------|-----------------|----------------|
| **CPU** | Load average (1, 5, 15 min), per-core usage, system/user time | Identifies processing bottlenecks |
| **Memory** | Available RAM, swap usage, buffer/cache utilization | Prevents out-of-memory crashes |
| **Disk** | Space usage, inode utilization, I/O wait times | Avoids disk-full failures |
| **Network** | Bandwidth, packet loss, latency, connection states | Detects network issues early |

### Monitoring Priorities by Environment

Different environments have different monitoring focus:

| Metric Type | Traditional Server | Container Environment | Cloud Infrastructure |
|-------------|-------------------|----------------------|---------------------|
| CPU | Overall usage | Per container usage | Instance utilization |
| Memory | Physical/Swap | Container limits | Instance limits |
| Storage | Partition usage | Volume usage | Block storage |
| Network | Interface stats | Container networks | VPC metrics |

## Why Beszel and Uptime Kuma?

Here's what each tool does:

| Tool | Purpose | What It Monitors |
|------|---------|------------------|
| **Beszel** | Internal resource monitoring | CPU, memory, disk, network, Docker containers |
| **Uptime Kuma** | External availability checks | HTTP/HTTPS endpoints, DNS, TCP ports, SSL certificates |

### Beszel - Lightweight Monitoring Hub

[Beszel](https://github.com/henrygd/beszel) is a lightweight monitoring solution. Unlike Prometheus + Grafana, Beszel uses a single binary agent and provides:

<ListCheck>
- Real-time server metrics monitoring
- Historical data with graphs
- Docker container statistics
- Custom notification channels (email, webhooks)
- Public key authentication for secure agent communication
- Multi-server support from a single hub
- Very low resource footprint
</ListCheck>

Here's what the Beszel interface looks like in action:

<Image src={beszel1} alt="Beszel Main Interface showing server metrics dashboard" />

Beszel provides detailed historical graphs for all your metrics:

<Image src={beszel2} alt="Beszel Graphs showing CPU, memory, and network usage over time" />

**Beszel Feature Overview:**

| Feature | Description | Benefit |
|---------|-------------|---------|
| Lightweight | Minimal resource usage (~10-20MB RAM per agent) | Ideal for small servers |
| Docker Integration | Native container monitoring | Easy container tracking |
| Public Key Auth | Secure agent communication via SSH keys | Enhanced security |
| Multi-server Support | Monitor multiple servers from one hub | Centralized monitoring |
| Historical Data | Stores metrics with graphs over time | Trend analysis |

### Uptime Kuma - Uptime Monitoring

[Uptime Kuma](https://github.com/louislam/uptime-kuma) is a self-hosted uptime monitoring solution. It checks if your websites and services are accessible from the outside world and sends notifications if they aren't.

<ListCheck>
- HTTP/HTTPS endpoint monitoring
- DNS, TCP, Ping, and Docker container checks
- SSL certificate expiration monitoring
- Beautiful status pages you can share
- 90+ notification integrations
- Maintenance windows
- Multi-language support
</ListCheck>

### Why Use Both Together?

**Internal health ≠ external availability**:

- Your server could show 10% CPU usage, but your website might be down due to a misconfigured nginx
- A container might be "running" but returning 502 errors
- Your disk might be 95% full, but Uptime Kuma won't know until the app crashes

Beszel tells you what's happening inside. Uptime Kuma tells you what users experience.

### How This Stack Compares to Other Solutions

| Feature | Beszel + Uptime Kuma | Prometheus/Grafana | Netdata |
|---------|---------------------|-------------------|---------|
| **Scalability** | Small-Medium | Enterprise-grade | Medium |
| **Setup Complexity** | Low | High | Low |
| **Customization** | Basic-Moderate | Extensive | Moderate |
| **Resource Usage** | Very Low (~200MB total) | Moderate-High | Low |
| **Learning Curve** | Gentle | Steep | Moderate |
| **Uptime Monitoring** | Built-in (Kuma) | Requires additional setup | Limited |
| **Status Pages** | Yes (Kuma) | Manual setup needed | No |

### The Importance of Proactive Notifications

A well-configured alerting system should:

1. **Provide Early Warning**
   - Detect potential issues before they become critical
   - Monitor trend changes that might indicate future problems
   - Alert on unusual patterns or anomalies

2. **Enable Quick Response**
   - Deliver notifications through multiple channels (email, SMS, Slack)
   - Include relevant diagnostic information
   - Provide clear action items

3. **Prevent Alert Fatigue**
   - Use intelligent thresholds
   - Implement alert correlation
   - Configure proper alert priorities

## Prerequisites

Before starting:

<ListCheck>
- **A VPS or Server**: Minimum 2GB RAM recommended (1GB works for small deployments)
- **Dokploy Installed**: Follow our [Dokploy Installation Guide](https://www.bitdoze.com/dokploy-install/) if you haven't already
- **A Domain Name**: For accessing your monitoring dashboards (e.g., `monitor.yourdomain.com`, `status.yourdomain.com`)
- **Email Service (Optional)**: For alert notifications (we'll use Brevo/Sendinblue which offers 300 free emails/day)
</ListCheck>

<Button text="Try Hetzner Cloud Now" link="https://go.bitdoze.com/hetzner" variant="solid" color="blue" size="lg" external={true} icon="rocket-launch" />
<Button text="Try Hostinger VPS" link="https://go.bitdoze.com/hostinger-vps" variant="solid" color="green" size="lg" external={true} icon="rocket-launch" />

## Part 1: Deploying Beszel (Resource Monitoring Hub)

Beszel has two components:
1. **The Hub**: The main dashboard where you view all metrics
2. **The Agent**: Installed on every server you want to monitor

### Step 1: Create the Beszel Service in Dokploy

1. Go to your Dokploy dashboard and navigate to your project
2. Click **Create Service** → **Template**
3. Search for **Beszel** and select it
4. Choose the server you want to deploy the Hub on
5. Select the latest version tag (e.g., `0.9.1` or `latest`)

<Notice type="info" title="Deployment Tip">
For redundancy, consider deploying the Hub on a separate node from your main production apps. If your production server goes down, you'll still receive alerts.
</Notice>

### Step 2: Configure the Domain

1. In Dokploy, go to the **Domains** tab for your new Beszel service
2. Add your domain (e.g., `monitor.yourdomain.com`)
3. Set the port to **8090** (Beszel's default UI port)
4. Enable **HTTPS** (Let's Encrypt)
5. Click **Create**

If using Cloudflare:
- Create an **A Record** pointing `monitor` to your server IP
- Set SSL/TLS mode to **Full** (not Flexible)

### Step 3: Set Essential Environment Variables

To ensure email alerts contain the correct links (instead of `localhost`), you must set the application URL.

1. Go to the **Environment** tab in Dokploy
2. Add the following variable:

```sh
APP_URL=https://monitor.yourdomain.com
```

3. Click **Save** and **Redeploy**

### Step 4: Initial Beszel Setup

1. Visit your new URL (`https://monitor.yourdomain.com`)
2. Create your admin account with a strong password
3. You'll land on the main dashboard (empty for now)

**Best Practices for Beszel Deployment:**
- Use secure networking between server and agents
- Implement proper backup for Beszel data
- Regular updates of both server and agent containers
- Monitor agent connectivity from the Hub

## Part 2: Installing the Beszel Agent

Now that the Hub is running, we need to install the Agent on every server we want to monitor.

### Step 1: Get the Agent Configuration from the Hub

1. In the Beszel Hub, click **Add System**
2. Name your system (e.g., `main-dokploy-node` or `production-1`)
3. Copy the Docker Compose snippet provided - it contains your unique public **KEY** for authentication

The snippet will look something like this:

```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:
      PORT: 45876
      KEY: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHiPxG...'
```

### Step 2: Deploy the Agent via Dokploy

1. Go back to Dokploy on the server you want to monitor
2. Create a new **Compose** service (not a template)
3. Name it `beszel-agent`
4. Paste the Docker Compose configuration you copied from the Hub
5. Click **Deploy**

<Notice type="warning" title="Important">
Ensure the port mapping matches what the Hub expects. The default is **45876**. If you change it, update it in both the agent and the Hub.
</Notice>

### Step 3: Verify the Connection

Once deployed:
- The icon in your Beszel Hub should turn **green**
- You'll start seeing real-time CPU, Memory, Disk, and Docker container stats
- Historical graphs will begin populating

**What Metrics You'll See:**

| Metric | Description | Alert Threshold Suggestion |
|--------|-------------|---------------------------|
| CPU Load | 1, 5, 15 minute load averages | > 90% for 5 minutes |
| Memory | Used, available, cached, swap | > 85% used |
| Disk | Usage per mount point, I/O stats | > 85% capacity |
| Network | Bandwidth in/out, packet stats | Unusual spikes |
| Docker | Per-container CPU, memory, network | Container-specific |

### Monitoring Additional Servers

Repeat the agent installation process for each server you want to monitor:

1. In the Hub, click **Add System** for each new server
2. Give it a unique name
3. Copy the Docker Compose snippet (each will have a unique KEY)
4. Deploy the agent on that server

## Part 3: Setting Up Uptime Kuma

Beszel watches internal resources, Uptime Kuma watches external availability.

### Step 1: Deploy via Dokploy Template

1. In Dokploy, create a new service from **Template**
2. Search for **Uptime Kuma** and select it
3. Check the image tag - change to the latest stable version if needed (e.g., `1` or specific version like `1.23.15`)
4. Click **Deploy**

### Step 2: Configure the Domain

1. Go to the **Domains** tab
2. Set up a domain (e.g., `status.yourdomain.com`)
3. The internal port should be **3001**
4. Enable **HTTPS**
5. Click **Create**

<Notice type="info" title="Volume Persistence">
Dokploy handles the volume creation automatically to persist your monitoring data across container restarts.
</Notice>

### Step 3: Initial Uptime Kuma Setup

1. Visit your new URL (`https://status.yourdomain.com`)
2. Create your admin account
3. You'll see an empty dashboard ready for monitors

### Step 4: Add Your First Monitor

1. Click **Add New Monitor**
2. Choose monitor type: **HTTP(s)** for websites
3. Enter the URL you want to monitor
4. Set the heartbeat interval (e.g., 60 seconds)
5. Click **Save**

**Recommended monitors to set up:**

| Monitor Type | Use Case | Example |
|--------------|----------|---------|
| HTTP(s) | Website availability | `https://yourdomain.com` |
| HTTP(s) - Keyword | Content verification | Check for "Welcome" text |
| TCP Port | Database connectivity | PostgreSQL on port 5432 |
| DNS | DNS resolution | Check A record for domain |
| Docker Container | Container health | Monitor specific container |

## Part 4: Configuring SMTP Alerts with Brevo

Monitoring doesn't help if you don't get notified when things break. Here's how to set up email alerts using [Brevo](https://www.brevo.com/) (formerly Sendinblue), which offers 300 free emails per day.

### Step 1: Get SMTP Details from Brevo

1. Create a free Brevo account if you don't have one
2. Go to **Settings** → **SMTP & API**
3. Generate a new **SMTP Key**
4. Note down your credentials:

| Setting | Value |
|---------|-------|
| Server | `smtp-relay.brevo.com` |
| Port | `587` |
| Login | Your Brevo email |
| Password | The SMTP Key you generated |

<Notice type="warning" title="Sender Authentication">
Ensure your sender address (e.g., `alerts@yourdomain.com`) is authenticated in Brevo. Go to **Settings** → **Senders & IP** → **Senders** and add/verify your domain.
</Notice>

### Step 2: Configure Beszel Alerts

1. In Beszel, go to **Settings** → **SMTP** (or General settings depending on version)
2. Enter the SMTP details:
   - **Host**: `smtp-relay.brevo.com`
   - **Port**: `587`
   - **Username**: Your Brevo email
   - **Password**: Your SMTP Key
   - **Sender Address**: `alerts@yourdomain.com`
3. Save the settings

**Set up alert thresholds:**

1. Go to **Systems** → click your server → **Alerts**
2. Enable alerts for specific thresholds:

| Metric | Recommended Threshold |
|--------|----------------------|
| CPU Usage | > 90% for 5 minutes |
| Memory Usage | > 85% |
| Disk Usage | > 85% |
| System Status | Down |

### Step 3: Configure Uptime Kuma Alerts

1. In Uptime Kuma, go to **Settings** → **Notifications**
2. Click **Setup Notification**
3. Choose **Email (SMTP)**
4. Fill in the same Brevo details:
   - **Hostname**: `smtp-relay.brevo.com`
   - **Port**: `587`
   - **Security**: STARTTLS
   - **Username**: Your Brevo email
   - **Password**: Your SMTP Key
   - **From Email**: `alerts@yourdomain.com`
   - **To Email**: Your notification email
5. Click **Test** to verify it works
6. Save the notification

**Attach notifications to monitors:**

When creating or editing a monitor, scroll down to **Notifications** and select your email notification to receive alerts for that specific monitor.

## Part 5: Testing Your Monitoring Stack

Verify everything works before assuming you're covered.

### Test Beszel Alerts

1. SSH into your monitored server
2. Stop the Beszel Agent container:
   ```sh
   docker stop beszel-agent
   ```
3. Wait 1-2 minutes
4. You should receive an email saying "System is Down"
5. Restart the agent:
   ```sh
   docker start beszel-agent
   ```
6. You should receive a "System is Up" email

### Test Uptime Kuma Alerts

1. Stop one of your monitored web applications:
   ```sh
   docker stop your-web-app
   ```
2. Uptime Kuma should detect the error (502/Timeout) within your heartbeat interval
3. You should receive a notification email
4. Restart your app and verify you get an "Up" notification

## Advanced Configuration

### Creating Status Pages with Uptime Kuma

Uptime Kuma can generate public status pages to share with your users:

1. Go to **Status Pages** in the menu
2. Click **New Status Page**
3. Give it a name and slug (e.g., `status`)
4. Add monitors to display
5. Customize the look and feel
6. Share the public URL with users

### Monitoring Docker Containers Directly

Uptime Kuma can monitor Docker containers without going through HTTP:

1. Create a new monitor with type **Docker Container**
2. Enter the container name or ID
3. The monitor checks if the container is running (not just the port)

<Notice type="info" title="Docker Socket Access">
For Docker container monitoring in Uptime Kuma, you need to mount the Docker socket. The Dokploy template should handle this, but verify the volume mount exists:
```yaml
volumes:
  - /var/run/docker.sock:/var/run/docker.sock
```
</Notice>

### Monitoring Multiple Servers

For a multi-server setup:

1. Deploy **one Beszel Hub** (central dashboard)
2. Deploy **Beszel Agents on each server** (using unique keys)
3. Deploy **one Uptime Kuma instance** (can monitor all external endpoints)
4. Configure alerts to go to the same email/Slack/Discord channel

## Best Practices

<ListCheck>
- **Set meaningful alert thresholds**: Avoid alert fatigue by not alerting on every 80% CPU spike
- **Use multiple notification channels**: Email + Slack/Discord for critical alerts
- **Monitor your monitoring**: Set up an external service (like UptimeRobot free tier) to monitor your Uptime Kuma instance
- **Regular testing**: Test your alerts monthly to ensure they still work
- **Document your setup**: Keep notes on what each monitor checks and why
- **Backup configurations**: Export your Uptime Kuma configuration periodically
</ListCheck>

### Recommended Alert Thresholds

Based on real-world experience, here are suggested thresholds for common metrics:

| Metric | Warning Level | Critical Level | Notes |
|--------|---------------|----------------|-------|
| CPU Usage | 70% for 5 min | 90% for 5 min | Sustained high CPU indicates bottleneck |
| Memory Usage | 75% | 85% | Leave headroom for spikes |
| Disk Usage | 80% | 90% | Plan expansion before hitting critical |
| Disk I/O Wait | 20% | 40% | High I/O wait slows everything |
| Network Errors | Any increase | Sustained errors | Usually indicates hardware issues |
| Container Restarts | 2 in 10 min | 5 in 10 min | Crash loops need investigation |

### When to Scale Up Your Monitoring

Consider moving to more robust solutions when:

1. **Small deployments (1-5 servers)**: Beszel + Uptime Kuma is perfect
2. **Medium deployments (5-20 servers)**: Consider adding Netdata for deeper insights
3. **Large deployments (20+ servers)**: Evaluate Prometheus/Grafana for enterprise features

## Conclusion

By combining **Beszel** for internal resource metrics and **Uptime Kuma** for external uptime checks, you have a self-hosted monitoring stack running on Dokploy. This setup is:

- **Lightweight**: Minimal resource usage compared to Prometheus/Grafana
- **Cost-effective**: Free to self-host
- **Comprehensive**: Covers internal health and external availability
- **Alert-ready**: You'll be first to know when something breaks

Your monitoring stack provides visibility into:
- Server resources (CPU, memory, disk, network)
- Docker container health and statistics
- Website and API availability
- SSL certificate expiration
- And more

### Choosing the Right Tool for Your Needs

| Your Situation | Recommended Approach |
|----------------|---------------------|
| **Beginner with 1-2 servers** | Start with this Beszel + Uptime Kuma stack |
| **Need log monitoring too** | Add Dozzle for Docker logs |
| **Want cloud-managed option** | Consider Netdata Cloud (free for 5 nodes) |
| **Enterprise with complex needs** | Prometheus + Grafana stack |

**Summary of Best Practices:**
- Start with basic monitoring and expand as needed
- Implement proper alerting with meaningful thresholds
- Regular backup of monitoring data
- Keep monitoring tools updated
- Document monitoring setup and procedures

For more advanced monitoring scenarios or to explore other tools like Netdata or Prometheus, check out our [Server Monitoring Guide](https://www.bitdoze.com/sever-monitoring/).

<Button link="https://github.com/henrygd/beszel" text="Beszel on GitHub" />
<Button link="https://github.com/louislam/uptime-kuma" text="Uptime Kuma on GitHub" />

## Frequently Asked Questions

<Accordion label="What's the difference between Beszel and Uptime Kuma?" group="faq" expanded="true">
**Beszel** monitors internal server resources - CPU usage, memory consumption, disk space, network bandwidth, and Docker container stats. It tells you what's happening inside your server.

**Uptime Kuma** monitors external availability - whether your websites are accessible, APIs are responding, and services are reachable from outside. It tells you what users experience.

You need both because a server can have healthy internal metrics but still serve errors to users (misconfig, full queue, etc.), and vice versa.
</Accordion>

<Accordion label="How much resources do Beszel and Uptime Kuma use?" group="faq">
Both tools are lightweight:

- **Beszel Hub**: ~50-100MB RAM
- **Beszel Agent**: ~10-20MB RAM per monitored server
- **Uptime Kuma**: ~100-200MB RAM depending on number of monitors

Combined, expect under 500MB RAM for a complete monitoring stack, which is less than Prometheus + Grafana.
</Accordion>

<Accordion label="Can I use other notification services besides email?" group="faq">
Both tools support multiple notification channels:

**Beszel** supports:
- Email (SMTP)
- Webhooks (for Slack, Discord, etc.)
- Custom integrations

**Uptime Kuma** has 90+ integrations including:
- Slack, Discord, Microsoft Teams
- Telegram, Pushover, Gotify
- PagerDuty, Opsgenie
- SMS services
- Custom webhooks
</Accordion>

<Accordion label="Can I monitor servers that aren't running Dokploy?" group="faq">
The Beszel Agent is a Docker container (or binary) that runs anywhere:

1. Install it via Docker on any Linux server
2. Run the binary directly without Docker
3. Deploy it on Kubernetes

As long as the agent can reach the Hub over the network (port 45876 by default), it works.
</Accordion>

<Accordion label="Is there a way to create public status pages?" group="faq">
Uptime Kuma has built-in status page functionality:

1. Go to **Status Pages** in the menu
2. Create a new status page with your monitors
3. Customize the appearance
4. Share the public URL with your users

You can have multiple status pages for different audiences (internal team vs. public users).
</Accordion>

<Accordion label="How do I backup my monitoring data?" group="faq">
For **Dokploy deployments**, data is stored in Docker volumes:

- **Beszel**: Data in `/beszel_data` inside the container
- **Uptime Kuma**: Data in the Kuma data volume

To backup:
1. Use Dokploy's backup features if available
2. Or manually backup the Docker volumes:
```sh
docker run --rm -v uptime-kuma_data:/data -v $(pwd):/backup alpine tar cvf /backup/kuma-backup.tar /data
```

For Beszel, export system configurations from the UI when possible.
</Accordion>

<Accordion label="What are the recommended alert thresholds?" group="faq">
Based on production experience, here are suggested thresholds:

- **CPU**: Alert at 90% sustained for 5+ minutes
- **Memory**: Alert at 85% usage
- **Disk**: Warning at 80%, critical at 90%
- **System Status**: Immediate alert when down

These can be adjusted based on your workload patterns. Some applications have natural CPU spikes that shouldn't trigger alerts.
</Accordion>

<Accordion label="Can I monitor additional disk partitions with Beszel?" group="faq">
Yes! Beszel supports monitoring additional disks by mounting folders in the `/extra-filesystems` directory. In your agent's Docker Compose, add:

```yaml
volumes:
  - /var/run/docker.sock:/var/run/docker.sock:ro
  - /mnt/disk/.beszel:/extra-filesystems/sda1:ro
```

This allows you to monitor external drives, NAS mounts, or additional partitions beyond the root filesystem.
</Accordion>

<Accordion label="How does Beszel compare to Netdata or Prometheus?" group="faq">
Each tool has its strengths:

- **Beszel**: Lightest weight (~20MB RAM), perfect for small deployments, simple setup
- **Netdata**: More metrics out of the box, ML anomaly detection, cloud option for 5 free nodes
- **Prometheus/Grafana**: Most customizable, enterprise-grade, but steeper learning curve and higher resource usage

For most self-hosted scenarios with 1-10 servers, Beszel + Uptime Kuma provides the best balance of features and resource efficiency.
</Accordion>