Free off-site monitoring and status page with Fly.io and Uptime Kuma

What good is a status page, when its availability depends on the status of your own infrastructure? After all the status page (and your monitoring) should also be available when the rest of your infrastructure isn’t. Bonus points of the status page is even in a different region/with a different provider.

Fly.io is a hosting provider that generously provides a free tier (256MB Ram and 3GB of storage) which is large enough to run an instance of Uptime Kuma. Fly.io provides a free instance per organisation, which means that even if you’re already using it for other projects, you could still have your free monitoring through them.

To get started with your own Uptime Kuma instance install the Fly.io command line utility and then create a file called fly.toml in an empty directory with the following content:

# fly.toml file generated for mykuma

app = "mykuma"

kill_signal = "SIGINT"
kill_timeout = 5
processes = []

[build]
  image = "louislam/uptime-kuma:1"

[mounts]
source="kuma"
destination="/app/data"

[env]
  PORT = "8080"

[experimental]
  allowed_public_ports = []
  auto_rollback = true

[[services]]
  http_checks = []
  internal_port = 8080
  processes = ["app"]
  protocol = "tcp"
  script_checks = []

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

The value of app needs to be unique and is basically the subdomain Uptime Kuma will be operating from, therefore this needs to be a unique name. In the above example the address for Uptime Kuma would be https://mykuma.fly.dev. By specifying image = "louislam/uptime-kuma:1" the instance will be deployed from the official Uptime Kuma container.

But before we can deploy our monitoring, we first need to create the data volume that we have already specified in the config above.

flyctl volumes create kuma

With the volume created a simple flyctl deploy will pull the container and deploy it on the fly.io infrastructure in the desired region.

In case you are not 100% sure about it, running flyctl info after the deployment has finished will show you the full url:

App
  Name     = mykuma
  Owner    = personal
  Version  = 0
  Status   = running
  Hostname = mykuma.fly.dev

Services
PROTOCOL PORTS
TCP      80 => 8080 [HTTP]
         443 => 8080 [TLS, HTTP]

IP Adresses
TYPE ADDRESS             REGION CREATED AT
v4   xxx.xxx.xxx.xxx               2h5m ago
v6   2a09:xxxx:1::1:xxxx        2h5m ago

The way Uptime Kuma is designed you have your own private monitoring dashboard (where you can create additional monitors and see the detailed status) at one domain (mykuma.fly.dev in the above example) and then can have a public “Status Page” on a completely separate domain.

To tell fly.io that is should respond to our own domain, one needs to create a “certificate” for it through flyctl. For my own setup I created a CNAME entry in the Cloudflare UI pointing to the “Hostname” fly.io gave for my deployed app and then executed the below command to register this domain entry with fly.io:

flyctl certs create status.mydomain.com

Once the domain is registered I can create a “New Status Page” within Uptime Kuma and assign status.mydomain.com in its settings as the “Domain Name[s]”.

And to round up your monitoring and status infrastructure a notification method (or maybe even more than just one) should be configured within Update Kuma to get notifications if important infrastructure stops responding.