Self-host Plausible Analytics in an Afternoon

Self-hosting Plausible Analytics in an Afternoon: Own Your Data, Ditch the Vendor Lock-in

You're tired of Google Analytics bloat. You want privacy-first analytics without the cookie banners. You need data sovereignty without the SaaS pricing treadmill. Here's how we built our own analytics infrastructure in one afternoon — and why you should too.

Why Self-host Analytics? Four Wins You Can't Buy

Data ownership matters. Your analytics live on your box, not a vendor's. No third-party data sharing, no surprise policy changes, no vendor deciding your data is suddenly worth more.

Privacy by design. Plausible Community Edition is cookieless and GDPR-friendly. No consent banners required. Your visitors get a 1KB script instead of Google's heavyweight tag.

Cost control. No per-pageview SaaS pricing as your traffic grows. One instance handles every property you run — we track four sites from a single deployment.

One dashboard, all properties. Manage analytics for eleven11.pro, blog.eleven11.pro, and audit.eleven11.pro from one interface. Add new sites without new subscriptions.

What We Built: The Stack

We deployed Plausible Community Edition v3.2.1 on a single Hetzner server running Docker Compose. The architecture is straightforward:

  • App layer: Plausible (Elixir/Phoenix) serves the dashboard and tracking script
  • Data layer: Postgres 16-alpine stores user accounts and site configs; ClickHouse 24.12-alpine handles event analytics
  • Edge layer: Caddy reverse proxy with automatic Let's Encrypt; Cloudflare for DNS and DDoS protection

The result: analytics.eleven11.pro tracking our entire web presence from one self-managed instance.

The Implementation: Docker Compose + Caddy

Network Setup First

Put your Plausible containers on the same Docker network as your reverse proxy. We use a shared e11-edge network so Caddy can resolve the app container by name:

networks:
  e11-edge:
    external: true

Caddy Configuration: One Line

Your reverse proxy config is dead simple. In Caddy:

analytics.eleven11.pro {
    reverse_proxy plausible:8000
}

Caddy handles TLS automatically. The container name plausible resolves because both containers join the same Docker network.

Environment Variables That Matter

Two secrets control your deployment:

  • SECRET_KEY_BASE: Signs user sessions (generate with openssl rand -base64 64)
  • TOTP_VAULT_KEY: Encrypts 2FA secrets (generate with openssl rand -base64 32)

Both are service-managed. Rotating them logs everyone out and breaks existing 2FA setups.

For registration, set DISABLE_REGISTRATION=invite_only. The first owner account can self-register, then public signup locks down. Set ENABLE_EMAIL_VERIFICATION=false so you can log in without configuring SMTP first.

The Gotchas: What Breaks and How to Fix It

SELinux Will Block Database Writes

On SELinux-enforcing hosts, containers with named volumes need label handling or database writes fail as read-only. Add this to your database containers:

security_opt:
  - label:disable

DNS and TLS Timing

Grey-cloud your DNS record (DNS-only mode) until the Let's Encrypt cert issues. Once the cert is live, flip to orange-cloud. If you go orange first, the ACME challenge fails behind Cloudflare's proxy. After the cert is issued, switch to Full (strict) SSL mode for end-to-end encryption.

Container Resolution

Your reverse proxy must resolve the app container by name. If Caddy can't reach plausible:8000, verify both containers joined the same Docker network.

Tracking Setup: Cookieless and Clean

Plausible uses a first-party script model. Each site gets a data-domain attribute pointing to your analytics instance:

<script defer data-domain="eleven11.pro" src="https://analytics.eleven11.pro/js/script.js"></script>

One instance serves different tracking configs per domain. No cookies, no consent banners, no privacy theater. The script is ~1KB versus Google Analytics' heavier tag.

The Time Investment: Half-Day Project

Wall-clock time breaks down like this:

  • DNS setup: 5 minutes (plus propagation wait)
  • Docker image pulls: 15–30 minutes depending on connection
  • Configuration: 30 minutes
  • TLS certificate issuance: 5 minutes
  • Testing and validation: 15 minutes

If you already run Docker and a reverse proxy, this is a half-day project, not a platform migration. Most of the time is waiting for DNS and image downloads.

Why This Matters for Engineering Leaders

Sovereignty beats convenience. You control the data, the uptime, and the feature roadmap. No vendor can sunset your analytics or change pricing overnight.

Privacy as a competitive advantage. Your visitors get faster page loads and better privacy. No third-party tracking, no data brokers, no surveillance capitalism.

Cost predictability. Your analytics cost is your server cost. Traffic growth doesn't trigger billing surprises or force plan upgrades.

Technical simplicity. Three containers, one network, standard Docker patterns. Your team can debug, backup, and maintain this without vendor-specific expertise.

The Bottom Line

For founders and engineering leaders who already self-host infrastructure: owning your analytics is a low-cost, high-sovereignty win you can ship this week.

We built analytics.eleven11.pro in one afternoon. It tracks four properties, serves cookieless analytics to thousands of visitors, and costs us exactly one server's worth of resources. No subscriptions, no per-seat pricing, no vendor lock-in.

Your data belongs on your infrastructure. Plausible Community Edition makes that practical without sacrificing functionality or user experience.