Nowadays, our lives are entirely connected:
- Online devices
- Sites
- Services
- Data
- ...
Knowing whether all these resources are accessible or not is of fundamental importance and in this Uptime Kuma Docker Compose guide we'll learn how to do it!
Table of Contents
Uptime Kuma at a Glance
So, let's give a quick introduction to this tool, to answer this question:
What Is Uptime Kuma?
According to its creator, louislam:
Uptime Kuma is an easy-to-use self-hosted monitoring tool.
Ok, so?!
Well, many of you surely know sites used to check if a site/service is up or down, like:
- https://downdetector.com/
- https://downforeveryoneorjustme.com/
- https://down.com/
- And many others....
Uptime Kuma is the equivalent of these sites, BUT it can be configured in order to monitor what we want:
- The monitoring is not just limited to sites, but can be extended to other things.
- It's possible to set notifications with various services, just to name a few, like Telegram, Discord, Slack, email.
- We can create our customized dashboards that only show the monitors we've chosen.
- Monitors could be grouped or categorized to simplify the search.
If you want to take a look and try Uptime Kuma, to better understand if it fits your needing, here's the demo page.
What can we monitor with it?
Here's a temporary list of what is actually supported by Uptime Kuma:
- HTTP(s) sites
- TCP ports
- HTTP(s) Keyword
- HTTP(s) Json Query
- Ping
- DNS Record
- Push
- Steam Game Server
- Docker Containers
- Databases
- MQTT
- Radius
- GameDig
Install Uptime Kuma with Docker and Docker Compose
The configuration is quite simple, but before starting we need to make sure our environment is set up correctly.
Requirements
I highly recommend to follow the newest Anand's guides to configure everything from zero or to update your existing configurations, as in this tutorial I'll use the same configuration.
Here are the links for the guides:
- Install Docker on Ubuntu
- Install Docker on Ubuntu Server
- Install Docker Compose on Ubuntu
- Set Docker Environment (MOST IMPORTANT)
Deployarr can install 40+ Docker Apps in minutes, including Traefik, Authelia, Starr Apps, and more.
Uptime Kuma Docker Compose
As I told before the configuration is quite simple,
we only need to create a new yml file in the "compose" folder and paste the following code:
services: uptimeKuma: container_name: uptimeKuma image: louislam/uptime-kuma:latest restart: always networks: - socket_proxy volumes: - $DOCKERDIR/appdata/uptimeKuma/data:/app/data ports: - 3001:3001
Add Uptime Kuma to the Docker Stack
Save the file as uptime-kuma.yml and edit the master docker-compose.yml file to include the newly created file:
[...] include: # Place the path of the file under the "include" section [...] - compose/UDMS/uptime-kuma.yml
Note, UDMS is the host name of machine based on Anand's guides. You could use your machine's hostname or even not separate your compose files by hosts, in which the path would be - compose/uptime-kuma.yml.
If you do so remember to insert the correct filename in the master docker-compose.yml file.
Start Uptime Kuma and Test
Now that we have added the Uptime Kuma docker compose to the main Docker Compose file, start it using the following command:
sudo docker compose -f /home/user/docker/docker-compose-udms.yml up -d uptimeKuma
Visit http://docker-host-ip:3001 to access Uptime Kuma web interface. Create the first user and continue.
Setting up Monitors
Everything is up and running, and now we can start to setup some monitors.
Containers Monitors
Before we start monitoring our containers, Docker Host must be configured, in order to allow Uptime Kuma to reach them.
Setup Docker Host Connection
Go to Settings, clicking on the User button on the top right page, and then on Settings:
Click on Docker Hosts, and Setup Docker Host:
Configure the connection:
Field | Explanation |
---|---|
Friendly Name | The name by which we will refer to our Docker Host |
Connection Type | The way we reach our Docker Daemon: Socket: if no proxy is configured and we bind directly docker.sock to Uptime Kuma container. TCP/HTTP: our case, where we have a proxy that communicates with Docker Daemon. |
Docker Daemon | The path we use to reach our Docker Daemon. |
If Docker Daemon is something new to you, here's something to clarify how it works and how it could allow communications between containers and Docker Host.
Click on Test to see if the configuration is working, and then Save.
Setup Containers Monitors
Click on the Add New Monitor button on the top left page:
From the Monitor Type drop-down menu, select Docker Container:
Field | Explanation |
---|---|
Friendly Name | The name by which we will refer to our monitored container: this can be different from the actual real container's name. |
Container Name / ID | The name of the container: this must be the real container's name defined in its yaml configuration file. |
Docker Host | The Docker Host we configured before. |
Heartbeat Interval | Time between checks: cannot be set lower than 20 seconds. |
Retries | Maximum retries before the service is marked as down and a notification is sent. |
Heartbeat Retry Interval | Time between retries: cannot be set lower than 20 seconds. |
Resend Notification if Down X times consecutively | The variable is self-explanatory: set this to 0 means disable resend. |
Upside Down Mode | Flip the status upside down. If the service is reachable, it is DOWN. |
Monitor Group | Add the monitor to a specific monitor group. |
Description | Description that will appear under the Friendly Name of the monitor in the main monitor's page. |
Tags | Tags that will make our life easier if we have to search among many containers. |
We can configure the monitor according to our needs, for example, if we don't need to know if a docker is UP or DOWN almost immediately, we can set the Heartbeat Interval to a higher value than 60 seconds, this is completely up to us!
Databases Monitors
For this monitor, I'm going to use a containerized MariaDB database, but we can of course use a not containerized one.
Setup Databases Monitors
Click on the Add New Monitor button on the top left page:
From the Monitor Type drop-down menu, select MySQL/MariaDB:
I have only reported the specific fields for this monitor, leaving out the generic ones that are the same for all (Friendly Name apart):
Field | Explanation |
---|---|
Friendly Name | The name by which we will refer to our monitored database. |
Connection String | The string that contains the details for the connection to the database:
The final result should be something like this: mysql://[email protected]/TestDatabase |
Password | If not inserted in the connection string, the password must be specified here |
Query | This is an optional field: a query for the database. It displays the number of row/rows found or the error message returned, in the main monitor page. Using query allows us to return customized error messages that we can receive as notifications. |
HTTP Monitors
There are various HTTP monitors:
- HTTP(s): to monitor sites and certifcates expiration
- HTTP(s) - Keyword: to search keyword in plain HTML or JSON response. The search is case-sensitive.
- HTTP(s) - Json Query: do a json Query against the response and check for expected value.
- HTTP(s) - Browser Engine BETA: Shows the picture of the page during the monitor checks, but it's still in Beta testing.
I'm going to show the HTTP(s) - Json Query as, in my opinion, it's the most interesting from a functional point of view, and because is the one I've used to realize my "Docker Host public IP change" monitor, but we'll discuss about this later.
Setup HTTP(s) - Json Query
Click on the Add New Monitor button on the top left page:
From the Monitor Type drop-down menu, select HTTP(s) - Json Query:
Even here, I have only reported the specific fields for this monitor, like I did before:
Field | Explanation |
---|---|
Friendly Name | The name by which we will refer to our HTTP monitor. |
URL | The URL that will provide us the Json response to analyze. |
Json Query | The documentation for the JSON query language can be found here, and a playground to test what you've learned from docs, here. |
Expected Value | The expected result from the Json query. |
Advanced | Self-explanatory advanced fields:
|
Max. Redirects | Max redirects to follow. Set this to 0 means disable redirects. |
Accepted Status Codes | The Status Codes that will be considered a succesful response. |
Proxy | The Proxy section allows us to configure a proxy to reach the desired URL. The supported protocols are:
|
HTTP Options | This fileds allows us to edit HTTP requests sent to the specified URL. |
Authentication | Authentication method for the specified URL. The supported methods are:
|
Other Monitors
We're going to see some monitors, that are very easy to set up, but at the same time very useful:
TCP Monitors
Need to keep an eye on a specific TCP port? Here's the monitor that will do the job.
The only field to configure, different from the others we've already seen, is the Port.
DNS Monitors
Monitor for DNS records:
Field | Explanation |
---|---|
Friendly Name | The name by which we will refer to our monitored DNS record. |
Hostname | the hostname DNS records refer to. | Resolver Server | DNS server to use. |
Port | Port of the DNS server. |
Resource Record Type | The type of the DNS record to check. |
Ping Monitors
Monitors that keep monitored the ping against a specific host/site/device/anything that has an IP address.
No new fields to report here!
Push Monitors
If we need to monitor something behind a firewall, or for some other reasons not directly reachable, we could implement a so called Passive Monitor Type. With this monitor we'll be provided an url, called Push URL, that needs to be called every X seconds, according to the value setted in the Heartbeat Interval field, from the thingh we want to monitor, otherwise it will be marked as DOWN.
Group Monitors
Groups are used to collect different monitors, improving dashboard ordering and clarity, especially if we have a lot of monitors.
With groups:
Without Groups:
No new fields to report here!
Telegram Notifications
With all these monitors, it would be nice to be notified when something happens, so what's better than some friendly Telegram notifications?
As I'm a great fan of Telegram, and I use it very often to receive notifications from NAS, IoT, docker, ... I've already explained how create and configure a bot to do so.
If you missed the tutorial, here's the link: Watchtower Docker Compose with Cool Notifications [2024]
After creating our bot, we need to access the Uptime Kuma notifications settings, and this could be done from the Settings page:
Here we can also see the settings for TLS Certificate Expiry present in the HTTP(s) monitors.
We can also access the notifications settings directly during the creation of a new monitor:
The Notification's setting page:
Field | Explanation |
---|---|
Notification Type | The supported Notification Services. In our case we'll choose Telegram. |
Friendly Name | The name by which we will refer to our Notification Service | Bot Token | Our Telegram Bot Token. |
Chat ID | The ID of the chat where we want to receive notifications. Supported chats ID are:
|
Other Options | The other options are all self-explanatory and could be left as they are, except if we want to, for example, receive silent notifications or enable by default notifications for all the new monitors. |
Click on Test, check your Telegram to see if the notification has arrived, and then Save.
Status Pages
Status pages make it possible to show pages with monitors status, without being logged, so accessible to basically anyone who knows the correct URL.
This is an example on how the Status Page looks like:
For every different status page, we can choose a different URL for its reaching.
Let's start the creation of our Status page by clicking on the Status Page button on the top right page:
Then click on New Status Page, select the name for the page and the slug referring to the page (E.g.: If you chose monitorpage as slug, the page will be reachable at http://:docker-host-ip:port/status/monitorpage)
Finally, we could select which monitors or groups to show in the page.
There are others options too, like theme selection, CSS, footer editing, and many more but I'm not going to cover them now, as they're not necessary to what we want to reach at the moment.
Other Features of Uptime-Kuma
2FA
If we plan to expose Uptime Kuma container to the internet, an extra layer of protections never hurts, so we'd better enable 2FA.
From Settings, click on Security and then 2FA Settings:
The classical QR code will be displayed, frame it with your favorite 2FA application, insert the generated code to verify and that's all!
API
Yes! There is an API too.
You can find the documentation here.
Just to give you an idea: I created an HTTP(s) - Json Query monitor that looks for an IP value, extracted from my Cloudflare DNS. When this value changes, the monitor is automatically updated with the new value.
The only limit is our own imagination!
Access Uptime Kuma
We have various options to access our dashboards or Uptime Kuma control panel:
- Port Forwarding
- Wireguard / VPN
- Reverse Proxy
Port Forwarding
The classic (and less secure) method, which consists in forwarding an external port of our router/modem/firewall/Internet facing device/..., directly to the corresponding port of the Uptime Kuma container's, on our Docker Host.
Wireguard/VPN
Safer than the previous method, we can access Uptime Kuma through Wireguard or any other VPN that you like.
You can find everything you need for Wireguard, that I highly recommend, here:
Other Posts in the Wireguard Series:
- Wireguard VPN Intro in 15 min: Amazing new VPN Protocol
- Complete Wireguard Setup in 20 min – Better Linux VPN Server
- Wireguard Windows Setup: Powerful VPN for Windows
- Wireguard Mac OS Client Setup – The sleek new VPN
- Wireguard Android Client Setup – Simple and Secure VPN
- Ultimate WireGuard Docker Compose: with CF and Traefik Support
Reverse Proxy
A good method that includes practicality, customization and security.
Traefik is our choice as reverse proxy, and its configuration is well detailed in these Anand's guide:
- v3: Ultimate Traefik v3 Docker Compose Guide: Best Reverse Proxy
- v2: Ultimate Traefik Docker Compose Guide: LE, SSL, Reverse Proxy
With this configuration, we can reach our Uptime Kuma dashboard or status pages through an address like https://uptime.ourdomain.org.
You can look at the Anand's configuration directly from his Github.
Bonus Track
Let's dive a little deep into HTTP(s)-Json Query monitors. As I said before, I built a monitor that looks for an IP value extracted from my Cloudflare DNS, so let's break it down to see how this works!
Some premises:
- The value of the DNS entry I'm monitoring is dynamic and automatically updated via Cloudflare API through a custom Python script.
- I did not use a DNS monitor because the only thing I can do with it is resolve a hostname to an IP, without the possibility of comparing the result obtained with the desired one.
- I did not use DNS monitor because even if it allowed me to compare the obtained result with the desired one, the IP obtained would be a Cloudflare one, as I use the Cloudflare proxy to avoid exposing the real IP address.
What we need
Final Thoughts
Uptime Kuma is definitely a good starting point to create our homemade monitoring system, implementing notifications and also status pages.
It allows us to create simple monitors with basic tasks like ping, resolving DNS, check sites certificates expiry, but also more complex tasks with databases, Json queries, and others.
We could also automate the monitor creation, based on Docker container labels, with AutoKuma.
In this guide I showed some of the monitors available in Uptime Kuma, to start getting familiar with it, but there are more.
Go play with it! Happy monitoring!