Files
boocode/docker-compose.yml
indifferentketchup 4fae77e526 v1.12 track B.1: codecontext sidecar container + HTTP shim
New /opt/boocode/codecontext/ directory holding the codecontext sidecar
that BooCode's tool wrappers (track B.2) will talk to. No BooCode-side
changes yet — this commit lands the sidecar standalone.

- Dockerfile: multi-stage golang:1.24-alpine → alpine:3.20. Clones
  codecontext at v3.2.1 from github.com/nmakod/codecontext (cgo build for
  tree-sitter bindings), builds the shim alongside (CGO_ENABLED=0).
- shim.go: stdlib-only Go HTTP server wrapping codecontext's stdio MCP
  child. Newline-delimited JSON framing per the MCP transport spec
  (NOT LSP-style Content-Length). 8 POST /v1/* endpoints, one per MCP
  tool, plus GET /health. Child supervised via child.Wait() goroutine
  that os.Exit's on death so the container's restart: unless-stopped
  policy fires (Signal(0) on a zombie returns nil and is not a liveness
  check — discovered during kill-restart testing).
- go.mod: no third-party deps; future Go security advisories don't apply.

docker-compose service: joins boocode_net (no host port), mounts
/opt:/opt:ro (BooCode projects live at /opt/<slug>, not exclusively
under /opt/projects), healthcheck on /health.

Verified: build clean, healthcheck reports healthy ~15s after up,
multi-project queries return valid markdown, target_dir swap works on
subtree paths. Kill-restart cycle completes in ~200ms with one failed
health poll observed (no misleading "ok" during the gap). Memory: 24.6
MiB after 5 search_symbols calls, 5.6 MiB after 30 min idle — codecontext
releases the per-call graph between target_dir swaps, so the shim doesn't
hold the indexed state.
2026-05-21 12:30:48 +00:00

91 lines
2.5 KiB
YAML

services:
boocode:
build: .
container_name: boocode
restart: unless-stopped
ports:
- "100.114.205.53:9500:3000"
env_file: .env
environment:
DATABASE_URL: postgres://boocode:${POSTGRES_PASSWORD}@boocode_db:5432/boocode
volumes:
- /opt:/opt
- /opt/projects:/opt/projects:rw
- ./secrets/boocode_gitea:/root/.ssh/id_ed25519:ro
- ./data:/data
- /opt/skills:/data/skills
depends_on:
- boocode_db
networks:
- boocode_net
booterm:
build:
context: .
dockerfile: apps/booterm/Dockerfile
container_name: booterm
restart: unless-stopped
ports:
- "100.114.205.53:9501:3000"
env_file: .env
environment:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgres://boocode:${POSTGRES_PASSWORD}@boocode_db:5432/boocode
volumes:
- /opt:/opt:rw
- /home/samkintop:/home/samkintop:rw
depends_on:
- boocode_db
networks:
- boocode_net
boocode_db:
image: postgres:16-alpine
container_name: boocode_db
restart: unless-stopped
environment:
POSTGRES_USER: boocode
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: boocode
ports:
- "127.0.0.1:5500:5432"
volumes:
- boocode_pgdata:/var/lib/postgresql/data
networks:
- boocode_net
# v1.12 Track B: codecontext sidecar. Stdio MCP server wrapped by a small
# HTTP shim (see ./codecontext/). No host port — reached from boocode at
# http://codecontext:8080 over the boocode_net bridge.
#
# Mounts /opt:/opt:ro (not just /opt/projects:ro): BooCode projects live
# at /opt/<slug> on the host, not exclusively under /opt/projects. The
# mount must cover anywhere a project.path could resolve to. Read-only
# because codecontext only analyzes — never writes. The model can't
# arbitrarily set target_dir to a sensitive subtree because the B.2
# wrappers validate target_dir against project.path before calling the
# shim, and the shim isn't reachable from outside boocode_net.
codecontext:
build:
context: ./codecontext
container_name: boocode_codecontext
restart: unless-stopped
networks:
- boocode_net
volumes:
- /opt:/opt:ro
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health || exit 1"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30s
volumes:
boocode_pgdata:
networks:
boocode_net:
driver: bridge