Skip to content
Guides · Recipes

How Do I Run Uptime Kuma in a Cloud Sandbox?

Updated October 27, 2026 .md

Short answer: Run docker run -d --restart unless-stopped -p 3001:3001 -v uptime-kuma:/app/data louislam/uptime-kuma:1 in a small Sandboxer sandbox, then sbx host 3001 for a private HTTPS URL. It suits trying Uptime Kuma or watching apps in the same sandbox. No checks run while the sandbox is stopped, and Kuma doesn't flag that gap.

Is a sandbox the right place for an uptime monitor?#

Be clear about the fit first. A monitor has to run all the time. A sandbox stops after its auto-stop deadline (one hour by default) and pauses itself when idle. Uptime Kuma's own checks don't count as activity, so they don't keep it awake. We measured that below.

You want to Fit
Try Uptime Kuma, build monitors and status pages, then copy the setup elsewhere Good
Watch apps that run in the same sandbox while you work on them Good
Watch an agent's dev servers during a long task Good, with idle pausing off and auto-stop extended
Production alerting for sites your customers use Poor. Run it on an always-on server, or use a hosted monitor. A monitor that stops is silent exactly when you need it

At a glance#

Everything below ran on one small sandbox (2 vCPU, 4 GB) in eu-central on October 27, 2026. Single runs, so treat timings as rough.

Check What we saw
Image louislam/uptime-kuma:1, version 1.23.17, 448 MB
Memory used in the whole VM, just after Kuma started 594 MB of 3.9 GB
Hosted URL without the token 401, for pages and for /socket.io/
Dashboard WebSocket through the hosted URL, with the cookie Logged in over websocket in 0.92 s, from a laptop
App stopped, check every 20 s First DOWN 7 s later, back UP 17 s after the app restarted
sbx stop --wait, 2 minutes, sbx resume memoryRestored: true, same PIDs, 128 s with no heartbeats and no DOWN
Idle pause with Kuma checking every 20 s Paused 96 s after the last API call with idle set to 1 minute
Reboot Kuma back with its monitors; an app started with systemd-run was not

1. Start Uptime Kuma#

Docker is preinstalled and running in every sandbox. The command follows Uptime Kuma's Docker install, with --restart unless-stopped so it comes back after a reboot, and one addition: --add-host lets Kuma reach servers running on the sandbox itself as host.docker.internal.

sbx new --name kuma --type small
id=sb_s0rmhm89da    # the id that sbx new printed

sbx exec $id --timeout 300 "docker run -d --name uptime-kuma --restart unless-stopped \
  -p 3001:3001 --add-host=host.docker.internal:host-gateway \
  -v uptime-kuma:/app/data louislam/uptime-kuma:1"
sbx exec $id "docker ps --format '{{.Names}} {{.Status}}'"
uptime-kuma Up 2 seconds (health: starting)

The named volume uptime-kuma holds Kuma's SQLite database: monitors, heartbeats, users and status pages. We used the 1 tag because the scripting client below was built for 1.x.

For something to watch, we started a small web server on the sandbox, port 8000:

sbx exec $id "mkdir -p ~/site && echo demo ok > ~/site/index.html && \
  sudo systemd-run -q --unit demo --uid=user --working-directory=/home/user/site python3 -m http.server 8000"

systemd-run is quick, but the unit it makes doesn't survive a reboot. See section 6.

2. Open the dashboard on a private URL#

sbx host $id 3001 --title "Uptime Kuma"
https://<subdomain>-3001.box.sandboxer.com?_token=<token>   # subdomain and token redacted

What the proxy returned, from a laptop:

Request Status
/ or /api/entry-page, no token 401 from the proxy. Kuma never sees it
The full URL with ?_token= 302 to /, sets the __sbx_auth cookie
/ with the cookie 302 to /dashboard
/socket.io/?EIO=4&transport=polling with the cookie 200
Same, no cookie 401

The dashboard runs over Socket.IO, so it needs WebSockets. They work through the hosted URL: a client sending the cookie connected with the websocket transport and logged in. Open the token URL in a browser, and Kuma asks you to create its admin account on first visit. That login is the second lock behind the token.

If you want a public status page, sbx host $id 3001 --public drops the token. Kuma's login then guards the dashboard on its own, so set the admin account up before you do that.

3. Add monitors from a script#

Kuma has no REST API for monitors. The dashboard talks Socket.IO. To script setup we used the community uptime-kuma-api Python client (1.2.1) inside the sandbox. The admin password is generated in the sandbox and never printed.

sbx scp kuma.py $id:/home/user/
sbx exec $id --timeout 300 "umask 077; openssl rand -hex 16 > ~/.kuma-admin; \
  python3 -m venv ~/kv && ~/kv/bin/pip -q install uptime-kuma-api && ~/kv/bin/python kuma.py setup"
# kuma.py (setup part)
import os
from uptime_kuma_api import UptimeKumaApi, MonitorType

pw = open(os.path.expanduser("~/.kuma-admin")).read().strip()
api = UptimeKumaApi("http://localhost:3001", timeout=30)
if api.need_setup():
    api.setup("admin", pw)
api.login("admin", pw)
a = api.add_monitor(type=MonitorType.HTTP, name="demo app",
                    url="http://host.docker.internal:8000/", interval=20, retryInterval=20, maxretries=0)
b = api.add_monitor(type=MonitorType.HTTP, name="example.com", url="https://example.com/", interval=60)
print("monitors", a["monitorID"], b["monitorID"])
print("version", api.info().get("version"))
api.disconnect()
monitors 1 2
version 1.23.17

maxretries=0 marks the monitor down on the first failed check. Kuma's default retries before declaring an outage, which is calmer but slower. Read heartbeats back with api.get_monitor_beats(monitor_id, 1) (the last hour).

4. Watch an app go down and come back#

We stopped the demo app at 10:29:27 UTC and started it again at 10:30:17:

== 1 demo app
10:29:14.697 UP    6 ms  200 - OK
10:29:34.708 DOWN        connect ECONNREFUSED 172.17.0.1:8000
10:29:54.714 DOWN        connect ECONNREFUSED 172.17.0.1:8000
10:30:14.721 DOWN        connect ECONNREFUSED 172.17.0.1:8000
10:30:34.726 UP    8 ms  200 - OK

host.docker.internal resolved to the Docker bridge, 172.17.0.1, so a server on the sandbox must listen on 0.0.0.0, not only 127.0.0.1. Checks against the sandbox's own apps took 3 to 11 ms. Checks of https://example.com from eu-central took about 70 ms.

5. What happens to checks while the sandbox is stopped#

We stopped the sandbox at 10:31:39, left it stopped for two minutes and resumed at 10:33:42:

sbx stop $id --wait
sbx resume $id --json | jq -c '{state, memoryRestored, resumeReason}'
{"state":"ready","memoryRestored":true,"resumeReason":null}

Kuma's process kept its PID, and the hosted URL went from 404 while stopped to 200 right after resume, with no new sbx host. The heartbeats show what a stop means for a monitor:

10:31:14.749 UP    4 ms   200 - OK
10:31:34.755 UP    8 ms   200 - OK
10:33:42.800 UP  346 ms   200 - OK
10:34:03.689 UP    3 ms   200 - OK

A 128-second hole, with no DOWN and no "monitor was offline" note. Kuma didn't run while frozen, so it saw nothing to report. The uptime percentage counts only the beats that exist, so it stays at 100%. If anything you watched broke during that window, Kuma never knew, and no notification went out. The first check after resume was slow (346 ms), then normal again.

Idle pausing#

The sandbox in this test came with idleStopMinutes 30 (it depends on your plan). We set it to 1 minute with sbx idle $id 1 and stopped making API calls. With Kuma checking every 20 seconds and the load average at 0.17, the sandbox paused 96 seconds later with "reason":"idle". Kuma's checks are local traffic, so they don't count as activity.

To keep a sandbox monitoring for a working session:

sbx idle $id 0            # never pause when idle
sbx extend $id --hours 12 # push out the auto-stop deadline

Auto-stop is a hard deadline even with idle pausing off. During the free trial, deadlines over eight hours and --no-auto-stop are refused. See long-running tasks.

6. After a reboot#

A resume boots from disk instead of restoring memory when it lands on a different CPU type. We tested that path with sudo systemctl reboot:

uptime-kuma Up 2 minutes (healthy)
inactive                                  # systemctl is-active demo
10:37:03.780 UP    4 ms   200 - OK
10:37:29.285 DOWN        connect ECONNREFUSED 172.17.0.1:8000

The Docker daemon starts at boot and --restart unless-stopped brought Kuma back, with both monitors and their history in the volume. The demo app, started with systemd-run, did not come back, and Kuma reported it down. Here the monitor did its job. For apps that should survive a cold boot, write a real unit file with WantedBy=multi-user.target and systemctl enable it, as the long-running docs show.

FAQ#

Can Uptime Kuma in a sandbox alert me when my production site is down?#

It can send alerts while the sandbox runs, but it can't promise to be running. It stops at the auto-stop deadline, and nothing tells you when it's paused or stopped. Use it to try Kuma or watch the sandbox's own apps, and run production monitoring on an always-on host.

Which size do I need?#

small (2 vCPU, 4 GB) was plenty. The whole VM used 594 MB just after Kuma started. Moving to a smaller size isn't supported yet, so start small and size up only if you add heavy apps next to it.

Does a request to the dashboard wake a paused sandbox?#

Yes, if it carries the token or cookie. A request to a hosted URL wakes a sandbox that paused for being idle. Kuma then resumes checking, but beats from the paused time are missing, not marked down.

How do I move my monitors to a permanent server?#

Kuma keeps everything in /app/data, which here is the uptime-kuma volume. Stop the container, pack that directory into a file, download it, and mount it on your server with the same image tag. We didn't run the migration. See move files in and out of a sandbox for the download.

Can Kuma monitor other sandboxes?#

Over their hosted URLs, yes; we only tested monitors of the sandbox's own apps and of a public site. A private URL answers 401 without its token, so a check either carries the token (which then sits in Kuma's database) or targets a port hosted with --public. Note that each check of a paused sandbox's URL wakes it. For metrics rather than up/down, see Grafana and Prometheus in a sandbox.

More guides

Top AI sandbox platforms for code execution in 2026, ranked

For running AI-written code we rank Sandboxer, Freestyle and E2B first: each gives code its own VM with an API or SDK and can pause with memory. Pick Daytona for Windows or GPUs, Modal or Northflank for GPUs at scale, E2B or Northflank to run in your own cloud, and Vercel Sandbox if your app lives on Vercel.

Read the guide
Best sandboxes for running coding agents (Claude Code, Codex, Gemini CLI) in 2026, ranked

For coding agents we rank Sandboxer first: a full Ubuntu VM with Claude Code and Codex preinstalled, Docker, and stop-and-resume that keeps the agent's session in memory. Freestyle and Amp Orbs also keep memory across pauses. Pick E2B for prebuilt agent templates on open source, Docker Sandboxes for free local runs, and Codespaces if you live in GitHub.

Read the guide
Best Daytona sandbox alternatives in 2026, ranked

The best Daytona alternatives depend on why you're switching. For a full Linux microVM on every sandbox with memory-saving stop and Docker, we rank Sandboxer first. E2B suits open source and self-hosting, Modal massive short-job fleets, Northflank bring-your-own-cloud with GPUs, and Vercel Sandbox apps on Vercel.

Read the guide
Best E2B alternatives in 2026, ranked

If you're leaving E2B for longer sessions or a fuller machine, we rank Sandboxer first, then Freestyle: both give each sandbox a full Linux VM that keeps memory across pauses, with Docker and no short session cap. Pick Daytona for Windows or GPUs, Northflank for bring-your-own-cloud, and stay on E2B if you need open source.

Read the guide