Appearance
How to monitor your sites with Uptime Kuma on a VPS
Uptime Kuma is a free, self hosted monitoring tool with a clean web interface. It checks websites, TCP ports, ping, DNS records and more, down to 20 second intervals, and alerts you through Telegram, Discord, Slack, email and dozens of other services. This guide runs it with Docker Compose, publishes it under your own domain with HTTPS through Caddy and connects Telegram alerts.
What you need
- A VPS with Docker installed. Follow how to install Docker on Ubuntu first. Uptime Kuma is light, 1 vCPU and 1 to 2 GB of RAM are enough for dozens of monitors.
- A domain or subdomain, for example
status.example.com, with an A record pointing to the server IP. - A Telegram account for alerts.
Monitor from a separate server
A monitoring tool cannot report that its own server is down. Run Uptime Kuma on a small VPS that is separate from the servers and sites it watches.
Step 1. Start Uptime Kuma with Docker Compose
Create a folder and a Compose file:
bash
mkdir -p ~/uptime-kuma && cd ~/uptime-kuma
nano compose.yamlThis is the official Compose file with one change: the port is bound to 127.0.0.1, so Kuma is reachable only through the reverse proxy and not directly from the internet. Docker published ports bypass UFW, so this binding matters.
yaml
services:
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./data:/app/data
ports:
- "127.0.0.1:3001:3001"Start it:
bash
docker compose up -d
docker compose ps
curl -I http://127.0.0.1:3001The container should be running, and curl should get an HTTP answer. All data is kept in ~/uptime-kuma/data. Uptime Kuma does not support network filesystems such as NFS for this folder, keep it on the local disk.
Step 2. Install Caddy as a reverse proxy
Caddy gets and renews a Let's Encrypt certificate automatically and proxies WebSocket connections, which the Kuma interface needs, without extra settings. Install it from the official repository:
bash
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddyThe package starts Caddy as a systemd service named caddy.
Step 3. Point your domain to Uptime Kuma
Replace the contents of /etc/caddy/Caddyfile:
bash
sudo nano /etc/caddy/Caddyfiletext
status.example.com {
reverse_proxy 127.0.0.1:3001
}Open the web ports if UFW is active, then reload Caddy:
bash
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo systemctl reload caddyCaddy needs port 80 and 443 reachable and the DNS record in place to get the certificate. If something is wrong, journalctl -u caddy -n 50 shows the reason.
Step 4. Create the admin account
Open https://status.example.com. On the first visit Uptime Kuma 2 asks which database to use. SQLite is a simple database file recommended for small setups, and the Docker image also includes an embedded MariaDB that needs no settings. Either works for a personal monitor.
Then create your admin account with a strong password. In Settings > Security you can also enable two factor authentication.
Because Kuma is only reachable through Caddy, go to Settings > Reverse Proxy and set Trust Proxy to Yes. Logs will then show real visitor IPs instead of 127.0.0.1.
Step 5. Connect Telegram notifications
- In Telegram, open @BotFather, send
/newbotand follow the prompts. Copy the bot token. - Open a chat with your new bot and send it any message, so it is allowed to write to you.
- In Uptime Kuma go to Settings > Notifications and click Set Up Notification.
- Choose Telegram as the notification type and paste the token into Bot Token.
- Click Auto Get next to Chat ID to fill in your chat ID automatically.
- Enable Default enabled so new monitors use it, and optionally Apply on all existing monitors.
- Click Test. A test message should arrive in Telegram. Then save.
Step 6. Add your first monitors
Click Add New Monitor and choose the Monitor Type:
| Type | Use it for |
|---|---|
| HTTP(s) | Websites and APIs. Checks the status code and can also warn before the TLS certificate expires. |
| HTTP(s) Keyword | Pages that must contain a specific text, to catch error pages returned with status 200. |
| TCP Port | Services like SSH, databases or a game server port. |
| Ping | Plain reachability of a server. |
| Push | Cron jobs and backups: the job calls a URL, and Kuma alerts if the call does not arrive in time. |
Give it a Friendly Name, set the URL or host and the Heartbeat Interval, then save. A Push monitor pairs well with a nightly restic backup: add a curl to the push URL after the backup, and you hear about it when a backup silently stops running.
Status pages
Under Status Pages you can publish a public page with selected monitors, for example to show your users whether your service is up. Each page gets its own slug, and you can map a separate domain to it.
Update Uptime Kuma
bash
cd ~/uptime-kuma
docker compose pull
docker compose up -dBack up ~/uptime-kuma/data before major upgrades. It holds all monitors, history and settings.
Summary
Uptime Kuma now runs in Docker, is reachable only through Caddy with HTTPS, and sends alerts to Telegram. Add a monitor for every site, API and important port you run, and you will learn about problems before your users do.