How to install Uptime Kuma 2 with Docker Compose and HTTPS
Install Uptime Kuma 2 with Docker Compose behind Caddy, secure the admin account with 2FA, set up monitors, alerts and status pages, then back up and update.
- Beginner
- 25 min read
- Updated
Tested on: Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12, Debian 13
This guide is not available in your language yet, so it is shown in English.
On this page
- Prerequisites
- Step 1 — Get the official Compose file
- Step 2 — Start Uptime Kuma
- Step 3 — Serve Uptime Kuma over HTTPS with Caddy
- Step 4 — Choose a database and create the admin account
- Step 5 — Add monitors, notifications and a status page
- Back up and restore
- Update Uptime Kuma
- Troubleshooting
- A monitor shows DOWN but the site works in your browser
- You forgot the admin password
- The page loads but stays on a spinner or keeps reconnecting
- SQLite errors such as database is locked or a corrupted database
- IPv6 monitors always fail
- Next steps
Uptime Kuma is a self-hosted monitoring tool with a clean web interface. It checks websites, APIs, TCP ports, DNS records, ping targets and more at a fixed interval, sends alerts through dozens of notification services when something goes down, and can publish public status pages for your users. Version 2 is the current major release.
This guide installs Uptime Kuma 2 with the project's official Docker Compose file, publishes the web interface only on 127.0.0.1, and serves it over HTTPS with Caddy, which passes the WebSocket connection the interface depends on. You then choose a database, create the admin account with two-factor authentication, add your first monitors, notifications and a status page, and learn how to back up, update and troubleshoot the installation.
Prerequisites
- A server running Ubuntu 24.04 LTS, Ubuntu 26.04 LTS, Debian 12 or Debian 13. The steps work on a HyperDC Linux VPS, VDS or dedicated server with root access.
- A non-root user with
sudorights: see Secure a new Linux server and Set up SSH keys. - Docker Engine with the Compose plugin: Install Docker on Ubuntu or Install Docker on Debian.
- A domain name such as
status.example.comwith an A (and optionally AAAA) record pointing at the server, and Caddy installed as in Caddy as a reverse proxy. - A local disk for the data folder. The project states that network file systems such as NFS are not supported.
| Resource | Minimum (official) | Suggested starting point |
|---|---|---|
| CPU | Not published | 1 vCPU |
| RAM | Not published | 1 GB |
| Disk | Not published | 10 GB, more if you keep long history |
The project does not publish minimum requirements for the Docker image. The right-hand column is a conservative starting point for a few dozen monitors, not a benchmark. The full image includes an embedded MariaDB and Chromium; the 2-slim tag leaves both out and is a few hundred megabytes smaller.
Step 1 — Get the official Compose file
Create the app folder and download the Compose file that the project's README recommends:
sudo mkdir -p /opt/uptime-kuma
sudo chown $USER:$USER /opt/uptime-kuma
cd /opt/uptime-kuma
curl -fsSL -o compose.yaml https://raw.githubusercontent.com/louislam/uptime-kuma/master/compose.yaml
cat compose.yamlThe file runs the louislam/uptime-kuma:2 image, keeps all data in ./data (mounted at /app/data), and publishes port 3001 on every address of the server. Docker-published ports bypass ufw, so change the port line to listen on loopback only. Open the file with nano compose.yaml and make it look like this:
services:
uptime-kuma:
image: louislam/uptime-kuma:2
restart: unless-stopped
volumes:
- ./data:/app/data
ports:
- "127.0.0.1:3001:3001"About the image tag: 2 follows the newest 2.x release and is the tag the project recommends. Exact tags such as 2.5.5 pin a version, 2-slim is the smaller variant, and latest is deprecated and still points to version 1.
Step 2 — Start Uptime Kuma
docker compose up -d
docker compose ps
docker compose logs --tail 30
curl -I http://127.0.0.1:3001docker compose ps shows the container as running, the logs show no errors, and curl answers with an HTTP status line (a redirect to the setup page is normal at this point). The interface is not yet reachable from the internet, which is intended.
Step 3 — Serve Uptime Kuma over HTTPS with Caddy
Add a site block to /etc/caddy/Caddyfile. Caddy's reverse_proxy upgrades WebSocket connections automatically, so no extra headers are needed:
status.example.com {
reverse_proxy 127.0.0.1:3001
}Reload Caddy and allow only SSH and web traffic through the firewall:
sudo systemctl reload caddy
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
curl -I https://status.example.comThe last command returns a response over a valid certificate. If you use Nginx instead (Nginx with Certbot), add the Upgrade and Connection headers for WebSockets as shown in the project's reverse proxy wiki page; Traefik handles WebSockets on its own.
Step 4 — Choose a database and create the admin account
Open https://status.example.com straight away; until you finish setup, anyone who finds the address could claim the admin account.
- The first screen asks which database to use. SQLite is described as a simple database file recommended for small-scale deployments, and it is the right choice for most single-server setups. Embedded MariaDB runs a MariaDB server inside the same container (full image only). MariaDB/MySQL connects to an external database server.
- Create the admin account with a unique user name and a long password from your password manager.
You land on the empty dashboard. Then harden the account:
- Open Settings, then Security, and use Set Up 2FA under Two Factor Authentication. Scan the QR code with an authenticator app and confirm with a code.
- Open Settings, then Reverse Proxy, and under HTTP Headers set Trust Proxy to Yes. Uptime Kuma then logs the real visitor IP addresses sent by Caddy instead of
127.0.0.1. Only do this when the app is reachable solely through your proxy, as it is here.
Step 5 — Add monitors, notifications and a status page
Notifications first. Open Settings, then Notifications, and click Setup Notification. Pick a service (email via SMTP, Telegram, Discord, Slack, Microsoft Teams, ntfy, a webhook and many more), fill in its details and use Test before saving. Tick Default enabled to attach it to new monitors automatically. For email alerts, enter your relay's host name (for example smtp.example.com), port 587 with STARTTLS security, your SMTP user and password, and the sender and recipient addresses.
Then monitors. Click Add New Monitor and choose a type:
- HTTP(s) checks that a URL answers with a success status; HTTP(s) - Keyword also looks for a word in the response.
- TCP Port, Ping and DNS check services that do not speak HTTP.
- Push waits for your own job (for example a backup script) to call a URL, and alerts when the call does not arrive in time.
Set the Heartbeat Interval (60 seconds is a sensible default), a few Retries to avoid alerts for one-off blips, and save. HTTPS monitors also warn you before certificates expire when you enable the certificate expiry notification.
Finally a status page. Open Status Pages, click New Status Page, enter a name and a slug, and add the monitors you want to show. The page is public at https://status.example.com/status/your-slug. It shows only the monitors you select, and you can schedule Maintenance windows so planned work does not appear as an outage.
Back up and restore
Everything lives in the data folder: the SQLite database (or the embedded MariaDB files), uploaded logos and settings. Version 2 removed the old JSON backup feature, and the project's migration guide names backing up the data directory as the only supported method. Stop the container so the database files are consistent, archive the folder and the Compose file, and start it again:
sudo mkdir -p /opt/backups
cd /opt/uptime-kuma
docker compose stop
sudo tar -czf /opt/backups/uptime-kuma-$(date +%F).tar.gz -C /opt/uptime-kuma compose.yaml data
docker compose startMonitoring pauses for the few seconds the backup takes. Schedule it with cron at a quiet time and copy the archives off the server.
To restore, stop the stack, move the current data aside, unpack the archive and start again:
cd /opt/uptime-kuma
docker compose down
sudo mv data data.old
sudo tar -xzf /opt/backups/uptime-kuma-2026-10-09.tar.gz -C /opt/uptime-kuma
docker compose up -dDelete data.old once you have checked that the restored dashboard shows your monitors.
Update Uptime Kuma
Read the release notes first and take a backup as shown above. Then pull the new image and recreate the container, as the project's update guide describes:
cd /opt/uptime-kuma
docker compose pull
docker compose up -d --force-recreate
docker compose logs -fSome updates migrate the database on first start. The migration from version 1 to version 2 rewrites the heartbeat table and can take minutes or, on slow hardware with a lot of history, hours. Watch the logs (Ctrl+C stops following them) and do not stop the container during a migration; if it is interrupted, restore the backup and try again.
Troubleshooting
A monitor shows DOWN but the site works in your browser
The check runs from inside the container, so Docker networking, DNS or a firewall on the target can produce a different result. The project's troubleshooting page suggests testing from inside the container:
docker compose exec uptime-kuma bash
apt update && apt --yes install curl
curl -I https://www.example.comType exit to leave the container shell. Also remember that localhost and 127.0.0.1 inside a monitor point at the container itself, not at the host; monitor the public HTTPS address instead.
You forgot the admin password
Reset it from the command line as the project documents. Open a shell in the container, run the reset script and enter a new password when asked:
docker compose exec uptime-kuma bash
npm run reset-passwordThe page loads but stays on a spinner or keeps reconnecting
The browser could not open the WebSocket connection. Caddy handles this automatically; with Nginx, add proxy_http_version 1.1 and the Upgrade and Connection headers. Also check that a CDN or firewall in front of the site allows WebSockets.
SQLite errors such as database is locked or a corrupted database
Usually the data folder sits on a network file system, which the project does not support. Move data to a local disk, restore the most recent backup if the database is damaged, and keep one Uptime Kuma container per data folder.
IPv6 monitors always fail
Docker networks have no IPv6 by default, so the container cannot reach IPv6-only targets. The project's troubleshooting page shows how to add a Compose network with enable_ipv6: true, or you can monitor the target's IPv4 address.
Next steps
- Learn the file format behind this setup in Docker Compose basics.
- Put other apps behind HTTPS the same way with Caddy.
- Harden the server itself with Secure a new Linux server.
- Browse more tools you can run yourself on the self-hosted apps page.
- Read the Uptime Kuma wiki for all monitor types and settings.
Frequently asked questions
Should I use the latest tag for Uptime Kuma?
No. The project's Docker tag list marks latest as deprecated and says it still points to version 1. Use the 2 tag, which follows the newest 2.x release, or pin an exact 2.x.y tag.
Can Uptime Kuma monitor the server it runs on?
It can check services on the same server, but it cannot tell you when that whole server or its network is down, because it goes down too. Run Uptime Kuma on a different server or location from the services you care about most.
SQLite or MariaDB for Uptime Kuma 2?
The setup screen describes SQLite as a simple database file recommended for small-scale deployments. The full Docker image also offers an embedded MariaDB, and you can connect an external MariaDB or MySQL server. Moving an existing SQLite database to MariaDB later is not supported by the maintainers.
Can I store the data folder on NFS?
No. The project states that network file systems such as NFS are not supported, because SQLite needs reliable POSIX file locks. Keep /app/data on a local disk or local Docker volume.
Is there a built-in backup button in version 2?
No. The JSON backup and restore feature was removed in version 2. The migration guide says backing up the data directory is the only supported backup method.
Sources
- github.com/louislam/uptime-kuma
- raw.githubusercontent.com/louislam/uptime-kuma/master/compose.yaml
- github.com/louislam/uptime-kuma/wiki/Docker-Tags
- github.com/louislam/uptime-kuma/wiki/%F0%9F%94%A7-How-to-Install
- github.com/louislam/uptime-kuma/wiki/Migration-From-v1-To-v2
- github.com/louislam/uptime-kuma/wiki/%F0%9F%86%99-How-to-Update
- github.com/louislam/uptime-kuma/wiki/Reverse-Proxy
- github.com/louislam/uptime-kuma/wiki/Environment-Variables
- github.com/louislam/uptime-kuma/wiki/Reset-Password-via-CLI
- github.com/louislam/uptime-kuma/wiki/Troubleshooting
- github.com/louislam/uptime-kuma/releases/latest