v0.3.0
A minor, and the number means what it says: read this before upgrading.
./upgrade.sh still does the work and there is nothing to run by hand, but two
of the images you pull are new and one thing you may have edited moved.
git fetch --tags && git checkout v0.3.0
cd infra/selfhost && ./upgrade.shTen images, not eight
clickhouse and valkey are now ours. They are upstream's images plus the files
they cannot start correctly without: ClickHouse's config drop-in and the
entrypoint that renders its four least-privilege users, and Valkey's two policy
files and its entrypoint. Those five files used to arrive as bind mounts from
infra/selfhost/.
Why this changed. A bind mount works when the compose file sits in a
checkout and nowhere else. A one-click platform clones the repository, writes the
rendered compose file and nothing beside it, so Docker creates an empty
directory for every missing bind source and ClickHouse dies with
oa-entrypoint.sh: Is a directory. Measured on Coolify 4.3.2. Every platform in
that category behaves the same way, so this was the last thing between the
project and a marketplace listing.
The files still live where they did, in clickhouse/ and valkey/, and are
copied into the images at build. There is one of each in the tree.
If you edited one of those files in place, it now has no effect. Two ways
back: bind-mount over the baked copy, which still wins, or build instead of pull
(./upgrade.sh --from-source). The five files are exactly the ones listed above;
nothing else moved.
One image serves both Valkeys. The queue and the realtime cache are the same
server under opposite policy, so both configs ship in it and OA_VALKEY_CONF
names which applies. A container started without it refuses rather than guesses:
a cache policy on the queue would evict acknowledged events before the worker
inserted them.
The plaintext Valkey check accepts a service name
buildConnectionOptions refuses a plaintext redis:// whose host it cannot
prove is private, and it proved that by matching the hostname against the RFC1918
literals. A compose service name matches none of them, so the check had no answer
for a name and refused every one.
It now also accepts a single-label name such as valkey-queue: a label with
no TLD has no public resolver that can answer it. A host with a dot in it outside
the private ranges is still refused, TLS is still required where the hop may be
public, and AUTH is still required everywhere. This is what lets a platform that
allocates its own network run the stack, since none of them lets a template pin
an address inside it.
The caveat, stated rather than hidden: a host configured with a DNS search suffix
can resolve a bare label to something off the machine. That needs an operator who
set a search domain and then wrote a bare label into a Valkey URL.
Coolify
infra/selfhost/docker-compose.coolify.yml has now been run on a real Coolify
install rather than only read. Two things that could not be checked any other way
both hold: the client-identity middleware is genuinely attached to the router
Coolify generates, and the SERVICE_FQDN_*, SERVICE_PASSWORD_* and
SERVICE_BASE64_* variables are filled in from the compose file with nothing
typed by hand.
Still not a supported path, and it will say so until an install has been run end
to end and watched.
One difference to know about there: /geoip is a named volume that starts empty,
because that platform has no checkout to mount a database from. Geo is null until
you copy one in, which is the documented degradation rather than a failure.
SELF-HOSTING.md says how under GeoIP.
Images
Ten, published to ghcr.io/openlabs-so/openanalytics and tagged v0.3.0:
migrate, tracker-build, api, collector, worker, query-gateway,
realtime, web, clickhouse, valkey. amd64. On arm64, build them instead:
same compose file, one flag.
Migrations do not go down. ./upgrade.sh takes the snapshot ./rollback.sh
needs before it starts, and a rollback discards everything recorded after it.
RELEASING.md
is what a version number here means.
Full changelog: v0.2.1...v0.3.0