LinuxcontainersTested on real hardware

Uptime Kuma — Docker Compose Install

Deploy Uptime Kuma monitoring on Linux with Docker Compose. Persists data to a named volume and exposes the web UI on port 3001. Covers notification setup and monitor types.

Distrosubuntu, debian, fedora, opensuse
Shellyaml
Updated
Compose file
yaml
#!/usr/bin/env bash
# Uptime Kuma — self-hosted uptime monitor — Docker Compose install.
# Image: louislam/uptime-kuma:2  (major-version pin, gets minor updates)
# Docs: https://github.com/louislam/uptime-kuma/wiki
set -euo pipefail

INSTALL_DIR="/opt/uptime-kuma"
HOST_PORT=3001

mkdir -p "${INSTALL_DIR}"
cd "${INSTALL_DIR}"

cat > docker-compose.yml <<EOF
services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    container_name: uptime-kuma
    ports:
      - "${HOST_PORT}:3001"
    volumes:
      - uptime-kuma:/app/data
    restart: unless-stopped

volumes:
  uptime-kuma:
EOF

docker compose up -d

echo ""
echo "Uptime Kuma is running at: http://$(hostname -I | awk '{print $1}'):${HOST_PORT}"
echo "Create your admin account on first visit."

What this does

Starts Uptime Kuma in a Docker container with a named volume so monitor history and settings persist across container restarts and updates. Uses the :2 major-version tag so docker compose pull delivers minor updates without a surprise major-version change.

Everything after this is configured through the web UI — no config files.

Why this approach

Uptime Kuma gives you a self-hosted status dashboard for everything in your lab — Plex, Home Assistant, Proxmox nodes, your router, external websites — with alerts to Telegram, Discord, email, or Ntfy when something goes down. The alternative is either knowing about outages because a family member tells you something isn’t working, or paying for an external monitoring service that polls your services from the internet. Uptime Kuma polls from inside your network, so it can reach LAN-only services that a cloud monitor can’t.

The named volume for data persistence is the single most important configuration decision in the compose file. Uptime Kuma stores its SQLite database — all your monitors, uptime history, and notification settings — in that volume. Without it, every container restart would start fresh. Using a named volume (rather than a bind mount) means Docker manages the data lifecycle, and the data survives docker compose down and docker compose up cycles automatically.

The :2 major-version pin (rather than :latest) is a deliberate choice for a monitoring service that’s supposed to always be running. :latest might pull a major version with breaking changes the next time you run docker compose pull. Pinning to :2 gets minor updates and patches within v2 automatically, while protecting against a v3 release changing the database schema or configuration format in a way that breaks your running instance.

Prerequisites

First-time setup

  1. Open http://SERVER-IP:3001
  2. Create an admin account (first account only — subsequent sign-up is disabled by default)
  3. Add monitors via Add New Monitor in the sidebar

Monitor types quick-reference

Type Use for Key field
HTTP(s) Web UIs, APIs URL + expected status code (200)
TCP Port Non-HTTP services (SSH, SMB) host:port
Ping Hosts with no open ports hostname or IP
DNS Domain resolution domain + expected IP
Docker Container Containers on the same host mount the Docker socket (see below)
Push Cron jobs that should check in receives a GET to a unique push URL

Monitor Docker containers directly (optional)

Mount the Docker socket so Uptime Kuma can query container health:

services:
  uptime-kuma:
    image: louislam/uptime-kuma:2
    volumes:
      - uptime-kuma:/app/data
      - /var/run/docker.sock:/var/run/docker.sock:ro  # add this

Then add monitors of type Docker Container, selecting the container name from the dropdown.

Set up notifications

Settings → Notifications → Setup Notification → choose a provider:

Provider What you need
Telegram Bot token + chat ID
Discord Webhook URL
Email (SMTP) SMTP server, user, password
ntfy ntfy server URL + topic
Gotify Server URL + app token
Pushover API token + user key

After saving, test with the Test button, then enable the notification on individual monitors or set it as the default for all new monitors.

Create a status page

Dashboard → Status PagesNew Status Page. Choose a slug (URL path), select monitors to include, and publish. Share the URL http://SERVER-IP:3001/status/your-slug with family or teammates.

Upgrade Uptime Kuma

cd /opt/uptime-kuma
docker compose pull
docker compose up -d

The named volume retains all monitor history and settings.

Fedora / openSUSE

Same compose file works on any Linux with Docker. On openSUSE with firewalld:

sudo firewall-cmd --permanent --add-port=3001/tcp
sudo firewall-cmd --reload

macOS (Docker Desktop)

The compose file works with Docker Desktop on macOS. The Docker socket path is /var/run/docker.sock — same as Linux. Access via http://localhost:3001 or the machine’s LAN IP.

Windows (Docker Desktop with WSL2)

Works with Docker Desktop on Windows. Port 3001 is accessible at http://localhost:3001. The Docker socket path in WSL2 is /var/run/docker.sock when accessed from inside a WSL2 container.