Artifact 841c4cd8ede10b0db25d078360e20a486b459995eeb528d5e41a434c9a56ba9e:
- File
compose.yml
— part of check-in
[bbe731e042]
at
2026-08-17 16:40:19
on branch trunk
— deploy: Dockerfile, compose stack and a run book
quarry had no packaging at all while notify already had a working Dockerfile and compose. The image ships zit WITH quarry, deliberately: 0001 §2 makes the zit CLI the entire store interface, so zit's behaviour IS quarry's, and today alone three zit builds changed what quarry does — frames got faster, a card fix changed which artifacts parse, stat -R enabled bare-store serving. ZIT_REF is a build argument and /etc/quarry-build records the pair, so a container can answer which zit it carries.
compose follows notify's shape, including the constraint its own file documents: dagnats binds loopback in standalone mode, so everything shares its network namespace. quarry joins it too — its embedded NATS uses DontListen and binds nothing, so there is no port to collide with.
docs/running.md is the by-hand path, which is what this was actually developed against: the launchd-signed dagnats, notify's bootstrap and workflows, the topic-vs-subscriber addressing, and the two credentials that close the write and push gates.
Unverified, and said so in the doc: no container runtime is installed here, so the images have never been built. The two build recipes inside them ARE verified natively — zit compiles from a clean clone with zig build --release=fast, quarry builds fully static with CGO_ENABLED=0.
Also lands the publish-throughput measurement as an opt-in test. It is what disproved the hypothesis that synchronous publish was the ingest bottleneck (62k msg/s sync), which redirected the search to zit frames and quarry's folding. (user: dmestas, size: 3574) [annotate] [blame] [check-ins using]
name: quarry # The full forge: quarry, plus the notify companion and the dagnats engine # notify runs on. Modelled on notify's own compose, which established the # shape — dagnats' embedded NATS binds LOOPBACK in standalone mode, so # anything talking to it must share its network namespace rather than # reach it by service DNS. # # quarry joins that namespace too, for two reasons. It reaches notify at # 127.0.0.1:3000 with no extra plumbing, and its OWN embedded NATS binds # nothing at all (events.Start uses DontListen), so there is no port to # collide with dagnats' 4222. quarry keeps its embedded event plane here; # --nats can point it at dagnats' NATS instead when a second node exists, # which is the same flag scale-out already uses. # # SQLite is single-writer and file-backed in BOTH notify and quarry: run # exactly one of each per data volume. Scaling out is a datastore change, # not a compose change. # # docker compose up --build # docker compose run --rm quarry account add --user you --admin --data /data # # NOTIFY_SRC must point at a notify checkout; its Dockerfile builds both # the notify server and the dagnats sidecar as separate targets. services: dagnats: build: context: ${NOTIFY_SRC:-../notify} target: dagnats environment: DAGNATS_HTTP_ADDR: 0.0.0.0:8080 DAGNATS_DATA_DIR: /data volumes: - dagnats-data:/data ports: # Every service in this namespace publishes here, because dagnats # owns the namespace. quarry's UI: - "${QUARRY_HOST_PORT:-8950}:8081" # notify's API: - "${NOTIFY_HOST_PORT:-3000}:3000" # dagnats' own console is UNAUTHENTICATED, so it is bound to # loopback deliberately and never 0.0.0.0. - "127.0.0.1:${DAGNATS_CONSOLE_HOST_PORT:-8081}:8080" restart: unless-stopped notify: build: context: ${NOTIFY_SRC:-../notify} target: notify depends_on: dagnats: condition: service_started network_mode: "service:dagnats" environment: NOTIFY_ADDR: 127.0.0.1:3000 NOTIFY_DB: /data/notify.db NOTIFY_NATS_URL: nats://127.0.0.1:4222 NOTIFY_BRIDGE_URL: http://127.0.0.1:8080 # Required outside dev: without it notify derives a fixed, # publicly-known key. Set NOTIFY_DEV=1 only for local work. NOTIFY_MASTER_KEY_HEX: ${NOTIFY_MASTER_KEY_HEX:-} NOTIFY_DEV: ${NOTIFY_DEV:-} volumes: - notify-data:/data restart: unless-stopped quarry: build: context: . args: # Pin the store implementation. Floating this is what lets two # deploys of the same quarry disagree about which artifacts parse. ZIT_REF: ${ZIT_REF:-trunk} VERSION: ${QUARRY_VERSION:-0.0.0-dev} depends_on: notify: condition: service_started network_mode: "service:dagnats" volumes: # Read-only: quarry never writes a store except through zit, and # the sync/write paths go through the same binary. Drop :ro when # enabling the write plane against these repositories. - ${QUARRY_REPOS:-./repos}:/repos:ro - quarry-data:/data command: - serve - --addr=127.0.0.1:8081 - --data=/data - --notify=http://127.0.0.1:3000 # The notify console API key, from `notify bootstrap`. - --notify-key=${QUARRY_NOTIFY_KEY:-} # One --repo per store. Names are the forge's; paths are inside the # container. - --repo=quarry=/repos/quarry restart: unless-stopped volumes: dagnats-data: notify-data: quarry-data: