Two-container stack (umami + postgres) deployed to the hetzner host via a remote Docker context, attached to npm_default so Nginx Proxy Manager fronts stats.gethumanai.pl. Secrets live in a gitignored .env. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| .env.example | ||
| .gitignore | ||
| deploy.sh | ||
| docker-compose.yml | ||
| README.md | ||
Umami
Self-hosted privacy-friendly web analytics, served at stats.gethumanai.pl.
Runs as two containers (umami + umami-db PostgreSQL) on the hetzner host,
deployed via a remote Docker context — same convention as humanai-web.
umami joins the npm_default network so Nginx Proxy Manager can proxy it by
container name; no host port is exposed.
Layout
| File | Purpose |
|---|---|
docker-compose.yml |
umami app + postgres + volume + networks |
.env.example |
template for the two required secrets |
.env |
real secrets — gitignored, never commit |
deploy.sh |
pulls images on the remote, starts the stack, smoke-tests /api/heartbeat |
First-time setup
cp .env.example .env
# fill in:
# openssl rand -hex 32 -> APP_SECRET
# openssl rand -hex 24 -> POSTGRES_PASSWORD
Deploy
./deploy.sh
The script creates the hetzner Docker context if missing, verifies the
npm_default network exists, runs docker compose up -d --pull always, waits
for the umami healthcheck, and smoke-tests the heartbeat endpoint.
Manual step in Nginx Proxy Manager
Add a Proxy Host:
| Field | Value |
|---|---|
| Domain | stats.gethumanai.pl |
| Scheme | http |
| Forward hostname | umami |
| Forward port | 3000 |
| Websockets | on |
| SSL | request a Let's Encrypt cert + Force SSL |
Then open https://stats.gethumanai.pl, log in with the default admin / umami, and change the password immediately.
Add the tracking snippet
In Umami: Settings → Websites → Add (domain gethumanai.pl), then copy the
generated <script> tag into the humanai-web site's index.html.