Skip to content
quarry Artifact [f9e4c47453]
Login

Artifact [f9e4c47453]

Artifact f9e4c474530c6504e2d8ef1a72145fbd265818c9f9747693c691ac16713a1b9a:


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: .
      additional_contexts:
        # zit's source. A named context rather than a clone: the
        # repository is private, and this pins exactly the checkout being
        # shipped. ZIT_SRC must point at a zit working tree.
        zit: ${ZIT_SRC:-../zit}
      args:
        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: