Self-Hosted Uptime Monitoring with Uptime Kuma on a VPS: Alerts, Status Pages, and SSL Checks
Uptime Kuma is an open-source, self-hosted monitoring tool for tracking website uptime, SSL certificate validity, DNS resolution, TCP ports, and API endpoints. UptimeRobot charges $7–$20/month for real-time monitoring. Uptime Kuma runs for free on your VPS, supports 50+ notification integrations, and lets you create beautiful public status pages — no subscription required.
What Uptime Kuma Monitors
- HTTP/HTTPS: Website availability and response time with keyword matching
- SSL certificates: Expiry warnings (notify at 30, 14, 7 days before expiry)
- TCP ports: Check if a port is open (databases, SSH, custom services)
- Ping (ICMP): Basic host reachability
- DNS: Verify DNS resolution returns expected records
- Docker containers: Check container running state
- Keyword matching: Fail if response doesn’t contain (or contains) a specific string
- JSON query: Check API response values
Step 1: Docker Installation
mkdir -p /opt/uptime-kuma && cd /opt/uptime-kuma
nano docker-compose.yml
version: '3.8'
services:
uptime-kuma:
image: louislam/uptime-kuma:latest
container_name: uptime-kuma
restart: always
ports:
- "127.0.0.1:3001:3001"
volumes:
- uptime_kuma_data:/app/data
# Mount Docker socket for container monitoring
- /var/run/docker.sock:/var/run/docker.sock:ro
volumes:
uptime_kuma_data:
docker compose up -d
docker compose logs -f uptime-kuma
Step 2: Nginx Reverse Proxy
sudo nano /etc/nginx/sites-available/uptime-kuma
server {
listen 80;
server_name status.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name status.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/status.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/status.yourdomain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
sudo ln -s /etc/nginx/sites-available/uptime-kuma /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d status.yourdomain.com
Step 3: Initial Setup
- Visit
https://status.yourdomain.com - Create your admin username and password
- You’re in the dashboard — add your first monitor
Step 4: Add Monitors
HTTP/HTTPS Website Monitor
- Add New Monitor → Monitor Type: HTTP(s)
- Friendly Name:
Main Website - URL:
https://yourdomain.com - Heartbeat Interval: 60 seconds
- Retry: 3 times (prevents false positives)
- Enable: Certificate Expiry Notification (warns before SSL expires)
- Expected Keywords: type a keyword that must appear in the response (e.g., company name)
TCP Port Monitor (Database, Redis)
- Monitor Type: TCP Port
- Host:
localhost - Port:
5432(PostgreSQL) - Interval: 60 seconds
Docker Container Monitor
- Monitor Type: Docker Container
- Container Name:
myapp - Notifies if container stops or crashes
SSL Certificate Monitor
- Monitor Type: HTTP(s) (SSL check is automatic for HTTPS monitors)
- Set “Certificate Expiry Notification” to 30 days
- Uptime Kuma checks certificate validity and warns before expiry
Step 5: Configure Notification Channels
Telegram
- Settings → Notifications → Add Notification
- Notification Type: Telegram
- Bot Token: your Telegram bot token (from @BotFather)
- Chat ID: your Telegram chat ID
- Test and Save
Slack / Discord / Email
- Settings → Notifications → Add Notification
- Choose your provider from 50+ options
- Enter webhook URL or credentials
- Test the notification to confirm delivery
Assign Notifications to Monitors
- Edit each monitor → Notifications → select which notification channels to use
- Configure: “Down” alert, “Up” recovery alert, certificate expiry alert
Step 6: Create a Public Status Page
- Status Page → New Status Page
- Name:
Service Status - Slug:
status(URL becomeshttps://status.yourdomain.com/status/status) - Add monitors to display (choose which services to show publicly)
- Customize: logo, title, description, incident messages
- Share the URL with customers or embed it in your website footer
The public status page shows uptime history, incident timeline, and current status of all included monitors — without exposing your admin dashboard.
Step 7: Monitoring from Multiple Locations
Uptime Kuma monitors from your VPS location only by default. For checking from multiple global locations (detect regional outages), run an Uptime Kuma satellite on a second VPS:
# On a second VPS (different location)
docker run -d \
-e UPTIME_KUMA_WS_ENDPOINT="wss://status.yourdomain.com" \
-e UPTIME_KUMA_MONITOR_LIST="1,2,3" \ # Monitor IDs from main instance
louislam/uptime-kuma-satellite
Uptime Kuma API for Automation
# REST API available at /metrics (Prometheus format)
curl https://status.yourdomain.com/metrics -u admin:password
# Get monitor status programmatically
curl "https://status.yourdomain.com/api/status-page/status" | jq '.publicGroupList[].monitorList[] | {name, status}'
Getting Started
Uptime Kuma uses 50–100 MB RAM and runs comfortably alongside other services on any Ubuntu VPS at VPS.DO. For maximum monitoring reliability, run Uptime Kuma on a separate VPS from the services it monitors — if your main VPS goes down, Uptime Kuma on a different server still detects the outage and sends alerts.
Conclusion
Uptime Kuma replaces UptimeRobot and Pingdom for teams that want full monitoring control, unlimited monitors, no per-monitor pricing, and a customizable public status page. HTTP, TCP, SSL, DNS, and Docker container monitoring cover the full scope of VPS service health. The 50+ notification integrations ensure the right people get alerted instantly when something goes down — not 5 minutes later when a customer reports it.