Skip to main content
Back to Category

Uptime Kuma Setup: Self-Hosted Uptime Monitoring

Uptime Kuma installation with Docker, HTTP/TCP/DNS/ping monitoring, notification integrations (Telegram, Discord, email), status page creation, and alert configuration.

Read time: 12 min Self-Hosting
uptime-kumamonitoringuptimeself-hostingdockernotificationsstatus page
Author
REXE Teknoloji Network & Security Team
Editor
REXE Teknoloji Technical Editorial
First published
Last updated

Uptime Kuma Setup: Self-Hosted Uptime Monitoring

Uptime Kuma is a self-hosted uptime monitoring tool that tracks the operational status of your services and websites. With a beautiful web interface, various monitor types, and rich notification integrations, it offers a great alternative to Uptime Robot.

What is Uptime Kuma?

Uptime Kuma's standout features:

  • Monitor Types: HTTP(S), TCP, DNS, Ping, Docker Container, Steam Game Server
  • Notification Channels: Telegram, Discord, Slack, Email, PagerDuty, Webhook, and 90+ integrations
  • Status Page: Customizable status page
  • SSL Monitoring: Certificate expiration date tracking
  • Maintenance Window: Define planned maintenance windows
  • 2FA Support: Two-factor authentication
  • Multi-language: 40+ languages including English

Installation

hljs bash
docker run -d \
  --name uptime-kuma \
  --restart=always \
  -p 3001:3001 \
  -v uptime-kuma:/app/data \
  louislam/uptime-kuma:latest

After installation:

http://SERVER_IP:3001

Installation with Docker Compose

hljs yaml
# docker-compose.yml
version: '3.8'
services:
  uptime-kuma:
    image: louislam/uptime-kuma:latest
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "3001:3001"
    volumes:
      - uptime-kuma:/app/data
    security_opt:
      - no-new-privileges:true

volumes:
  uptime-kuma:
hljs bash
docker compose up -d

HTTPS with Nginx Reverse Proxy

hljs nginx
# /etc/nginx/sites-available/uptime.example.com
server {
    listen 80;
    server_name uptime.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name uptime.example.com;

    ssl_certificate /etc/letsencrypt/live/uptime.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/uptime.example.com/privkey.pem;

    location / {
        proxy_pass http://localhost: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;
        proxy_cache_bypass $http_upgrade;
    }
}
hljs bash
sudo ln -s /etc/nginx/sites-available/uptime.example.com /etc/nginx/sites-enabled/
sudo certbot --nginx -d uptime.example.com
sudo nginx -t && sudo systemctl reload nginx

Initial Setup

Create an admin account on first login:

  1. Set username and password
  2. Log in
  3. Add your first monitor with Add New Monitor

Monitor Types

HTTP(S) Monitor

For monitoring websites and API endpoints:

Monitor Type: HTTP(S)
Friendly Name: Homepage
URL: https://example.com
Heartbeat Interval: 60 seconds
Retries: 3
Accepted Status Codes: 200-299

Advanced HTTP settings:

hljs bash
# Keyword monitoring (search for specific text on page)
Monitor Type: HTTP(S) - Keyword
Keyword: "Welcome"

# JSON Query monitoring (API response check)
Monitor Type: HTTP(S) - JSON Query
JSON Path: $.status
Expected Value: ok

# Endpoint requiring Basic Auth
Authentication: Basic Auth
Username: api_user
Password: api_password

TCP Port Monitor

Monitor Type: TCP Port
Friendly Name: MySQL Database
Hostname: db.example.com
Port: 3306
Heartbeat Interval: 120 seconds

DNS Monitor

Monitor Type: DNS
Friendly Name: DNS Check
Hostname: example.com
Resolver Server: 8.8.8.8
DNS Resolve Type: A
Expected Value: 1.2.3.4

Ping Monitor

Monitor Type: Ping
Friendly Name: Server Ping
Hostname: 192.168.1.1
Heartbeat Interval: 60 seconds

Docker Container Monitor

hljs bash
# Monitor Docker container status
Monitor Type: Docker Container
Container Name / ID: nginx
Docker Host: /var/run/docker.sock

SSL Certificate Monitoring

Monitor Type: HTTP(S)
URL: https://example.com
# In SSL tab:
Enable SSL Certificate Expiry Notification: ON
Notify Before (days): 30

Notification Integrations

Telegram Notification

hljs bash
# 1. Create a bot from BotFather
# Set bot name and username with /newbot command
# Get Bot Token: 1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ

# 2. Get Chat ID
# Send a message to the bot, then:
curl https://api.telegram.org/bot<TOKEN>/getUpdates
# Note the "chat":{"id":123456789} value

Telegram settings in Uptime Kuma:

Notification Type: Telegram
Bot Token: 1234567890:ABCdefGHIjklMNOpqrSTUvwxYZ
Chat ID: 123456789
Message Thread ID: (optional, for group topics)

Discord Notification

hljs bash
# Create Webhook in Discord:
# Server Settings → Integrations → Webhooks → New Webhook
# Copy Webhook URL
Notification Type: Discord
Discord Webhook URL: https://discord.com/api/webhooks/...
Username: Uptime Kuma
Prefix: [ALERT]

Slack Notification

Notification Type: Slack
Slack Webhook URL: https://hooks.slack.com/services/...
Channel: #alerts
Username: Uptime Kuma
Icon Emoji: :warning:

Email (SMTP) Notification

Notification Type: Email (SMTP)
From Email: alerts@example.com
To Email: admin@example.com
SMTP Host: smtp.gmail.com
SMTP Port: 587
SMTP Username: alerts@example.com
SMTP Password: app-password
Security: STARTTLS

Webhook Notification

hljs bash
# Send notifications to any service with custom webhook
Notification Type: Webhook
Post URL: https://api.example.com/alerts
Content Type: application/json

# Example payload:
{
  "monitor": "{{monitorName}}",
  "status": "{{status}}",
  "message": "{{msg}}",
  "time": "{{time}}"
}

Creating a Status Page

New Status Page

  1. Status PagesNew Status Page
  2. Set page name and slug: status.example.com
  3. Add logo and title
  4. Add monitors to groups
  5. Save with Save

Status Page Customization

hljs bash
# Status Page settings:
Title: Service Status
Description: Real-time status of all our services
Theme: Auto (Light/Dark)
Custom CSS: (custom styles)
Footer Text: © 2024 Company Name

# Domain binding:
Custom Domain: status.example.com
# DNS: CNAME status.example.com → uptime.example.com

Incident Management

hljs bash
# Create incident on status page:
# Status Pages → Edit → Incidents → Create Incident
Title: Planned Maintenance
Content: Maintenance will be performed between 02:00-04:00.
Style: info / warning / danger

Maintenance Window

To avoid false alarms during planned maintenance:

Maintenance → Add Maintenance
Title: Weekly Maintenance
Strategy: Recurring
Start Time: Sunday 02:00
End Time: Sunday 04:00
Timezone: UTC
Affected Monitors: All monitors

Updating Uptime Kuma

hljs bash
# Update with Docker
docker stop uptime-kuma
docker rm uptime-kuma
docker pull louislam/uptime-kuma:latest

# Restart (data preserved in volume)
docker run -d \
  --name uptime-kuma \
  --restart=always \
  -p 3001:3001 \
  -v uptime-kuma:/app/data \
  louislam/uptime-kuma:latest

Backup

hljs bash
# Backup Uptime Kuma data
docker exec uptime-kuma tar -czf /tmp/backup.tar.gz /app/data
docker cp uptime-kuma:/tmp/backup.tar.gz ./uptime-kuma-backup-$(date +%Y%m%d).tar.gz

# Restore
docker cp ./uptime-kuma-backup.tar.gz uptime-kuma:/tmp/
docker exec uptime-kuma tar -xzf /tmp/backup.tar.gz -C /

You can monitor all services running on your REXE servers with Uptime Kuma. With Telegram notifications, you'll be instantly informed of any service outages.

Frequently Asked Questions

I can't access port 3001 after installing Uptime Kuma.

Open port 3001 in the firewall: 'ufw allow 3001/tcp'. Check that the container is running with 'docker ps | grep uptime-kuma'. If using Nginx reverse proxy, check the proxy_pass settings and SSL certificate.

Telegram notifications are not coming through.

Verify the bot token is correct. Run 'curl https://api.telegram.org/bot<TOKEN>/getUpdates' to verify the Chat ID. You must have sent at least one message to the bot. If using a group, add the bot to the group and make it an admin. Use the 'Test' button in Notification settings to send a test notification.

My HTTP monitor keeps showing 'down' but the site is working.

Check the Accepted Status Codes setting (default: 200-299). If your site returns 301/302 redirects, add those too. If there's an SSL certificate error, enable the 'Ignore TLS/SSL error' option. Increase the timeout. Verify that the site is accessible from the server where Uptime Kuma is running.

How do I connect a status page to a custom domain?

Enter your domain name in the 'Custom Domain' field in status page settings (e.g., status.example.com). Create a CNAME record in DNS: status.example.com → uptime.example.com. If using Nginx reverse proxy, add a new server block. Get an SSL certificate with Let's Encrypt.

I have many monitors in Uptime Kuma and experiencing performance issues.

Increase the heartbeat interval (120-300 seconds instead of 60). Disable unnecessary monitors. Allocate more resources to the Uptime Kuma container. The SQLite database can slow down as it grows; regularly clean up old records. Use the 'Settings → Database → Shrink Database' option.

How do I set up SSL certificate expiration notifications?

When creating or editing an HTTP(S) monitor, go to the 'SSL' tab. Enable the 'Enable SSL Certificate Expiry Notification' option. Set how many days in advance you want to be notified (e.g., 30 days). Make sure your notification channel (Telegram, email, etc.) is configured.

Related Articles

Network TrafficInbound GbpsOutbound Gbps