v0.3.1
A patch, and for the ordinary compose path an empty one: nothing here changes
what a docker-compose.yml install runs. Everything below is the Coolify
variant, which went from a file that had been read to a stack that has been run.
git fetch --tags && git checkout v0.3.1
cd infra/selfhost && ./upgrade.shThe Coolify variant has now been deployed, and it took five fixes
infra/selfhost/docker-compose.coolify.yml was written by reading, and every one
of these was invisible until it ran on Coolify 4.3.2 against real DNS and real
certificates.
- The migration one-shot did not run migrations. It is the worker's image
under another tag, so with no entrypoint of its own it booted as the worker,
loaded the worker's schema, and was refused by the least-privilege boundary:
CLICKHOUSE_MIGRATION_PASSWORD: must not be provided to the "worker" service.
The boundary was right; the file was missing a line the stock compose file has
always had. - The ClickHouse database was named wrong.
openanalytics, where every grant
inclickhouse/oa-entrypoint.shis written againstanalytics.<table>by name
rather thananalytics.*. The stack would have come up green and failed on the
first read with a permission error naming a table nobody had renamed. GEOIP_DB_PATHwas set on a volume that starts empty. A path is a promise:
the collector reads it at boot and refuses to start when the file is not there.
On a platform with no checkout to download into, that turned the documented
degradation into a crash loop. Unset is what an install with no database
should say.- The dashboard was probed on a route it does not serve. The shared
healthcheck asks for/health; the six backend services answer it and a
Next.js app does not. Sowebanswered404forever, never turned healthy,
and the proxy served "no available server" in front of a dashboard whose own
log saidReady in 283ms. - The public services did not say which port they listen on. Traefik takes a
container's port from the ports it exposes, and the six backend services share
a Dockerfile that declares none. The collector's router was therefore
unroutable, was dropped, and its certificate was never even requested. Nothing
logged it: the hostname simply did not answer while the container beside it was
healthy.expose:publishes nothing to the host and is exactly the metadata
these platforms read, so declaring it fixes every one of them at once rather
than asking an operator to type a port they have no way to know.
What now holds on a live install, rather than in a file: all thirteen
containers correct, four hostnames on HTTPS with Let's Encrypt certificates, an
account and a site created through the dashboard, and three page views accepted
by the collector, drained through the queue by the worker and stored in
ClickHouse.
The client-identity middleware works, and that is the one that mattered. Every
forged header is deleted before it reaches the collector: CF-Connecting-IP,
CF-IPCountry, CF-IPCity, True-Client-IP, Fly-Client-IP,
Fly-Client-Country, X-Vercel-IP-Country, X-Vercel-IP-City, with
X-Forwarded-For left carrying the real connection address. Proven twice: once
against an echo service behind the same middleware, and once by sending
CF-IPCountry: XX with a real page view and finding the stored row's country
empty rather than XX.
Still not a supported path, because one install on one platform is a
demonstration rather than a promise. It is no longer a file nobody has run.
A correction, and one that matters when you cut a release
RELEASING.md said a GHCR package is private when first created and needs a
visit to its settings page. That was true on v0.1.0 for the original eight. It
was not true on v0.3.0 for clickhouse and valkey, which came out public
with nothing clicked. Two data points and no announced change between them, so
the section now says to check rather than to believe either answer, and gives the
one command that checks it from a machine with no GHCR login.
Images
Ten, published to ghcr.io/openlabs-so/openanalytics and tagged v0.3.1:
migrate, tracker-build, api, collector, worker, query-gateway,
realtime, web, clickhouse, valkey. amd64. On arm64, build them instead:
same compose file, one flag.
Their contents are unchanged from v0.3.0. The tag moves because the compose
file, the env templates and the migrations ship with the images and a release is
one commit.
RELEASING.md
is what a version number here means.
Full changelog: v0.3.0...v0.3.1