Docker & HTTPS
Use this path for a homelab, NAS with Docker Compose, or VPS. You need Docker Engine or Docker Desktop with Compose, outbound access to GHCR, and a disk for persistent data. The image supports linux/amd64 and linux/arm64.
HTTP: local first run
Download two small files — no clone or build:
mkdir -p servomon && cd servomon
curl -fsSLo compose.yaml https://raw.githubusercontent.com/nirjan-dev/servomon/main/deploy/compose.yaml
curl -fsSLo .env https://raw.githubusercontent.com/nirjan-dev/servomon/main/deploy/.env.exampleEdit .env, replacing NUXT_BASIC_AUTH_USERS with your own user:strong-password pair. Leave NUXT_BASIC_AUTH_ENABLED=true.
docker compose up -d
docker compose logs -fOpen http://localhost:3000. The app listens on port 3000 and stores data in the named volume mounted at /app/data. HTTP on a published port is not safe for transmitting credentials across a network; add HTTPS before remote use.
HTTPS with Caddy
Give your host a domain such as monitor.example.com, with DNS pointing at it. Permit inbound TCP 80 and 443 so Caddy can obtain a publicly trusted certificate. If behind a router, forward those ports to the Docker host.
Download the standalone HTTPS compose file; it is not an override to merge with the HTTP file:
curl -fsSLo compose.https.yaml https://raw.githubusercontent.com/nirjan-dev/servomon/main/deploy/compose.https.yamlIn .env, set SERVOMON_DOMAIN=monitor.example.com and your operator credentials. If you started the HTTP file above, stop that stack first (do not add -v; keep its data volume):
docker compose down
docker compose -f compose.https.yaml up -dOpen https://monitor.example.com, then install your first agent. Caddy is the public entry point; the app's port is not published to the host. Keep Caddy's certificate volumes as well as the app data volume.
LAN-only HTTPS options
You do not have to expose the dashboard to the internet:
- Tailscale Serve: keep the HTTP app reachable only from the local proxy, then expose it to your tailnet using Tailscale Serve. Use its HTTPS URL for
SERVER_URL. All agent machines need access to that tailnet. - Cloudflare Tunnel: run cloudflared to proxy a hostname to the app without inbound router ports. Preserve WebSocket upgrades and unbuffered SSE. Extra identity-provider gates must not intercept the agent's enrollment and bearer-authenticated API traffic. This is a proxy option, not deployment to Cloudflare Workers.
- Caddy internal CA: for private hostnames, append
--internal-certsto the Caddy command incompose.https.yaml.localhostuses Caddy's local CA automatically. Trust Caddy's root CA on every browser/phone and agent. See Caddy's local HTTPS guidance.
For an internal-CA installation, copy Caddy's root certificate to the directory where you run the installer:
docker compose -f compose.https.yaml cp caddy:/data/caddy/pki/authorities/local/root.crt ./servomon-ca.crt
curl -fsSL https://github.com/nirjan-dev/servomon/releases/latest/download/install.sh | sh -s -- --server https://monitor.home.arpa --ca-cert ./servomon-ca.crtReplace the hostname with yours. On a different agent machine, securely copy servomon-ca.crt there first and verify it came from your Caddy instance. The installer saves it as /opt/servomon-agent/ca.crt, supplies it during enrollment, and sets Environment=DENO_CERT=/opt/servomon-agent/ca.crt in the service unit. Re-runs preserve it.
Compiled agents honor DENO_CERT only in the process environment, not when put in the agent's .env file. Manual runs can use DENO_CERT=/path/ca.crt ./servomon-agent. Alternatively, install the CA in the OS trust store and set DENO_TLS_CA_STORE=system in the systemd unit environment. Never disable certificate verification.
Browsers and phones must also trust the CA for a trusted secure context (push/PWA). Tailscale Serve, Cloudflare Tunnel, or a real domain with a publicly trusted certificate (including DNS-challenge issuance where appropriate) are easier LAN choices if you do not want to manage device trust.
Why HTTPS matters
Operator login and agent tokens travel in HTTP headers. Tickets do not make cleartext HTTP safe. Browser push and installable PWA features also need a secure context (HTTPS, with localhost exceptions). A LAN is not a substitute for TLS.
Upgrade and backup
Back up the persistent /app/data volume before upgrading. For the HTTP stack:
docker compose pull
docker compose up -dFor HTTPS, use docker compose -f compose.https.yaml for both commands. Keep one application instance. Never use docker compose down -v unless you intend to delete the volumes and their data. Image tags include latest, 0.1 and 0.1.0; pin the full version in your compose file for controlled upgrades.