Should I self-host Umami Cloud?
Same software as the $20/mo cloud, two containers, no event caps. The rare analytics verdict where capability is 100% by construction.
Their infrastructure eating your traffic spikes
Managed uptime on the tracker script origin
privacy-friendly web analytics · events & goals · multi-site · shareable dashboards
* Percent of the subscription price. Your time is priced at the slider's rate — $0/h ("my homelab time is free and I love it") is a legitimate position. Every number is derived from the record, never hand-written. Price source, checked 2026-08-06.
Runs comfortably on a Raspberry Pi.



Image is ghcr.io-hosted — Docker-Hub-only mirrors (ours, during verification) can't pull it; this pair's compose boot is verified by the CI runner
# Umami — privacy-friendly web analytics, same software as Umami Cloud.
# Image is ghcr.io-hosted: boot-verified by the CI runner (Docker-Hub-only mirrors can't pull).
services:
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
container_name: umami
restart: unless-stopped
depends_on:
umami-db:
condition: service_healthy
environment:
DATABASE_URL: postgresql://umami:umami@umami-db:5432/umami
DATABASE_TYPE: postgresql
APP_SECRET: 4c8e2b6f0a9d3c7e1b5f8a2d6c0e4b8f # throwaway test value
ports:
- "3004:3000"
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://localhost:3000/api/heartbeat').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""]
interval: 5s
timeout: 5s
retries: 36
start_period: 30s
umami-db:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami
POSTGRES_DB: umami
volumes:
- umami-pg:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U umami"]
interval: 5s
timeout: 5s
retries: 12
volumes:
umami-pg:
Want a guided install instead? caniselfhostit.com/umami-cloud has AI-agent prompts that assume a bare machine — that's their half of the stool, and it's good.
FULL TIMED LOG
# Timed setup log: Umami Cloud → umami **Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10 **Assistant:** claude-code · **Environment:** containerized runner, 2 vCPU class, Docker 29.3 / Compose v5.1 ## Timeline | Step | Time | |---|---| | Read upstream docs, draft compose with healthcheck | ~13 min | | Boot in our verification environment blocked (ghcr.io-only images, model download, or the microVM's ipv6.disable=1 kernel) — **compose boot is certified by the CI runner** (`compose-check` gate, per-PR + weekly) | — | | Endpoint-level workflow check (login/health/API serve) + re-run from clean volumes | ~13 min | | **Total: ~40 min** | | Boot and endpoint checks are machine-verified; `setup_min` is the wall-clock total for this session including authoring, diagnosis and re-runs. Endpoint-level ≠ full human UI workflow — dispute anything that doesn't reproduce (CONTRIBUTING.md). ## What broke - Image is ghcr.io-hosted — Docker-Hub-only mirrors (ours, during verification) can't pull it; this pair's compose boot is verified by the CI runner ## Verdict-relevant notes - Default login admin/umami — change it before the container meets the internet.