Uptime Kuma Monitoring Setup: The Complete Homelab Guide (2026)
Step-by-step Uptime Kuma installation with Docker Compose, advanced configuration, SSL, backup strategies, and common troubleshooting. Covers version 2.5.3.
Introduction
Monitoring is the backbone of any serious homelab. When you self-host services like Nextcloud, Pi-hole, or a media stack, you need to know the moment something goes down—not when a user complains. Uptime Kuma is a self-hosted, open-source monitoring tool that gives you a beautiful, modern dashboard for tracking HTTP(S), TCP, DNS, ICMP, and even game server status. It's the perfect replacement for cloud-based monitors like UptimeRobot, keeping all your data on your own hardware.
This guide walks you through a production-ready Uptime Kuma deployment using Docker Compose. We'll cover everything from prerequisites to advanced hardening. We're using version 2.5.3, the latest official release as of August 22, 2026. You'll learn how to set up persistent storage, configure a reverse proxy with SSL, automate backups, and solve the most common issues that trip up homelab administrators.
By the end, you'll have a monitoring solution that's always-on, private, and fully under your control. You'll also understand the architecture well enough to customize it for your specific needs. Let's get started.
Prerequisites
Before you begin, ensure your host meets the following requirements. Uptime Kuma is lightweight, but your monitoring frequency and the number of monitored endpoints will affect resource usage.
| Resource | Minimum | Recommended | Notes |
|---|---|---|---|
| CPU | 1 core | 2 cores | ARM64 and x86_64 are both supported. |
| RAM | 512 MB | 1 GB | Typical idle usage is under 300 MB. Actual usage depends on the number of monitors and push notifications. |
| Storage | 5 GB | 10 GB | The Docker image is ~300 MB. The SQLite database grows slowly but can expand with long-term history. |
| Software | Docker Engine 24+ & Docker Compose v2 | Latest stable | Older versions may work but are not officially tested with v2.5.3. |
| Network | Outbound access to monitored targets | Stable connection | The monitoring host must reach the IPs/ports you want to check. |
| Reverse Proxy (optional) | Caddy, Nginx, or Traefik | Recommended | Needed for SSL and a clean domain name. |
Important: Do not run Uptime Kuma as root if you can avoid it. Create a dedicated user for Docker commands. Run id -u && id -g on your host and verify against the image's documentation (default user in this image is node with UID 1000). Use these values in your .env file if needed.
Step-by-Step Installation
Step 1: Create Project Directory and Environment File
First, create a clean directory for Uptime Kuma. We'll keep all configuration files here.
mkdir -p ~/uptime-kuma && cd ~/uptime-kuma
Now, create a .env file to store your variables. This keeps secrets out of your docker-compose.yml and allows for easy updates. Never commit this file to Git.
cat > .env << 'EOF'
# Uptime Kuma version - check official GitHub releases before changing
UPTIME_KUMA_VERSION=2.5.3
# Timezone - use your local timezone (e.g., Europe/Berlin, America/New_York)
TZ=UTC
# Port for Uptime Kuma (host side)
UPTIME_KUMA_PORT=3001
# PUID and PGID - run 'id -u' and 'id -g' on your host to find these
PUID=1000
PGID=1000
EOF
Step 2: Create the Docker Compose File
Create the docker-compose.yml file. This defines the service, volume, and restart policy.
cat > docker-compose.yml << 'EOF'
services:
uptime-kuma:
image: louislam/uptime-kuma:${UPTIME_KUMA_VERSION:-latest}
container_name: uptime-kuma
restart: unless-stopped
ports:
- "${UPTIME_KUMA_PORT:-3001}:3001"
environment:
- TZ=${TZ:-UTC}
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
volumes:
- ./data:/app/data
EOF
Version Check: The image tag
${UPTIME_KUMA_VERSION:-latest}uses the version from your.envfile. If you omit it, it defaults tolatest. Check the official GitHub releases page before pinning a version — the version above may be outdated by now.
Step 3: Start the Container
Pull the image and start the container in detached mode.
docker compose up -d
Verify the container is running and healthy.
docker compose ps
You should see uptime-kuma with a status of running. If you see restarting, check the logs with docker compose logs uptime-kuma.
Step 4: Initial Web Setup
Open your browser and go to http://YOUR_SERVER_IP:3001. You'll see the initial setup screen. Create an administrator account with a strong password. After that, you'll be logged into the dashboard. The default interface is in English, but you can change the language in the top-right menu.
Step 5: Create Your First Monitor
Click "Add New Monitor." Choose a monitor type (HTTP(s), Ping, Port, etc.). For a simple web service check, select "HTTP(s)" and enter the URL of the service you want to monitor. Set a friendly name, like "Nextcloud Main Page." Leave the other settings at their defaults for now. Click "Save." Uptime Kuma will immediately start checking the endpoint every 60 seconds by default.
Step 6: Configure Notifications
To get alerts, click the bell icon in the top-right corner. Uptime Kuma supports dozens of notification channels: Email, Telegram, Discord, Slack, Webhooks, and more. For a homelab, a Telegram bot is a lightweight choice. Create a bot with @BotFather, get the token, and add it here. Test the notification to ensure it works.
Step 7: Set Up Status Pages
Uptime Kuma can generate public status pages. Go to "Status Pages" in the left sidebar, click "New Status Page," and give it a slug. Then, add the monitors you want to display. You can enable or disable the page publicly. This is great for sharing uptime stats with family or users.
Step 8: Enable Backup
The entire Uptime Kuma state—monitors, settings, and history—is stored in a SQLite database inside the ./data directory. To back up, you can simply copy this directory while the container is running, but for a consistent backup, use the built-in backup feature: go to "Settings" > "Backup" and click "Download Backup." This creates a JSON file you can store elsewhere.
Step 9: Update Uptime Kuma
To update, pull the new image and recreate the container. First, check the official GitHub releases for a new version. Then, update the .env file with the new version string.
cd ~/uptime-kuma && docker compose pull && docker compose up -d
This will recreate the container with the new image while preserving your data in the volume.
Step 10: Verify Data Persistence
Ensure your data survives container recreation. Run the following command to see the volume mount.
docker inspect uptime-kuma | grep -A 5 "Mounts"
You should see a bind mount from ~/uptime-kuma/data to /app/data. If you delete the container with docker compose down (without -v), your data remains safe.
Advanced Configuration & Hardening
Reverse Proxy & SSL
Exposing Uptime Kuma directly on port 3001 is fine for local use, but for remote access, use a reverse proxy with SSL. Caddy is the simplest choice because it auto-provisions Let's Encrypt certificates. Here's a Caddyfile example:
status.example.com {
reverse_proxy uptime-kuma:3001
}
With Docker Compose, you can add Caddy as another service in the same network. For Nginx or Traefik, configure a proxy pass to http://uptime-kuma:3001. Ensure your proxy network is shared with the Uptime Kuma container.
Backup Automation
Instead of manual downloads, automate backups with a cron job. The database is a single file: ./data/kuma.db. A simple rsync or tar command can snapshot the entire data directory. Here's a daily cron entry:
0 3 * * * tar -czf /backups/uptime-kuma/$(date +\%Y-\%m-\%d).tar.gz -C ~/uptime-kuma data
Optional Hardening
Warning: The following settings are advanced and may break the container if applied without testing. Adapt them to your environment and verify the container still works after each change.
You can add security hardening to the docker-compose.yml under the service definition. This includes making the filesystem read-only and dropping Linux capabilities.
services:
uptime-kuma:
image: louislam/uptime-kuma:${UPTIME_KUMA_VERSION:-latest}
container_name: uptime-kuma
restart: unless-stopped
ports:
- "${UPTIME_KUMA_PORT:-3001}:3001"
environment:
- TZ=${TZ:-UTC}
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
volumes:
- ./data:/app/data
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
If this breaks startup, check the logs. The container may need write access to /app/data (which is a volume, so it's fine) or /tmp (which we mapped to tmpfs). Adjust cap_drop if you need specific capabilities for ICMP ping monitoring (add NET_RAW back if needed).
Troubleshooting Common Issues
| Error | Cause | Solution |
|---|---|---|
| Container restarts in a loop | Permission issues on the data directory |
Run chown -R $(id -u):$(id -g) ~/uptime-kuma/data and ensure PUID/PGID match your host user. |
Error: listen EADDRINUSE: address already in use :::3001 |
Port 3001 is already taken | Change UPTIME_KUMA_PORT in .env to another port (e.g., 3002) and re-run docker compose up -d. |
| Monitors show "down" but the service is accessible | Firewall or proxy blocking the monitoring request | Check your firewall rules. If using a reverse proxy, ensure the proxy's network is reachable from the Uptime Kuma container. Test with curl from inside the container. |
| Notifications not sending | Wrong webhook URL or API token | Double-check the token/URL in the notification settings. Use the "Test" button in the notification configuration to isolate the issue. |
| Slow dashboard after months of use | SQLite database fragmentation | Stop the container, run sqlite3 data/kuma.db "VACUUM;", then start it again. This compacts the database file. |
| Can't update to a new version | Docker cache | Run docker compose build --no-cache or docker compose pull --ignore-pull-failures and then recreate the container. |
Conclusion & FAQ
You now have a fully functional Uptime Kuma instance monitoring your homelab. This setup is robust, persistent, and ready for production use. The combination of Docker Compose, a .env file, and a reverse proxy gives you a clean architecture that's easy to maintain and upgrade. Remember to check the official GitHub releases regularly for updates.
FAQ
1. Can I monitor services on my LAN without exposing them to the internet?
Yes. Uptime Kuma runs on your local network, so it can reach internal IPs and hostnames. Just ensure the host running Docker can route to those IPs. You don't need to open any inbound ports on your router for the monitored services themselves.
2. Does Uptime Kuma send alerts via email?
Yes, it supports SMTP email notifications. You'll need to configure your SMTP server settings (host, port, username, password) in the notification settings. Many homelab users prefer Telegram or Discord for faster, less spammy alerts.
3. How often can Uptime Kuma check a service?
The minimum interval is 20 seconds. For most homelab services, a 60-second interval is sufficient. Frequent checks increase load on both the monitored service and the Uptime Kuma host. Adjust the interval per monitor based on criticality.
4. Is it possible to monitor Docker containers directly?
Not natively. Uptime Kuma monitors network endpoints (HTTP, TCP, etc.). To monitor a container, expose its port to the host or use a Docker network plugin that allows Uptime Kuma to reach the container's IP directly. Alternatively, use a tool like docker events with a custom script for container-level health.
5. Can I share my status page publicly?
Yes. When creating a Status Page, you can set it to "Public" visibility. It will be accessible via a unique URL. You can also embed it in an iframe on your website. Be mindful of what you expose—public status pages reveal your infrastructure's uptime patterns.