Paying $20–50/month for Pingdom or UptimeRobot? Uptime Kuma does the same thing for free — on your own server, with unlimited monitors and zero per-seat pricing.
It's open-source, self-hosted, and takes about 10 minutes to deploy with Docker Compose. It supports 20+ monitor types (HTTP, TCP, Ping, DNS, Docker container health, push-based), sends alerts through 90+ notification providers, and lets you create public status pages. Version 2.0 added MariaDB support, rootless Docker images, and domain expiry monitoring.
Prerequisites
- Ubuntu 24.04 VPS with at least 1 vCPU and 1 GB RAM
- SSH access
- Docker and Docker Compose installed
Step 1 — Create the Project Directory
mkdir -p ~/uptime-kuma/data
cd ~/uptime-kuma
The data directory stores Uptime Kuma's SQLite database — all monitors, alerts, and uptime history.
Step 2 — Create the Docker Compose File
nano docker-compose.yml
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
restart: always
ports:
- "3001:3001"
volumes:
- ./data:/app/data
environment:
- TZ=UTC
-
louislam/uptime-kuma:2— pinned to v2 to avoid breaking changes -
restart: always— survives reboots and crashes -
./data:/app/data— persistent storage (without this, data is lost on recreate)
⚠️ Don't mount data on NFS — SQLite requires POSIX file locks, NFS causes corruption.
Step 3 — Start Uptime Kuma
docker compose up -d
docker compose ps
docker compose logs -f
Look for Listening on 3001. Ctrl+C to exit logs.
Step 4 — Configure the Firewall
sudo ufw allow 3001/tcp
sudo ufw reload
💡 Production tip: put Nginx in front as a reverse proxy with SSL. Change port mapping to
127.0.0.1:3001:3001so only localhost can reach it.
Step 5 — Create Your Admin Account
Open http://your_server_ip:3001. Set language, username, and strong password.
⚠️ No email-based password recovery exists. Losing the admin password means resetting via the SQLite database directly.
Step 6 — Add Your First Monitor
Click Add New Monitor:
- Type: HTTP(s) for websites
- Name: "Company Website"
-
URL:
https://example.com - Heartbeat: 60 seconds (30 for frequent checks)
- Retries: 3 (avoids false positives)
Other monitor types: TCP Port, Ping, DNS, Docker Container, Push (for cron jobs).
Step 7 — Set Up Notifications
Settings → Notifications → Setup Notification:
- Email: SMTP host, port 587/465, credentials, from/to addresses
- Telegram: Bot token (via @botfather) + chat ID
- Slack/Discord: Webhook URL
Click Test to verify, then Save. Apply to monitors via the Notifications section in each monitor's settings.
Step 8 — Update and Back Up
cd ~/uptime-kuma
docker compose pull
docker compose up -d
cp -r ~/uptime-kuma/data ~/uptime-kuma-backup-$(date +%Y%m%d)
Schedule backups with a cron job.
What's Next
- Add monitors for all your services
- Create public status pages for clients
- Set up Nginx + Let's Encrypt for HTTPS
- Mount Docker socket to monitor containers on the same server
- Set up multiple notification channels for redundancy
I'm Serdar, co-founder of Raff — affordable and reliable cloud infrastructure built to be the one platform your app needs — compute, storage, and beyond. Originally published on the Raff Technologies blog.
Top comments (0)