
Deploy Offen | (Just Updated) Google Analytics Alternative With A Login Nobody Can Brute-Force
Privacy-first analytics your visitors control, with brute-force protection
postgres
Just deployed
/var/lib/postgresql
Just deployed
Deploy and Host Offen Fair Web Analytics on Railway
Offen Fair Web Analytics is a self-hosted, radically privacy-first alternative to Google Analytics. Collection is strictly opt-in, usage data is end-to-end encrypted in the visitor's browser before it is sent, no IP addresses or User-Agent strings are ever stored, and every tracked visitor can open an "Auditorium" to read, export or delete the data collected about them. This template deploys Offen v1.4.2 with PostgreSQL, an operator account seeded before the server accepts its first request, and — unlike every other Offen template on Railway — Offen's own brute-force throttle left switched on.
About Hosting Offen Fair Web Analytics
Offen is a single Go binary that serves three things at once: the operator console where you read your traffic, the consent tool your visitors answer, and the Auditorium where they inspect their own data. It keeps everything in PostgreSQL, so the application service itself is stateless and the database is the only thing to back up.
Two Railway-specific details decide whether the deployment is sound, and both are handled here.
The login throttle stays on. Offen replaces its rate limiter with a no-op whenever
OFFEN_SERVER_REVERSEPROXY is set, and that limiter is the only brute-force protection in
the product — it guards login, password reset, password change, invitations and the
user-secret exchange. The flag is tempting on Railway because Railway terminates TLS at its
edge, but Offen's throttle keys on the submitted username and on a global bucket rather than
on the client address, so it behaves correctly behind a proxy and the flag buys nothing.
Measured on identical instances, fifteen wrong-password login attempts complete in 0.30
seconds with the flag set and 7.63 seconds without it. This template leaves it off, and the
entrypoint unsets it even if the environment carries it.
The operator account exists before the URL does. The first operator is seeded from the
generated OFFEN_ADMIN_PASSWORD during startup, before the server binds a port, and the
container refuses to boot on an empty password rather than coming up in a half-configured
state. Migrations run first, with a retry loop so a cold PostgreSQL never fails the deploy.
The deploy form asks for nothing. Every value — the database URL, the base64 application secret, the operator email and the operator password — is generated or wired for you, so there is no required field left blank and nothing to look up before clicking deploy.
Typical cost is about $5/month on Railway for the Go service and PostgreSQL. Offen is free and open source under Apache-2.0.
Common Use Cases
- A GDPR-first replacement for Google Analytics — opt-in only, no IPs, no cookies for visitors who decline, and nothing sent to a third party.
- Analytics you can defend to your users — point visitors at the Auditorium so they can see and delete exactly what was collected about them.
- Multi-site reporting from one installation — track several websites from a single deployment, with accounts shared across a team.
- First-party traffic measurement for EU/consent-sensitive products — encrypted at the client, stored on infrastructure you own.
Dependencies for Offen Fair Web Analytics Hosting
- A Railway account — roughly $5/month for the application and PostgreSQL
- PostgreSQL (included in this template, with a persistent volume)
- A website where you can add a one-line script tag
- Nothing else — Offen is a single self-contained Go binary
Deployment Dependencies
Implementation Details
Two services deploy on Railway's private network. The offen service runs
ghcr.io/bon5co/offen-railway:1.4.2, which pins upstream offen/offen:v1.4.2 by digest;
the postgres service runs postgres:17.6-alpine with a volume mounted at
/var/lib/postgresql, leaving PGDATA at its default subdirectory so the entrypoint
creates and owns it correctly.
On boot the wrapper validates its inputs (the operator password against Offen's 8–64
character rule, OFFEN_SECRET as standard base64) and refuses to start on an empty
credential; unsets OFFEN_SERVER_REVERSEPROXY so the rate limiter is the real one; runs
offen migrate with a retry loop until PostgreSQL answers; seeds the first operator with
offen setup, which is idempotent across redeploys; drops the admin password from the
served process's environment; and execs the stock server on Railway's injected port. The
health check probes /healthz.
The first analytics account is created with a fixed identifier so the tracker snippet is the same for every deployment of this template. Add it to any page you want to measure:
Events older than the retention window (six months by default) are pruned hourly by the web
process itself, so no scheduler service is needed. SMTP is not configured, which means
password-reset and invitation email will not send — keep the generated operator password,
and keep OFFEN_SECRET stable across redeploys.
Why Deploy Offen Fair Web Analytics on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Offen on Railway you get managed HTTPS, private networking between the app and its database, a persistent PostgreSQL volume, and generated secrets — with the two settings that actually matter on this platform already correct: an operator account that exists before the public URL does, and a login endpoint that still throttles.
Template Content
