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
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 redactedWhat 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.17maxretries=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 - OKhost.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 - OKA 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 deadlineAuto-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:8000The 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.
Related#
More guides
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.
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.
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.
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.