Skip to content
Deployments

Deploy Uptime Kuma with the uptime-kuma template

Deployment

Deploy Uptime Kuma with the uptime-kuma template

Stand up Uptime Kuma, an open-source uptime-monitoring and status-page tool, on a single Quake AI instance using the validated OpenTofu template uptime-kuma. You apply the template, reach the dashboard over the floating IP, create the admin account, add monitors for a service you run, send an alert to a notification channel, and publish a public status page.

Uptime Kuma watches the services you deploy and tells your users when something is down. You run it yourself; this is a self-hosted tool you operate, not a managed service.

YouStatus page viewerFloating IPUbuntu instanceYour serviceCaddyreverse proxyUptime Kumadashboard + checks proxies 443 to 3001HTTPS dashboardHTTPS status pageHTTP / TCP / ping checks
Click to zoom
What you'll build: an Uptime Kuma host on a single instance, with a restricted admin dashboard, monitors polling your services, and a public status page served over HTTPS through a Caddy reverse proxy

Monthly cost estimate

Pricing calculator ↗

Sized as a custom package on shared vCPU.

Starting template$14.70/mo

Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.

What each resource is for

Uptime Kuma host

s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps

Runs Uptime Kuma in Docker (monitor checks, alerting, and public status pages), with the SQLite database on an attached volume.

Uptime Kuma is a single SQLite-backed container that runs on 2 vCPU and 2 GiB RAM. Size up only for hundreds of monitors at short check intervals.

$16.50/mo

Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.

Included in baseline

s1a.small

2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50

Compute + RAM rate basis

2 vCPU + 2 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.

—

Block storage (40 GiB)

40 GiB at $0.08/GiB/mo

$3.20

Public IP (included)

1 included with the custom package

$0.00

Package promotional discount

Flat −$5.00/mo on the custom package (same promotion as named plans).

$-5.00

Included at no charge

These line items are zero on Quake AI. Many other providers meter them separately.

Data transfer (inbound and outbound)

Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.

AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.

Learn more
$0.00

Private networking

Private networks, subnets, Neutron routers, and security groups are included with the plan.

VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.

$0.00

Control-plane API requests

OpenStack API calls for provisioning and management are included.

Some managed services on other clouds meter API calls or charge for premium control-plane features.

$0.00

Pricing data last validated: . For current rates, check quake.ai/pricing.

Prerequisites#

You need:

  • OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
  • Your OpenStack credentials sourced into the shell (source openrc.sh). See the OpenStack CLI guide.
  • An SSH keypair that already exists in your project. Record its name for the key_name variable.
  • A copy of the uptime-kuma template directory from the template reference page.
  • A service you want to monitor (an HTTP endpoint, a TCP port, or a host that answers pings). Any app you have already deployed works.
  • Your workstation's public IP address, so you can open the dashboard port to it for first-boot setup. Find it with curl -sS https://api.ipify.org.

A domain is optional for first boot. You add it later to serve the dashboard and the public status page over HTTPS.

Step 1: Set the variables and apply the template#

The dashboard listens on port 3001 over plain HTTP. The template's security group restricts port 3001 to dashboard_allowed_cidr, which defaults to the private network only, so the raw dashboard stays off the public internet. To reach the dashboard from your workstation for first-boot setup, set dashboard_allowed_cidr to your own address.

Copy the template's example variables file and open it:

bash
cp terraform.tfvars.example terraform.tfvars

Set key_name to the SSH keypair already in your project, and dashboard_allowed_cidr to your workstation's public IP with a /32 suffix:

HCL
key_name               = "YOUR_KEY_NAME"
dashboard_allowed_cidr = "YOUR_IP/32"

Initialize the working directory, preview the plan, and apply:

bash
tofu init
tofu plan
tofu apply

OpenTofu provisions a private network, a router, a security group, a block volume mounted at /var/lib/docker, an instance, and a floating IP. On first boot, cloud-init mounts the data volume, installs Docker Engine, and starts Uptime Kuma from a compose file on port 3001.

When the apply finishes, read the outputs:

bash
tofu output

Record floating_ip, dashboard_url, and status_page_url.

Step 2: Create the admin account#

Uptime Kuma does not ship a default password. You create the admin account the first time you open the dashboard.

cloud-init takes a minute or two after the instance reaches ACTIVE. Open dashboard_url (for example http://YOUR_FLOATING_IP:3001) in your browser. If the page does not load yet, wait and retry; you can watch the container start over SSH:

bash
ssh ubuntu@YOUR_FLOATING_IP "sudo docker ps --filter name=uptime-kuma"

When the setup screen appears, enter a username and a strong password to create the admin account. Uptime Kuma signs you in and opens an empty dashboard.

Step 3: Add monitors for your service#

A monitor is one check that Uptime Kuma runs on a schedule. Add one of each common type for the service you want to watch.

  1. Select Add New Monitor. Set Monitor Type to HTTP(s), Friendly Name to a label such as API health, and URL to your service's health endpoint (for example https://api.example.com/health). Set Heartbeat Interval to 60 seconds. Select Save.
  2. Add a second monitor with Monitor Type TCP Port. Set Hostname to your service host and Port to the port you depend on (for example 5432 for a database). Select Save.
  3. Add a third monitor with Monitor Type Ping. Set Hostname to the host you want to reach. Select Save.

Each monitor shows a live status and a heartbeat bar. Within a couple of intervals, a reachable service shows green. To confirm the failure path, stop the monitored service briefly: the monitor turns red and records a downtime event.

Step 4: Send alerts to a notification channel#

A monitor is useful once it tells you about a failure. Add a notification channel and attach it to your monitors.

  1. Go to Settings > Notifications > Setup Notification.
  2. Choose a Notification Type. Email (SMTP), a webhook, and chat integrations (Slack, Discord, Telegram) are all built in. For a webhook, set the URL your receiver listens on.
  3. Select Test to send a sample alert and confirm it arrives, then Save.
  4. Enable Default enabled so new monitors use the channel, or open each monitor and attach the notification under Notifications.

When a check fails, Uptime Kuma sends an alert through the channel and a recovery message when the service returns.

Step 5: Publish a public status page#

A status page is a public, read-only view of the monitors you choose. It is separate from the admin dashboard, which stays restricted.

  1. Go to Status Pages > New Status Page. Set a Name and a Slug such as public. The page is served at /status/public.
  2. On the page editor, add the monitors you want visible. A status page shows only the monitors you add, so leave internal checks (such as a database port) off a public page.
  3. Set the page to Published and select Save.

The status page is now reachable at http://YOUR_FLOATING_IP:3001/status/public. Status pages are meant to be public, so you expose this path deliberately while keeping the admin dashboard restricted.

Step 6: Serve the dashboard and status page over HTTPS#

The template leaves ports 80 and 443 open for a reverse proxy. Caddy obtains and renews a TLS certificate automatically once a domain resolves to the instance.

  1. Create a DNS A record for your domain (for example status.example.com) pointing at YOUR_FLOATING_IP. Follow How to point a domain at a Quake AI resource. Wait until the record resolves:
bash
dig +short status.example.com
  1. SSH to the instance and create /opt/uptime-kuma/Caddyfile:
status.example.com {
  reverse_proxy 127.0.0.1:3001
}
  1. Add Caddy to the compose file at /opt/uptime-kuma/docker-compose.yml so it runs alongside Uptime Kuma:
YAML
services:
  caddy:
    image: caddy:2
    restart: unless-stopped
    network_mode: host
    volumes:
      - /opt/uptime-kuma/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
volumes:
  caddy_data:
  1. Apply the changes and confirm both containers run:
bash
cd /opt/uptime-kuma
sudo docker compose up -d
sudo docker compose ps

Open https://status.example.com/status/public and confirm the padlock. For background on certificate issuance and renewal, see How to issue and auto-renew a TLS certificate with Let's Encrypt. Once HTTPS works, close direct access to port 3001 by setting dashboard_allowed_cidr back to the private network in terraform.tfvars and running tofu apply.

What you built#

  • Applied the uptime-kuma template to provision a network, security group, data volume, instance, and floating IP, and let cloud-init install Docker and start Uptime Kuma
  • Created the admin account on the dashboard's first-boot screen
  • Added HTTP, TCP, and ping monitors for a service you run
  • Sent alerts to a notification channel and confirmed delivery
  • Published a public status page and served it over HTTPS through a Caddy reverse proxy

Scope of this deployment#

This template runs a single-VM Uptime Kuma host, not a managed monitoring cloud. The instance is CPU-only and runs in one region, so run it in a different region from the workloads it watches: a monitor that shares a failure domain with the service it checks cannot report a region-wide outage. You operate the instance, Docker, Uptime Kuma, and the data volume yourself: back them up, patch them, and snapshot the volume before you resize or rebuild the host.

Next steps#

Clean up#

When you no longer need the deployment, destroy everything the template created:

bash
tofu destroy

Then remove the DNS A record you created in step 6. Because the monitors, history, and status pages all live on the instance and its attached volume, tofu destroy removes them along with the infrastructure. Export any configuration you want to keep before you destroy.

Before this
Was this page helpful?