It was not as easy as I hoped, so I created a tool for it which is now available on GitHub!
We decided to replace the paid monitoring service UptimeRobot with the self-hosted open source project UptimeKuma. Using UptimeRobot was a good experience, but in the end, we missed some features and found a promising alternative.
So I started the migration process. That meant I had to:
- Set Kuma up
- Export all our current monitors from UptimeRobot
- Import the monitors to Kuma
- Delete/silence all monitors in UptimeRobot to prevent double alerting
Setting up Kuma
This process was really easy. First, we had to decide where the tool should live. Hosting Kuma inside our main infrastructure would lead to the monitoring being down together with all the services we monitor, so Kuma could not send any alerts. Even hosting it in the same data center would result in Kuma not being reachable when the rest of our servers is down (even though this scenario is unlikely). So we bought a cloud server in another country, completely decoupled from all other parts of our infrastructure and services.
For hosting, we use a simple docker-compose setup with caddy as a reverse proxy. Kuma has this setup covered in their documentation. So I just had to copy the yaml file, place it on the server, enter our domain and start the server.
Exporting from UptimeRobot
Thanks to the simple usage of the REST-API provided by UptimeRobot, fetching all our monitors was done in a couple of minutes. You might ask yourself, “Why did he write a blog post about such a basic task?”. Well, the next step had a bunch of challenges for me, and I wanted to share my learnings and give some hints for my future self.
Importing the monitors to Kuma
My plan was to transform the monitors exported from UptimeRobot and import them with the help of a Kuma-API. Soon I had to realise that Kuma does not provide a public API. So I dug into the Kuma-UI and figured out that the Kuma Server and UI communicate via a websocket connection. So my new plan was to hook into the Kuma websocket, send a bunch of messages, and the job should be done. After 3 hours of fighting different python websocket packages, weird message numbers inside the websocket connection and unsuspected timeouts, I closed my laptop and went to bed.
The next day, a colleague of mine had the brilliant idea to use Playwright for this job. Playwright is very similar to Cypress and TestCafé. It allows you to control a browser and simulate user interaction. Usually, we use it for end-to-end testing our own applications.
This time I used it to automate clicking through the Kuma UI to create the monitors we previously exported from UptimeRobot. This method was really straightforward and worked reliably after adding small timeouts ensuring the UI was ready for the fast interactions through Playwright.
What I learned
Most of the time, using an API is the best way for your program to interact with any other program. But sometimes the API is unstable, not documented, weird or just not there yet. In this case, it is important to know alternative ways to access data and functions of the external system. Having Playwright in your toolbox for this, and not just for automated testing, was very handy and helped me a lot. For me, this was a good example of thinking outside the box. The usual way of using an API is not always the best one.
When you are also thinking about migrating to Kuma, check out my GitHub repository containing the basics you need to migrate your monitors. But keep in mind that this tool was created to migrate our monitors. It may not support all monitor types and settings you might have configured.