Deploy a self-hosted, open-source uptime monitoring stack using Docker and Uptime Kuma to track HTTP(S), TCP, ICMP, DNS, and Container health across internal and public services. The solution implements persistent storage, health checks, and Discord notifications for actionable on-call signals, and a published read-only status page for stakeholders. The main aim of this solution is to provide early detection of outages with minimal operational overhead.
If you choose to deploy Uptime-Kuma as a Docker container, I recommend using Ubuntu Server or Linux Mint as the base OS. During testing, I noted that the default Ping monitor type did not work when using Ubuntu Desktop (see Troubleshooting Notes).
Uninterrupted website, server, device, and internet connectivity are crucial for businesses that rely on digital services. Whether it is a cloud SaaS platform, website, or critical internal IT infrastructure, any downtime can lead to frustrated users or clients, lost revenues, and a tarnished reputation. This is where uptime monitoring tools come into play; not only can they provide early alerts about inaccessible systems or infrastructure, but they can also help detect and prevent cyber attacks (https://blog.sitehawk.io/how-uptime-monitoring-helps-in-detecting-and-preventing-cyber-attacks-96550dd1d6a).
In one of my previous roles, I used Nirsoft PingInfoView (https://www.nirsoft.net/utils/multiple_ping_tool.html), a free Windows utility, to visually monitor critical internal infrastructure, cloud platforms, and internet connectivity. For a single client/admin use-case, this tool is sufficient. However, in an environment where multiple IT/network admins, security engineers, or SOC analysts need to monitor the uptime of critical services, a more robust solution is required.
While there are many uptime monitoring solutions, open-source and paid, I settled on Uptime Kuma (https://uptimekuma.org/). It is open-source, fairly simple to implement and use, platform/OS agnostic, and can be self-hosted on-premise or in the cloud, depending on your preference. Uptime Kuma includes several additional features, but for my use case the following were the most important:
Docker implementation.
Support for secure 2 Factor Authentication; not included in this project, but extremely easy to set up.
Alert notifications - Uptime Kuma can be set up to send notifications to several platforms (Slack, Telegram, Discord, SendGrid, OpsGenie and PagerDuty).
A read-only status dashboard can be created and shared with others within the organisation who need or want to monitor services.
Setting up Uptime Kuma is fairly simple and can be done in 10 - 15 minutes if you follow the steps outlined on this page. If you would like to test Uptime Kuma before proceeding with the rest of this project, you can check out the free demo: https://demo.kuma.pet/start-demo
I opted to set up Docker and Uptime Kuma on Ubuntu 25.10, but the setup should work on any operating system, provided you follow the required steps to install Docker.
The commands to the right are copied directly from the Ubuntu installation pages for Docker Engine (https://docs.docker.com/engine/install/ubuntu/) and Docker Desktop (https://docs.docker.com/get-started/get-docker/). I recommend following each step (copy and paste each command - except for the comments denoted by the '#' symbol):
Ensure the operating system is up to date.
Add Docker's GPG key and the repository to Ubuntu's apt sources.
Install the latest version of Docker Engine, Compose, and dependencies.
Confirm the Docker engine is running
If Docker engine is not running, execute: sudo systemctl start docker
Download and install Docker Desktop (you may need to change the execute file permissions of the downloaded file - chmod +x docker-desktop-amd64.deb)
The remaining commands are not essential, but are useful for deploying Docker in a production environment:
Ensure Docker automatically starts at system bootup: systemctl --user enable docker-desktop
Run Docker commands without sudo for the current user:
Add the current user to the Docker group: sudo usermod -aG docker $USER
Logout and log back in to effect the group changes (recommended), or execute the following command (to change the current effective group ID of your user for the duration of the terminal session): newgrp docker
Ensure Docker Engine is running
Docker Engine, Desktop, and Compose versions
Recommend: After installing the Docker Engine and Desktop, reboot the OS (or Virtual Machine in my case) to confirm Docker will run at system startup without issues. In my case, I am using VMware Workstation and encountered the 'Virtualisation Support' error (below) for Docker Desktop.
If you are using VMware Workstation/Player, power down the VM, access the Virtual Machine Settings, and under the Processor tab, ensure the respective Virtualisation Engine parameters are enabled (see right). If you are using VirtualBox or running Docker on your main OS and encounter this error, you will need to research and troubleshoot the issue further.
https://docs.docker.com/desktop/setup/install/linux/#kvm-virtualization-support
VMware Workstation Virtualisation Engine configuration enabled.
At this point, (if you're running Docker for the first time), there should be no containers running or any images downloaded; this can be confirmed by running the following commands and not receiving any output.
Display locally available images: docker images
Display locally running containers: docker ps
It is possible to download and set up a Uptime Kuma container manually, but as best practice and to ensure consistency, create a compose.yml file with the required configurations. I used the compose.yml sample (right) from the official Uptime Kuma website (https://uptimekuma.org/install-uptime-kuma-docker/) with slight modifications:
Removed the deprecated version
Changed the restart policy from 'always' to 'unless-stopped' (https://docs.docker.com/engine/containers/start-containers-automatically/)
Changed volumes to './data:/app/data'
I recommend placing the custom Uptime Kuma compose file in its own directory.
Next, execute the following at the command line to download, configure, and launch the uptime-kuma container:
docker compose up -d
Once completed, confirm the container is running by executing docker ps
Uptime Kuma container initial download, configuration, and launch.
Docker Desktop with uptime-kuma container running
If the compose.yml file and the commands execute correctly, a new 'uptime-kuma' container will run and be accessible at http://localhost:3001 on the same host machine running the Docker engine.
On the following pages, you will need to set up Uptime Kuma's basic configuration, admin credentials, and add monitors. Monitors are essentially specific checks configured to track the 'status' of services and devices on the network (local or over the internet).
Uptime Kuma works by periodically sending requests to user-defined services (like websites, IP addresses, or servers) to check their status, and if a service is down, it keeps track and sends alerts to a configured notification service like Slack or Discord. Custom monitoring intervals can be set, such as checking a website every 20 seconds, and Uptime Kuma will display the status on a dashboard and generate notifications based on pre-set rules and the service's status change.
Uptime Kuma initial user setup page.
Uptime Kuma admin Dashboard page
There are various types of monitors that can be configured within Uptime Kuma - HTTP/S, Ping, Port, DNS, etc. To add a monitor, click the '+ Add New Monitor' button near the top-left corner of the Dashboard page.
On the following page, from the Monitor Type dropdown, select the type of monitor (https://uptimekuma.org/wiki/add-a-monitor-in-uptime-kuma/).
Specify a 'Friendly Name'
Specify the IPv4 address, URL, domain name, Port, etc, you want to monitor (the required details will vary depending on the monitor type selected).
Specify the 'Heartbeat Interval', i.e. how often Uptime Kuma will check on the system, device, or IP address.
Specify the number of 'Retries'
Click save
For instance, you can set up the following monitors to monitor your personal/company website or cloud platform and internet connection:
HTTP(s) (Moniter Cloud Platforms, Websites, etc.):
Monitor Type: HTTP(s)
Friendly Name: < user-friendly name>
URL: `https://<domain>`
Ping/ICMP (Internal Gateway, Servers/Services, Devices, etc):
Monitor Type: TCP Port
Port: 53
Hostname: `<ip address>`
Adding website monitors to the Uptime Kuma monitoring system.
For each monitor defined, you can set up Uptime Kuma to send out notifications via email (SMTP), Telegram or Signal alerts, Slack Channel alerts, Discord notifications, Splunk, SendGrid, Twilio and Pushover. Using this feature, IT teams will receive an alert when a service, device, or IP address is marked as 'down' without having to log in to Uptime Kuma.
Each notification system (Slack, email, Discord, etc) requires unique set up steps, but the process is fairly easy. In Discord, you will need a Discord Server and a Channel to create a Webhook (https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks), which is then added to Uptime Kuma. In my test setup (see below), I added my Discord webhook and confirmed that alerts from my local Uptime Kuma container can communicate with my Discord server/channel.
Testing notification alerts using Discord webhooks.
Uptime Kuma Status Page is a useful communication feature IT teams can use to communicate information to customers or key company staff during an outage or maintenance period. A status page can provide real-time, read-only information to key stakeholders regarding the status of a platform, service or device. Many organisations provide free and open access to their status pages, including Google (https://www.google.com/appsstatus/dashboard/), AWS (https://health.aws.amazon.com/health/status), and Azure (https://azure.status.microsoft/en-us/status).
To create a Uptime Kuma status page, click on the 'Status Pages' button near the top right corner of the main Dashboard page and follow these steps:
Provide a Status Page name and slug (a unique URL element that can be used to access a specific status page).
Click Next
On the next page, select the monitors (or Group of monitors) to add to the Status page:
On the left side panel, you can customise elements such as a Status page description, footer text, theme, Google Analytics ID, and custom CSS styling.
When done, click the Save button.
You can add the unique status page URL to your internal company intranet, public website, or share the link with staff, usually in the format: http(s)://<ip or domain>/status/<status-page-slug>. However, this can be rewritten to any required format using a reverse proxy.
Defining the name and URL of the Uptime Kuma Status page.
Customising and adding monitors to the Uptime Kuma Status page.
Uptime Kuma admin Dashboard page (left) vs the read-only Status page (right).
The default Ping Monitor type (in my case - see right) did not work out of the box and kept reporting that the IP address (internal and external) could not be reached, and the device/service failed.
Even after disabling the firewall, the container could not ping the respective IP address or hostname. However, the TCP/Port monitor type functioned without issue.
I did note that when executing the Uptime Kuma compose configuration file and containers as root, the Ping monitor type did work, but this is not a secure way to run a container in a production environment (see screenshot below).
A useful command I found while troubleshooting this particular problem was - docker exec, which allows you to execute a command inside a running Docker container.
The command takes two main parameters:
Container name/ID
Command to execute within the container.
https://docs.docker.com/reference/cli/docker/container/exec/
The Uptime Kuma Docker container can ping IP addresses when running as root.
The Ping monitor works when running the Uptime Kuma Docker container as root.
However, this solution is not ideal, because a security breach of the container would potentially allow an attacker to compromise the host operating system. In summary, never deploy and run containers as root.
An alternative solution I found was to run the container with the following command:
# Launch the container again and availing it on the LAN
docker run -d --network host --name uptime-kuma louislam/uptime-kuma:latest
However, this also had several security issues:
Exposure of Host Network Interfaces and Ports: Container directly shares the host's network namespace, allowing it to bind to any port and the network interface on the host. This effectively exposes all services running inside the container to the host's network and potentially the external network (internet).
Reduced Network Segmentation: There is no network isolation between the host and container, nor between containers running on the same host using --network host. Thus, removing the critical layer of security that network segmentation provides and allowing easier lateral movement by an attacker.
Access to Host Network Services: The container can directly access services running on the host, such as databases, SSH daemons, or other applications, without any filtering or port mapping. This can lead to unauthorised access to sensitive host resources if the container is compromised.
Increased Attack Surface: Any vulnerability within the containerised application or its dependencies becomes a direct vulnerability of the host system's network. Attackers can exploit these vulnerabilities to gain a foothold on the host, potentially escalating privileges and compromising the entire system.
Kernel Vulnerabilities: Since containers share the host kernel, any kernel vulnerability can be exploited by a compromised container to potentially break out of the container and gain root access to the host.
I tried several other options for deploying Uptime-Kuma, including building a customised image based on louislam/uptime-kuma:latest with additional packages and settings to allow the container to ping hosts and IP addresses. I also tried building a new Ubuntu 24.04 virtual machine and restarting the whole project from scratch, just in case I missed something; neither the custom image nor the rebuilt VM yielded any positive results.
In the end, I opted to try other Linux distributions and confirmed that setting up Uptime Kuma as a Docker container on Linux Mint or Ubuntu Server 24.04 provided full functionality.
Uptime Kuma running on Ubuntu Desktop (left) could not ping any IP address, while the same Docker container running on Ubuntu Server (right) can ping ip addresses.
Uptime Kuma provides quiet a number of key features for small to medium sized organisations, and for home labs. If you are deploying this solution as a Docker Container on a Linux host system, I would recommend Linux Mint (if you need a graphical interface) or Ubuntu Server (specifically 24.04). However, it is possible to install Uptime Kuma on a standalone Linux or Windows system.
It is worth mentioning that there are several alternatives to Uptime Kuma (open-source and paid), offering a variety of features, including the following:
Monitoror (Open Source): A free, self-hosted monitoring tool available for Windows 64-bit, Linux 64-bit, Linux ARM, and macOS.
Upptime (Open Source): Provides comprehensive monitoring capabilities (analytics and response time metrics), built-in notification, and incident reports.
StatusGator (3 Monitors Free): Excels at aggregating official status data from third-party providers and can monitor 4,000+ cloud services (AWS, GitHub, Cloudflare).
Pulsetic (10 Monitors Free): Provides a modern interface and can be set up quickly and simply to start monitoring and produce detailed performance reports.
UptimeRobot (50 Monitors Free): Like Yptime Kuma, it can generate notifications and includes the ability to monitor cron and keywords.
Docker Engine: https://docs.docker.com/engine/install/ubuntu/
Docker Desktop: https://docs.docker.com/get-started/get-docker/
Get Docker Compose: https://docs.docker.com/compose/install/
Uptime Kuma: https://hub.docker.com/r/louislam/uptime-kuma
Uptime Kuma (GitHub): https://github.com/louislam/uptime-kuma