Get your free server today! View Plans →
Home Plans Blog About Contact Panel Join Discord
Guides

How to self-host a status page with Uptime Kuma

Run your own monitoring with Uptime Kuma. This guide covers installing it with Docker or Node, watching sites and game servers, wiring up Discord and email alerts, publishing a status page, and securing it behind Nginx with HTTPS.

How to self-host a status page with Uptime Kuma

By the end of this guide you'll have Uptime Kuma running on your own server, watching your websites and game servers around the clock, pinging you on Discord the moment something goes down, and showing a clean public status page anyone can check. This is for anyone who runs a site, a bot, or a game server and is tired of hearing about outages from their players first. You don't need much Linux experience. If you can SSH in and edit a file, you can do this.

What Uptime Kuma actually does

Uptime Kuma is a self-hosted monitoring tool. You point it at the things you care about, a website URL, a game server port, a host you want to ping, and it checks each one on a schedule. When a check fails, it records the downtime and fires off a notification. When the thing recovers, it tells you that too.

It does a few jobs that you'd otherwise pay a monitoring service for:

Because it runs on your own box, your monitoring data stays with you, and you can watch internal services that a public service could never reach. One thing to keep in mind: run it somewhere other than the server you're monitoring. If Kuma lives on the same machine as your website and that machine falls over, your monitor goes down with it. A small separate VPS is the usual home for it.

Before you start

You'll need a Linux server you can reach over SSH with sudo access. Almost any small VPS handles Kuma fine, since it's light on resources. The examples use Ubuntu or Debian. We recommend the Docker route, because it bundles everything and updates are painless. The Node route is there if you'd rather not use Docker.

Step 1: Install with Docker (the easy way)

If you don't have Docker yet, the official script is the fastest way to get it:

curl -fsSL https://get.docker.com | sudo sh

Check it landed:

docker --version

You should see something like Docker version 27.x.x. Now create a folder to hold Kuma's data and start the container:

sudo docker run -d \
  --restart=unless-stopped \
  -p 3001:3001 \
  -v uptime-kuma:/app/data \
  --name uptime-kuma \
  louislam/uptime-kuma:1

Here's what each part means. The -d runs it in the background. --restart=unless-stopped brings the container back after a reboot or a crash, which is exactly what you want for a monitor. -p 3001:3001 exposes the web interface on port 3001. The -v uptime-kuma:/app/data stores the database in a named volume, so your monitors and history survive container updates.

After a few seconds, confirm it's alive:

sudo docker ps

You should see the uptime-kuma container with a status of Up. If you'd rather manage it with a file you can version and reuse, use Docker Compose instead. Create docker-compose.yml:

services:
  uptime-kuma:
    image: louislam/uptime-kuma:1
    container_name: uptime-kuma
    restart: unless-stopped
    ports:
      - "3001:3001"
    volumes:
      - uptime-kuma:/app/data

volumes:
  uptime-kuma:

Then bring it up:

sudo docker compose up -d

Step 2: Install with Node (the alternative)

Prefer to skip Docker? Kuma runs directly on Node. You'll need Node 18 or newer and git. On Ubuntu:

sudo apt update
sudo apt install -y git nodejs npm

Check the Node version with node -v. If your distro ships an old Node, install a current one from NodeSource first. Then clone and set it up:

git clone https://github.com/louislam/uptime-kuma.git
cd uptime-kuma
npm run setup

It listens on port 3001 by default. To keep it running after you log out and restart it on boot, use a process manager like pm2:

sudo npm install -g pm2
pm2 start server/server.js --name uptime-kuma
pm2 save
pm2 startup

The Docker path is simpler to update later, so most people land there. From here on, both routes look the same, since you're working in the web interface.

Step 3: First run and the admin account

Open a browser and go to your server's address on port 3001:

http://YOUR_SERVER_IP:3001

The first time you load it, Kuma shows a setup screen. Pick a username and a strong password and submit. That account is your admin login. There's no default password and no email confirmation, the first account you make is the one in charge, so choose a real password here. If port 3001 doesn't load, your firewall is probably blocking it. On a server with UFW:

sudo ufw allow 3001/tcp

We'll lock this behind a domain and HTTPS later, so opening 3001 now is just to get you in.

Step 4: Add your first monitors

This is the part that does the actual work. A monitor is one thing you want watched. Click Add New Monitor and you'll see a Monitor Type dropdown. The type decides how Kuma checks. Three cover most needs.

An HTTP monitor for a website

Choose HTTP(s) for any website or web app. Fill in:

Kuma counts a 2xx or 3xx response as up. If your site returns a 500 or times out, that's a fail. Under the advanced options you can also tell it to treat certain status codes as healthy, which is useful for endpoints that return a 401 on purpose.

A TCP port monitor for a game server

A game server doesn't speak HTTP, so checking a URL is pointless. Instead, check whether its port is open and accepting connections. Choose TCP Port and enter:

If the port accepts a connection, the monitor is up. That's a solid signal the server process is alive and reachable. A closed port almost always means a crashed or stopped server. For Minecraft specifically, Kuma also has a dedicated game type that reads the player count, which is worth trying.

A ping monitor for a whole host

If you just want to know a machine is online and reachable, choose Ping and enter the hostname or IP. Kuma sends ICMP echo requests, the same thing the ping command does. It's the lightest check and a good catch-all for "is the box up at all". Some networks block ICMP, in which case a ping monitor reads as down even when the host is fine. If that happens, fall back to a TCP check on a port you know is open.

Save each monitor and Kuma starts checking right away. Within a minute you'll see green heartbeat bars filling in and a response time graph building up.

Step 5: Set up notifications

A monitor that no one watches is half a tool. Notifications are what make Kuma useful at 3am. Go to Settings, then Notifications, then Setup Notification.

Discord

Discord is the easiest and the one we reach for most. First make a webhook in Discord: open your server, go to Server Settings, then Integrations, then Webhooks, and create one pointed at the channel you want alerts in. Copy its URL. Back in Kuma, pick Discord as the notification type, paste the webhook URL, give it a name, and hit Test. A test message should appear in your channel within a second or two. Save it.

Email (SMTP)

For email, choose Email (SMTP) and fill in your mail provider's SMTP host, port, and login. A typical setup with a provider that uses TLS looks like host smtp.yourprovider.com, port 587, with your username and an app password. Put the address you want alerts sent to in the "To" field. Send a test before saving, since a wrong port or a blocked login is the usual snag.

Telegram

For Telegram, message @BotFather to create a bot and copy the token. Get your chat ID by messaging your new bot and visiting its getUpdates URL, or by using a chat ID bot. In Kuma, pick Telegram, paste the bot token and chat ID, and test.

One step people miss: creating a notification doesn't attach it to anything. You either tick the box to apply it as a default for all monitors when you set it up, or you edit each monitor and enable the notification there. If your alerts never fire, this is almost always why.

Step 6: Build a public status page

The status page is the front you show the world. Click Status Pages in the top menu, then New Status Page. Give it a name and a slug (the slug becomes the URL, like /status/main). On the editor screen you can:

You choose exactly which monitors appear, so internal checks stay hidden while public services show. Hit Save, and the page is live at http://YOUR_SERVER_IP:3001/status/main. Visitors don't need an account. Share this link so players check the status page first instead of asking if the server is down.

Step 7: Put it behind Nginx with SSL

Right now you reach Kuma on a raw IP and port over plain HTTP. The proper setup is a real domain with HTTPS. Point a DNS A record (say status.yourdomain.com) at your server's IP, then install Nginx:

sudo apt install nginx -y

Create a server block at /etc/nginx/sites-available/uptime-kuma:

server {
    listen 80;
    server_name status.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_http_version 1.1;
        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_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Those last two Upgrade lines matter. Kuma uses WebSockets to push live updates, and without them the dashboard loads but never refreshes. Enable the site, test, and reload:

sudo ln -s /etc/nginx/sites-available/uptime-kuma /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Now add a free certificate with Certbot:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d status.yourdomain.com

Certbot fetches the certificate and rewrites your server block to serve HTTPS, with a redirect from http. Once it's done, close the firewall hole on 3001 so the only way in is through Nginx:

sudo ufw delete allow 3001/tcp

Your status page now lives at https://status.yourdomain.com with a padlock.

Keeping it updated

New versions bring fixes and monitor types, so update every so often. With Docker it's three commands. Because your data lives in the named volume, nothing is lost:

sudo docker pull louislam/uptime-kuma:1
sudo docker stop uptime-kuma
sudo docker rm uptime-kuma

Then run the same docker run command from Step 1 again. If you used Compose, it's just sudo docker compose pull followed by sudo docker compose up -d. Before a big version jump, snapshot the VPS or copy the data volume so you have a safety net.

Troubleshooting

The container won't start

First read the logs, they almost always name the cause:

sudo docker logs uptime-kuma

The most common culprit is a port clash. If something else already uses 3001, the container exits. Check with sudo ss -tlnp | grep 3001. Either stop the other service or map Kuma to a different host port, like -p 3002:3001, and proxy to that. If you mounted a host folder instead of a named volume, make sure the container can write to it.

Notifications aren't firing

This is the number one support question, and it's nearly always one of two things. First, the notification was created but not attached to the monitor. Open the monitor, scroll to its notification list, and tick the box for the channel you set up. Second, the channel itself is misconfigured. Go back to Settings, Notifications, and hit Test on the notification. If the test fails, the problem is the webhook URL, the SMTP login, or the bot token, not Kuma. A Discord webhook that was deleted on the Discord side will silently stop working, so recreate it if the test fails there.

The dashboard loads but never updates

If the page shows but heartbeats freeze and never refresh, the WebSocket connection isn't getting through your reverse proxy. Confirm you added proxy_http_version 1.1 and the Upgrade and Connection headers shown in Step 7, then sudo nginx -t and reload. If Cloudflare sits in front, make sure its WebSocket support is on.

A monitor shows down but the service is clearly up

For a ping monitor, check whether the network blocks ICMP, since plenty of hosts drop ping while serving traffic fine. Switch to a TCP check on a known-open port. For an HTTP monitor, a self-signed or expired certificate fails the check, so either fix the cert or toggle "Ignore TLS Error" in the advanced options. For a TCP game server monitor, double-check the port number and that the server's firewall allows connections from your monitoring box.

You can't reach the page after adding SSL

If the site times out after Certbot, your firewall may still block 443. Run sudo ufw allow 'Nginx Full' to open 80 and 443. Also confirm your DNS A record actually points at the server, since Certbot can only issue a cert once the domain resolves to your IP.

Wrapping up

You now have a monitor that watches your sites and game servers, alerts you the second they fall over, and shows a public status page on your own domain over HTTPS. The pattern that works best is simple: run Kuma on a small separate server, add a monitor for everything you'd be embarrassed to find down, wire up at least one notification, and attach it to every monitor. Keep it updated and the data volume backed up, and you've got monitoring that costs almost nothing and saves you from learning about outages the hard way.

Common questions

Should I run Uptime Kuma with Docker or Node?

Docker is the easier choice for most people, since it bundles everything and updates are just a pull and restart with your data kept in a named volume. Use the Node install only if you cannot run Docker on your host. Either way you end up working in the same web interface.

How do I monitor a game server that does not use HTTP?

Use a TCP Port monitor instead of an HTTP one. Enter the server's IP or domain and the game's port, for example 25565 for a Minecraft Java server. If the port accepts a connection the monitor reads as up, which is a reliable sign the server process is alive and reachable.

Why aren't my Uptime Kuma notifications firing?

Almost always one of two reasons. The notification was created but never attached to the monitor, so open the monitor and tick its box. Or the channel itself is wrong, so go to Settings then Notifications and hit Test. A deleted Discord webhook or a bad SMTP login will fail the test.

The dashboard loads but the heartbeats never update. What's wrong?

Your reverse proxy is not passing the WebSocket connection Kuma uses for live updates. In your Nginx server block add proxy_http_version 1.1 along with the Upgrade and Connection headers, then run nginx -t and reload. If Cloudflare is in front, enable its WebSocket support too.

Should I run Uptime Kuma on the same server it monitors?

No. If Kuma lives on the same machine as your website and that machine goes down, your monitor goes down with it and you get no alert. Run it on a small separate VPS so it stays up to report when the monitored server fails.

TR
Tom Reyes
Support Engineer at Bytte.cloud

Part of the Bytte.cloud team. We run game servers, bots and websites for a living, and we write these guides from what we see day to day in support and on our own servers.

Want to try this on real hardware?

Bytte.cloud has free plans for game servers, bots and websites. No credit card, set up in seconds.

Start for free See the plans