When we launched dacforge.com two days ago we shipped it with no analytics. No Google tag, no Plausible, no anything. The privacy posture on the home page said "we run our own infrastructure"; putting a third-party tracker on the site would have been a visible contradiction on line one.
Two days in, that stance had already stopped being defensible. The site had traffic we could not explain, referrers we could not trace, and pages whose value we could not compare. "No analytics" is a purist line that works until you need to make a decision, and then you have nothing. The honest move was not to hold the line; it was to pick a tool that would let us keep most of the privacy posture intact and add just enough visibility to act on.
Today we deployed Umami on the same Hetzner box that serves this site, behind https://analytics.dacforge.com, and flipped the tracker on in Base.astro. Here is what shipped, why Umami over the other four options we evaluated, and the short version of the legal posture on /privacy.
The constraints
Before tool shopping, we wrote down what would make a choice a yes or a no.
- Self-hosted. We cannot sell "run your own infrastructure" to clients while running a third-party tracker on our own site. Fathom and Simple Analytics (SaaS-only) fell out here.
- Cookieless. A cookie banner on our own site would advertise the same contradiction. Rules out GA4 as configured for most sites.
- Low maintenance. A 2-person studio does not want a tool that needs twice-yearly CPU-feature checks, SMTP config, three-database compose files, and UID-999 permission dances.
- Free to run. We already pay for the Hetzner box. No monthly SaaS fee.
- Cookieless implementation that survives legal review. First-party, no cross-site identifier, no cookies, clear disclosure, one-click opt-out.
Five tools cleared the first filter: Umami, Plausible Community Edition, GA4, GoAccess, and do-nothing. Umami won. The rest of this post is the build, then the short version of why the other four did not.
The build, in five minutes
Coolify one-click
Umami is an official Coolify one-click service in the Analytics category. The template is pinned to ghcr.io/umami-software/umami:3.0.3 with postgres:16-alpine, exposes port 3000 (which matches Coolify's UI default, so no port override), and uses Coolify's magic env vars to auto-generate the Postgres password and the Umami APP_SECRET. Practical human input is one field: the public domain.
From the Coolify UI:
- Resources, New Resource, Service, Umami
- Pick the project and environment
- Set the public domain to
analytics.dacforge.com - Deploy
Coolify issues the Let's Encrypt cert via Traefik. Postgres comes up alongside Umami in the same compose. Total elapsed: about five minutes, most of which is DNS propagation.
Log in to Umami at the public domain with the default admin / umami and change the password immediately. Add a website, note the generated data-website-id, and keep the browser tab open while you wire the script into the site.
Wiring the tracker into Astro
dacforge.com is a static Astro site rendered to HTML and served by nginx. The tracker is a single <script> tag in the shared Base.astro layout, gated behind a public env var so local builds do not report:
---
// src/layouts/Base.astro
const umamiSrc = import.meta.env.PUBLIC_UMAMI_SRC;
const umamiWebsiteId = import.meta.env.PUBLIC_UMAMI_WEBSITE_ID;
const umamiOrigin = umamiSrc ? new URL(umamiSrc).origin : null;
---
<head>
{/* ... existing head ... */}
{umamiOrigin && <link rel="preconnect" href={umamiOrigin} crossorigin />}
{umamiSrc && umamiWebsiteId && (
<script
defer
src={umamiSrc}
data-website-id={umamiWebsiteId}
data-do-not-track="true"
/>
)}
</head>
Two details matter here. data-do-not-track="true" tells Umami's script to short-circuit on any browser that sends Do Not Track or Global Privacy Control. And the env-var gate means npm run dev on a laptop does not pollute the dashboard with a developer's own pageviews; only the production build, which has PUBLIC_UMAMI_SRC and PUBLIC_UMAMI_WEBSITE_ID set in Coolify, actually renders the script.
Deploy, open the site, open the Umami dashboard, watch the pageview count tick up by one. If it does not, the two usual suspects are a typo in the website ID or an ad blocker on your own browser (uBlock Origin blocks Umami's default script path; the workaround is to serve the script from your own domain, which the Coolify template already handles).
The /privacy page
A tracker without a privacy page is table stakes wrong. Before flipping the env vars, we rewrote /privacy to cover four things:
- What we collect. Pageview, referrer, anonymised IP-derived country and city, user agent (device class, browser, OS). No cookies, no cross-site identifier, no profile join.
- Legal basis. UK: the Data (Use and Access) Act 2025 statistical-purposes PECR exemption, which commenced on 5 February 2026. EU: GDPR Art. 6(1)(f) legitimate interest, bounded retention, no ad targeting. US: we honour Global Privacy Control and Do Not Track signals at the tracker level.
- Retention. 13 months. Long enough to do year-over-year comparisons, short enough to bound the data. Umami's default is indefinite; the retention window is our add.
-
Opt-out. A visible toggle on the page that sets
localStorage.umami.disabled = 1and stops sending events from that browser. One click, no flow, no account.
We do not claim "no consent required, anywhere." The honest phrasing is "we rely on the UK DUAA statistical-purposes PECR exemption, on GDPR Art. 6(1)(f) legitimate interest in the EU, and we give you a one-click opt-out anyway."
What we ruled out
Plausible Community Edition. Shortest distance to a yes of any of the alternatives. It is cookieless, self-hostable, respected in the category. Three things tipped us away. AGPLv3's network-use clause is stricter than MIT for a studio that may fork or patch for client work. Practical RAM floor is ~1 GB with 2 GB recommended (ClickHouse is the cost) against Umami's ~512 MB; on a single Hetzner VPS that matters. And Plausible CE ships "twice annually" by explicit policy, gating funnels, SSO, Sites API, and advanced bot filtering to the cloud product. Coolify also does not ship a one-click for Plausible because of a trademark restriction, which pushes deploy time from five minutes to an hour of compose, SMTP, and port-override work.
GA4. Off the table for a privacy-positioned studio regardless of tooling. Third-party cookies, data leaves your infrastructure, consent banner required for most of the EU, and the regulatory blast radius is non-trivial. California's Capital One action in May 2025 (around $350k) targeted third-party pixels behind a broken consent UI; first-party cookieless counters on a site honouring Global Privacy Control are not the same category, but the GA-shaped risk is not one we are interested in carrying.
GoAccess. A log-based analyzer that reads nginx access logs and produces an HTML dashboard. Zero privacy cost, no client JS, no database. The reason it did not win is that it cannot see what a client-side tracker sees: no engagement time, no event funnels, no bounce-versus-read distinction. And it adds its own ops cost: a bind-mount from the nginx container, logrotate to coordinate with the real-time HTML refresh. GoAccess stays on the shortlist as a future sidecar for bot and bandwidth visibility, not a replacement for Umami.
Do-nothing. The version where we literally know nothing about visitor behaviour. Purest privacy posture available, and untenable past launch. We could not make page-investment or content decisions from zero data, and "no analytics" became the thing blocking useful ones.
If you want the same setup
The whole stack is one Hetzner box running Coolify, with nginx-served dacforge.com and Umami on the same host, Let's Encrypt via Traefik, Postgres per app. If you want a walk-through for your own site we offer a Coolify setup consultant engagement that covers the same ground end to end, and a DevOps consultant for small business engagement for the broader infra picture (boring infrastructure is a feature; it should not be somebody's side quest).
Or email hello@dacforge.com if you want to talk about shipping something together.
This article was originally published by DEV Community and written by DacForge.
Read original article on DEV Community