If you run any self-hosted service — a Nextcloud instance, a Vaultwarden vault, a personal blog, or a home lab full of containers — you eventually ask the same question: how do I know when something goes down before a user (or your boss) tells you?
Commercial uptime monitors like UptimeRobot and Pingdom solve this, but they route your infrastructure’s availability data through a third party and often gate features like SMS alerts or unlimited monitors behind a paywall. Uptime Kuma is the self-hosted answer: a fast, open-source monitoring tool with a clean dashboard, over 90 notification integrations, and the ability to publish a public status page — all running entirely on your own hardware.
This guide walks through the full Docker deployment, monitor configuration, notification setup, securing the dashboard behind a reverse proxy, and building a public status page for your services.
1. How Uptime Kuma Works
Unlike Immich or Nextcloud, Uptime Kuma is intentionally lightweight — a single container handles everything, with no separate database service required for most setups.
Uptime Kuma Core Architecture:
[ Monitors (HTTP, TCP, Ping, DNS, Docker) ]
│
▼ (checked on interval)
[ Uptime Kuma Server ]
(Node.js + Socket.IO)
│ │
▼ ▼
[ SQLite Database ] [ Notification Providers ]
(history, config) (Telegram, Discord, Email,
Webhook, ntfy, etc.)
│
▼
[ Public Status Page ]
- Monitor Engine: Runs scheduled checks against HTTP(S) endpoints, TCP ports, ICMP ping targets, DNS records, and even Docker container health status.
- SQLite Storage: Stores historical uptime data, response times, and configuration in a single embedded database file — no external Postgres or MySQL needed.
- Real-Time Dashboard: Uses Socket.IO to push live status updates to the web UI without requiring a page refresh.
- Notification Layer: When a monitor fails a check (after your configured retry threshold), it fires alerts through any connected notification provider.
- Status Page Generator: Builds a shareable, public-facing page displaying the live status of whichever monitors you choose to expose.
2. System Prerequisites
Uptime Kuma is intentionally lightweight compared to a machine-learning-driven app like Immich:
- CPU: Any modern x86_64 or ARM64 core — it runs comfortably on a Raspberry Pi.
- RAM: 512 MB minimum; 1 GB recommended if monitoring 50+ endpoints.
- Storage: Under 1 GB for the application; database growth is minimal even with months of history.
- Software: Docker and Docker Compose installed on a Linux host.
If you haven’t set up Docker yet, our guide on installing Docker on Ubuntu covers the full setup from a clean system.
3. Step-by-Step Docker Installation
Create a dedicated directory for the deployment:
mkdir -p ~/uptime-kuma
cd ~/uptime-kuma
The Docker Compose File
nano docker-compose.yml
version: "3.8"
services:
uptime-kuma:
container_name: uptime_kuma
image: louislam/uptime-kuma:1
volumes:
- uptime-kuma-data:/app/data
- /var/run/docker.sock:/var/run/docker.sock:ro
ports:
- 3001:3001
restart: always
volumes:
uptime-kuma-data:
Explaining the Configuration
uptime-kuma-datavolume: Persists the SQLite database, uploaded images, and settings across container restarts and upgrades./var/run/docker.sockmount: Optional, but required if you want Uptime Kuma to monitor the health status of other Docker containers running on the same host. Mount it read-only (:ro) unless you specifically need write access.- Port
3001: The default web dashboard port. You’ll place this behind a reverse proxy in step 6 rather than exposing it directly.
Launch the stack:
sudo docker compose up -d
Check the logs to confirm a clean startup:
sudo docker compose logs -f
4. Initial Setup & First Monitor
- Navigate to
http://<YOUR_SERVER_IP>:3001in your browser. - Create your administrator account with a username and a strong password.
- Click Add New Monitor on the dashboard.
- Configure your first check:
| Field | Example Value | Notes |
|---|---|---|
| Monitor Type | HTTP(s) | Also supports TCP Port, Ping, DNS, Docker Container |
| Friendly Name | Free Tech Learner | Display label on the dashboard |
| URL | https://www.freetechlearner.com | The endpoint to check |
| Heartbeat Interval | 60 seconds | How often the check runs |
| Retries | 3 | Failed checks before an alert fires |
| Resend Notification | Every 10 checks | Prevents alert fatigue during long outages |
Monitor Lifecycle:
[ Check Runs ] ──► [ Success ] ──► Green heartbeat, dashboard updates
│
└────────► [ Failure ] ──► Retry threshold hit? ──► [ Yes ] ──► Fire notification
5. Configuring Notifications
A monitor without an alert channel is just a pretty graph. Under Settings > Notifications, Uptime Kuma supports Telegram, Discord, Slack, email (SMTP), webhooks, and self-hosted push services like ntfy.
Example: Telegram Bot Alerts
- Create a bot via @BotFather on Telegram and copy the bot token.
- In Uptime Kuma, go to Settings > Notifications > Setup Notification.
- Select Telegram, paste your bot token, and enter your chat ID.
- Click Test to confirm delivery, then save.
- Attach this notification to each monitor you want it to cover — notifications are opt-in per monitor, not global by default.
Example: Self-Hosted Webhook
If you already run automation tooling, a generic webhook lets Uptime Kuma POST a JSON payload to any endpoint you control — useful for piping alerts into a home automation system or a custom logging pipeline.
6. Securing the Dashboard with a Reverse Proxy
Never expose port 3001 directly to the internet. Route it through a reverse proxy with HTTPS termination. If you’re already running Nginx Proxy Manager for other self-hosted services, our Nginx Proxy Manager security guide covers hardening it properly — the same proxy host pattern applies here:
- In Nginx Proxy Manager, add a new Proxy Host.
- Set the domain (e.g.,
status.yourdomain.com), forward hostname to your server’s internal IP, and forward port3001. - Enable Force SSL and request a Let’s Encrypt certificate.
- Enable WebSockets Support — this is required, since Uptime Kuma’s live dashboard relies on Socket.IO.
Also make sure your firewall only allows the reverse proxy to reach port 3001, not the wider internet. Our Linux security commands guide and Fail2Ban guide are useful next steps for locking down the host this container runs on.
7. Building a Public Status Page
One of Uptime Kuma’s strongest features is generating a status page you can share with users, clients, or teammates — without exposing your internal dashboard.
- Go to Status Pages in the left sidebar and click New Status Page.
- Give it a title (e.g., “Free Tech Learner Service Status”) and a custom slug.
- Drag the monitors you want to expose into visible groups — you can hide internal-only monitors (like a database health check) while showing public-facing ones.
- Customize the theme, add a description, and optionally attach a custom domain.
- Publish — the page is now available at
https://<your-domain>/status/<slug>without requiring a login.
Status Page Visibility:
[ Internal Monitors ] ──X── (hidden from public page)
[ Public-Facing Services ] ──✓── (shown with live uptime %)
8. Backing Up Your Uptime Kuma Data
Since everything lives in a single SQLite file inside the Docker volume, backups are straightforward:
#!/bin/bash
BACKUP_DIR="/home/suresh/uptime-kuma/backups"
TIMESTAMP=$(date +%F)
mkdir -p "$BACKUP_DIR"
# Copy the SQLite database and config out of the container
docker cp uptime_kuma:/app/data/kuma.db "$BACKUP_DIR/kuma_$TIMESTAMP.db"
# Retain only the last 14 days of backups
find "$BACKUP_DIR" -type f -name "kuma_*.db" -mtime +14 -delete
Schedule it with cron for daily execution, and sync the backup directory offsite using the same rsync pattern covered in our self-hosted backup strategies guide.
9. Troubleshooting & Maintenance
| Issue / Symptom | Primary Cause | Troubleshooting / Diagnostic Action |
|---|---|---|
| Dashboard shows blank page | WebSocket connection blocked by proxy | Confirm WebSockets Support is enabled on your reverse proxy host. |
| Docker container monitors show “N/A” | Docker socket not mounted | Verify /var/run/docker.sock is mounted in docker-compose.yml and the container was restarted after adding it. |
| Notifications never fire | Notification not attached to monitor | Notifications must be individually enabled per monitor, not just configured globally. |
| False-positive downtime alerts | Retry/interval set too aggressively | Increase Retries and Heartbeat Interval to tolerate brief network blips. |
| Status page not loading on custom domain | DNS or proxy misconfiguration | Confirm the custom domain’s DNS record points to your reverse proxy, not directly to the container. |
10. Uptime Kuma vs. Alternatives
| Feature / Metric | Uptime Kuma | UptimeRobot | Healthchecks.io |
|---|---|---|---|
| Hosting Model | Self-hosted | Cloud (SaaS) | Cloud / self-hostable |
| Monitor Types | HTTP, TCP, Ping, DNS, Docker | HTTP, Ping, Port, Keyword | Cron/heartbeat-style |
| Public Status Pages | Unlimited, free | Limited on free tier | Yes |
| Notification Integrations | 90+ | Fewer, tiered by plan | Moderate |
| Data Ownership | Fully local | Third-party servers | Third-party (unless self-hosted) |
| Cost | Free (self-hosted) | Free tier + paid plans | Free tier + paid plans |
11. Conclusion
Uptime Kuma gives you full visibility into your self-hosted infrastructure without handing your uptime data to a third party. Paired with a hardened reverse proxy and a solid backup routine, it becomes the missing monitoring layer for any home lab or personal server stack.
Once your monitoring is live, make sure the services it’s watching are actually secure. Check out our guides on securing SSH on Ubuntu and the complete home server security checklist to lock down what Uptime Kuma is keeping an eye on.
Discussion
Loading comments...