Self-hosted service
louislam/uptime-kuma avatar
louislam/uptime-kuma

Uptime Kuma: self-hosted monitoring with Docker, PM2 and a WebSocket UI

Uptime Kuma runs website and service checks on your own server, then sends alerts and publishes status pages.

91,956 stars8,479 forksJavaScriptMIT

At a glance

What is it?
Uptime Kuma runs HTTP, TCP, ping, DNS and push checks from your own server, then alerts you and publishes status pages. The Docker route is one command; the trade-offs are in storage and scope.
Who is it for?
Adopt Uptime Kuma if you want check results and status pages to live on hardware you control, and if you can give it a local volume rather than an NFS mount. Skip it if you need synthetic browser journeys or a hosted service with a support contract.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Uptime Kuma replaces, and for whom

The README is explicit about the origin: the author wanted a self-hosted tool like Uptime Robot, evaluated statping and found it "not stable and no longer maintained", then built his own. That is the whole pitch. You are trading a hosted dashboard and someone else's on-call rotation for a process on your own machine that pings your endpoints and tells you when they stop answering.

The audience follows from that. It suits a solo operator or a small team that already runs a VPS, a home server, or a Proxmox box and wants check results to stay on that hardware. It suits people monitoring internal services that a SaaS probe cannot reach, because the checks run from wherever you install it. It does not suit an organisation that needs a vendor to answer a phone call at 03:00, and it does not suit anyone who wants monitoring without owning the machine that does the monitoring. If your monitoring host and your production host share a power feed, you have not solved the problem you thought you solved.

The check types, notification fan-out and 20-second floor

The feature list covers HTTP(s), TCP, HTTP(s) Keyword, HTTP(s) Json Query, Websocket, Ping, DNS Record, Push, Steam Game Server and Docker Containers. The two HTTP variants that inspect the body matter more than the plain one: a keyword check fails when the response stops containing a string, and a JSON query check fails when a field in the response no longer matches. A 200 with an error page inside it passes a plain HTTP check and fails both of those.

Notifications go to Telegram, Discord, Gotify, Slack, Pushover, SMTP email, and the README points at a directory of 90+ notification services under src/components/notifications. The README states a 20-second interval. Treat that as the floor the project advertises, not a target: every monitor you add at that cadence multiplies the outbound requests your host makes, and a check that runs every 20 seconds against a third-party API is a good way to get rate limited.

The architecture choice is stated in the motivation section: WebSocket with a single-page app instead of a REST API. That is why the UI feels immediate, and it is also why anything you build against it should not assume a stable documented REST surface. The README does not describe a public API contract.

Installing Uptime Kuma with Docker Compose

The README's first install path creates a directory, downloads the compose file from the repository, and starts the stack. The compose.yaml in the repository maps ./data to /app/data and publishes port 3001.

bash
mkdir uptime-kuma
cd uptime-kuma
curl -o compose.yaml https://raw.githubusercontent.com/louislam/uptime-kuma/master/compose.yaml
docker compose up -d

After that the README says Uptime Kuma is running on all network interfaces, reachable at http://localhost:3001 or http://your-ip:3001. Open it and the first screen asks you to create the admin account. Do that before you expose the port anywhere, because until an account exists the instance is unclaimed.

The single-container form is equivalent and easier to script. Note the image tag: the README uses louislam/uptime-kuma:2, and compose.yaml pins the same major tag.

bash
docker run -d --restart=always -p 3001:3001 -v uptime-kuma:/app/data --name uptime-kuma louislam/uptime-kuma:2

The README also shows how to keep the port off the network entirely, binding it to loopback and putting a reverse proxy in front:

bash
docker run ... -p 127.0.0.1:3001:3001 ...

One warning is worth repeating verbatim in substance: NFS and similar network file systems are not supported, so map to a local directory or a named volume. In compose.yaml that means ./data on local disk, not a mount from a NAS. After the container is up, add one monitor for a site you control, set a notification, and use the test button on the notification to confirm delivery. A monitor that turns red with no working notification channel is decoration.

Installing without Docker, and the Node version trap

The non-Docker path needs Node.js >= 20.4, Git and pm2 according to the README. The repository's package.json is stricter: it declares "node": ">= 26.2.0" and a version of 3.0.0-beta.0. That gap is the single most confusing thing about installing from source right now. The README's requirement and the package.json engines field disagree, and the README is the document most people read first.

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

# Option 1. Try it
node server/server.js

# (Recommended) Option 2. Run in the background using PM2
npm install pm2 -g && pm2 install pm2-logrotate
pm2 start server/server.js --name uptime-kuma

For a quick look, node server/server.js is enough. For anything you intend to keep, the PM2 route is the one the README recommends, and pm2-logrotate is installed alongside it so logs do not fill the disk. The README lists pm2 monit for console output and pm2 startup && pm2 save to survive a reboot.

Platform support is narrower than the Docker path. The README marks major Linux distributions and Windows 10 x64 or Windows Server 2012 R2 x64 and higher as supported, and FreeBSD, OpenBSD, NetBSD, Replit and Heroku as not supported. If you are on a BSD, the source install is a dead end and you should look at the Docker path on a Linux host instead.

Where Uptime Kuma is the wrong tool

It checks reachability and response content. It does not drive a browser through a login flow, click a button and assert on the result, so a checkout page that returns 200 with a broken payment iframe looks healthy. The check types in the README are the boundary of what it can see.

Storage is the second limit. The README's warning about NFS is not incidental: the data directory is where monitors, history and the SQLite database live, and network file systems are called out as unsupported. If your plan was to point the volume at a NAS share so several hosts can share state, that plan does not work here.

The third limit is operational. A self-hosted monitor is a service you now run, back up and upgrade. The README sends update instructions to a wiki page rather than documenting the procedure inline, so the upgrade path is not visible from the repository root. The README also states that general and technical questions should not be emailed to the author and that such emails will not be answered, directing people to GitHub Issues, the r/UptimeKuma subreddit, or a search engine. That is a support model, not a support desk. If you need a response time commitment, this project does not offer one.

Uptime Kuma versus a hosted monitor

The obvious alternative is the category the README names as the motivation: a hosted service such as Uptime Robot. The difference in approach is where the probe runs. A hosted monitor checks your service from infrastructure you do not own, from multiple regions, and keeps working when your rack loses power. Uptime Kuma checks from the machine you installed it on, which means it can reach a service that is only on your LAN, and it also means the monitor goes down with the thing it is watching.

The second difference is data and cost. Uptime Kuma is MIT licensed, so there is no per-monitor pricing tier and no account, and check history stays in your data directory. Hosted services keep that history on their side and typically meter monitors or check frequency. The README's own framing is that the closest self-hosted option it found, statping, was unstable and unmaintained, which is an argument about the self-hosted niche rather than about hosted services.

The honest position: these are not substitutes. A hosted probe answers "can the public internet reach me". Uptime Kuma answers "can this host reach that target, and did the response look right". Plenty of teams run both, with the self-hosted instance covering internal endpoints and the hosted one covering the public edge.

Licence, upgrades and what the repository does not tell you

The licence is MIT, stated in package.json and in the LICENSE file at the repository root. That permits commercial use and modification; it also means no warranty. Redistribution obligations under MIT are about preserving the licence text and copyright notice, and I am not going to give legal advice beyond pointing at the file.

The upgrade cost is real and the repository does not hide it, it just relocates it. The README's update section is a link to the wiki, and the release history shows patch releases landing hours apart: 2.5.1, 2.5.2 and 2.5.3 all carry timestamps on 2026-08-22. Frequent patches are good for fixes and annoying for operators, because each one is a container pull and a restart. Pin the image tag you have tested rather than following a floating tag, and read the wiki update page before jumping a major version.

The version situation deserves a plain statement. The README and compose.yaml point at the 2 series, the latest releases are 2.5.x, and package.json on master says 3.0.0-beta.0 with a Node engine of >= 26.2.0. Anyone installing from source on master is on the beta line, not the released line, whether they intended to be or not. The README does mention that beta releases exist and links to the releases page, but it does not warn that a plain git clone of master lands you there. Clone a release tag if you want the stable series from source.

Editorial conclusion

Adopt Uptime Kuma if you want check results and status pages to live on hardware you control, and if you can give it a local volume rather than an NFS mount. Skip it if you need synthetic browser journeys or a hosted service with a support contract. Before trusting it, verify three things yourself: that your data path is a local directory, that port 3001 is behind a reverse proxy or bound to 127.0.0.1, and that a test notification actually arrives on the channel you configured. The repository is on its 2.5.x release line with the last push on 2026-08-22, while package.json already declares 3.0.0-beta.0, so pin the image tag rather than tracking latest and read the upgrade wiki page before you move.

Frequently asked questions

What is Uptime Kuma used for?

It monitors uptime for HTTP(s), TCP, HTTP(s) Keyword, HTTP(s) Json Query, Websocket, Ping, DNS Record, Push, Steam Game Server and Docker Containers, sends notifications when a check fails, and publishes status pages. The README describes it as an easy-to-use self-hosted monitoring tool.

Is Uptime Kuma free?

Yes. The project is MIT licensed, with the licence declared in package.json and the LICENSE file at the repository root. You pay for the server you run it on, not for the software.

Is Uptime Kuma safe?

The README lists 2FA support and proxy support among the features, and the Docker install can be bound to 127.0.0.1 so only a reverse proxy reaches it. The README does not publish a security audit, so exposure decisions are yours; there is a SECURITY.md file in the repository root for reporting issues.

How to install Uptime Kuma with Docker?

The README's Docker Compose path creates a directory, downloads compose.yaml from the repository, and runs docker compose up -d, which publishes port 3001 and maps ./data to /app/data. A single docker run command with the louislam/uptime-kuma:2 image does the same thing.

How to access Uptime Kuma after it starts?

The README states it runs on all network interfaces, so you reach it at http://localhost:3001 or http://your-ip:3001. Create the admin account on first load.

Can Uptime Kuma be installed on Windows?

The non-Docker requirements list Windows 10 (x64) and Windows Server 2012 R2 (x64) or higher as supported, with Node.js, Git and pm2. The README does not list a Windows-specific install procedure beyond those requirements.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/louislam-uptime-kuma.svg)](https://hysenlabs.com/projects/louislam-uptime-kuma)
Community notes

Community notes