Uptime Kuma is a self-hosted monitoring tool: it checks your websites and services and alerts you when something goes down. It's one container, one volume, and it makes a perfect first app.
Prerequisites
- A server with Docker Engine and the Compose plugin installed (the Docker Compose guide covers this)
- An SSH login as a non-root user with sudo — from the security guide
1. Create the project folder
Run on the server, over your SSH session:
sudo mkdir -p /opt/uptime-kuma
cd /opt/uptime-kuma
2. Write the Compose file
Still on the server, create docker-compose.yml:
services:
uptime-kuma:
image: louislam/uptime-kuma:2
container_name: uptime-kuma
volumes:
- uptime-kuma-data:/app/data
# Bound to localhost only — reached through an SSH tunnel (step 4)
ports:
- "127.0.0.1:3001:3001"
restart: unless-stopped
volumes:
uptime-kuma-data:
"3001:3001" mapping publishes the app on every network interface, visible to the whole internet — including bots that probe for exposed dashboards. Binding to 127.0.0.1 keeps it private to the server itself. Note that Docker manages its own firewall rules ahead of ufw, so don't rely on ufw alone to block published ports.3. Start the container
sudo docker compose up -d
sudo docker compose ps # expect "running"
sudo docker compose logs -f uptime-kuma # Ctrl+C to exit; logs keep it running
4. First access via SSH tunnel
Run this on your own computer (not the server), then open http://localhost:3001:
# On your local machine — forwards local port 3001 to the server
ssh -L 3001:localhost:3001 your-user@your-server-ip
The setup wizard appears. Create your admin account — there are no default credentials.
5. Updates
cd /opt/uptime-kuma
sudo docker compose pull
sudo docker compose up -d # recreates the container if the image changed
Your data lives in the named volume, so updates never touch it. Before major version jumps (for example v2 to a future v3), read the project's release notes — some upgrades run one-way data migrations.
6. Backups
# Stop the app so the database file is consistent, then back up the volume
sudo docker compose stop
sudo tar czf uptime-kuma-backup-$(date +%F).tar.gz -C /var/lib/docker/volumes/uptime-kuma_uptime-kuma-data/_data .
sudo docker compose start
Move the archive somewhere off the server. Include this folder in the automated routine from the backups guide.
Troubleshooting
- Nothing at localhost:3001 after tunneling: check
sudo docker compose pson the server — is the container running? Readsudo docker compose logs uptime-kumafor the first error line. - Port already in use: something else holds 3001 locally or on the server. Change the left side of the port mapping (for example
"127.0.0.1:3002:3001") and tunnel to 3002 instead. - Permission denied on the volume directory: don't fight Docker's internal user by chowning volume files — stop the stack and let the container recreate what it needs, or check the project's documentation for the expected PUID/PGID handling.
Official documentation: Uptime Kuma wiki · Image tags: Docker Tags