Parallel deploy target to the systemd units that landed in a59ef5b.
Single image carries all 11 daemons; docker-compose runs one
container per daemon with the same dependency graph as the systemd
units. Useful when systemd isn't available (Mac dev, remote VMs
without root) or when isolation to a private docker network is
preferred.
Dockerfile (multi-stage):
- Builder: golang:1.25-bookworm. DuckDB cgo needs gcc + glibc;
alpine's musl doesn't link the official duckdb-go bindings cleanly.
- Runtime: debian:bookworm-slim — same libc, much smaller surface.
Adds ca-certificates (outbound HTTPS to OpenRouter/OpenCode/Kimi),
curl + jq (in-container healthchecks + smoke probes), tini (PID 1
signal forwarding so docker stop sends SIGTERM to the daemon, not
to a wrapper).
- Single image, multiple binaries. Ships all 11 cmd/* + 3 scripts/
(staffing_workers, playbook_lift, multi_coord_stress) so deployed
stacks can run reality tests against themselves.
- Non-root runtime user (uid 999 lakehouse). Layout matches
/usr/local/bin/lakehouse/<daemon> from REPLICATION.md.
- ENTRYPOINT=tini; no default CMD — operators / compose pick
which daemon explicitly.
docker-compose.yml (11 services):
- Same dependency graph as deploy/systemd/. depends_on with
service_healthy condition matches Requires= equivalents:
catalogd → storaged
ingestd → storaged + catalogd
queryd → catalogd
matrixd → embedd + vectord
- Gateway uses bare depends_on (no health condition) — Wants=
equivalent so single-upstream restart doesn't cascade.
- chatd has per-provider env_file entries (one each for
ollama_cloud, openrouter, opencode, kimi) — missing files are
silently OK, matching the systemd unit's EnvironmentFile=- list.
- Persistent state on the lakehouse-state named volume; commented
driver_opts shows how to bind to a host path for off-volume
backups.
.dockerignore:
- Excludes bin/ + reports/ + data/ + git metadata + .env files.
- Especially excludes lakehouse.toml/secrets-go.toml/auth.env so
local dev configs don't accidentally bake into a published image.
REPLICATION.md gains a Docker section between systemd setup and
the logs section. Ten-line copy-paste from "git clone" to
"docker compose up -d", plus a docker-vs-systemd differences
table covering process supervision, logs, restart policy, file
ownership, host networking quirks, and backup targets.
Validation: docker compose config --quiet → exit 0 (with
placeholder env files in place).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
809 B
Plaintext
38 lines
809 B
Plaintext
# Match what `go build` actually needs; everything else bloats the
|
|
# build context and slows COPY . . to a crawl.
|
|
|
|
bin/
|
|
out/
|
|
.git/
|
|
.github/
|
|
.idea/
|
|
.vscode/
|
|
*.swp
|
|
*.swo
|
|
|
|
# Reality test outputs — regenerable, not needed in the image.
|
|
reports/
|
|
data/
|
|
|
|
# Per-run smoke logs in /tmp obviously don't end up here, but defensive.
|
|
*.log
|
|
|
|
# Local config + secrets — must NEVER ship in an image.
|
|
lakehouse.toml
|
|
secrets-go.toml
|
|
auth.env
|
|
*.env
|
|
|
|
# Editor swap files
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# Existing systemd unit files don't belong in the container — the
|
|
# image deploys via docker-compose, not systemd-inside-container.
|
|
deploy/systemd/
|
|
|
|
# Reality-test JSON corpora are large + the multi_coord_stress
|
|
# binary will reference them as files, but they get mounted at
|
|
# runtime, not baked in.
|
|
tests/reality/contracts/*.json
|