Files
boocode/docker-compose.yml
indifferentketchup 7f0fd1281b security: scope /opt mount to /opt/projects
Splits the previous /opt:/opt:rw bind into two mounts to narrow the
writable scope of the container:

- /opt:/opt:ro — read-only mount for legacy/existing project
  add-existing flow. resolveProjectPath still uses
  PROJECT_ROOT_WHITELIST (/opt by default) so existing projects under
  /opt/<name> (analytics, boolab, boocode itself) continue to resolve
  and serve their file-tree via the read-only tools.
- /opt/projects:/opt/projects:rw — writable mount targeted at the
  create-new-project bootstrap path.

Picked Option B from the spec (simpler than two scan roots):
PROJECT_ROOT_WHITELIST stays /opt, new BOOTSTRAP_ROOT env var defaults
to /opt/projects and is used by project_bootstrap.ts as the mkdir
target. Bootstrap path-escape check now compares against
BOOTSTRAP_ROOT.

Prereq: host must `mkdir -p /opt/projects` before next container
restart. Documented in CLAUDE.md and .env.example.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 04:35:59 +00:00

43 lines
1.0 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:
# Read-only mount for legacy/existing project add-existing flow.
- /opt:/opt:ro
# Writable mount only for the create-new-project bootstrap target.
# Host must `mkdir -p /opt/projects` before container start.
- /opt/projects:/opt/projects: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
volumes:
boocode_pgdata:
networks:
boocode_net:
driver: bridge