Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 1s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 1s
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 4s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 1s
Retarget main PRs to staging / Retarget to staging (pull_request) Has been skipped
CI / Detect changes (pull_request) Successful in 7s
E2E API Smoke Test / detect-changes (pull_request) Successful in 6s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 7s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 7s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 3s
CI / Python Lint & Test (pull_request) Successful in 3s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 2s
CI / Canvas (Next.js) (pull_request) Successful in 6s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 5s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 3s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
Harness Replays / Harness Replays (pull_request) Failing after 6s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 43s
CI / Platform (Go) (pull_request) Successful in 2m1s
Closes core#116. Brings local-dev iteration parity with the canvas's
Turbopack HMR — edit a Go file, see the platform restart in <5s
instead of running 'docker compose up --build' (~30s) per change.
USAGE
make dev # docker compose with air-driven live reload
make up # production-shape stack (no air, normal Dockerfile)
WHAT THIS ADDS
workspace-server/.air.toml — air watch config
workspace-server/Dockerfile.dev — air-on-golang:1.25-alpine, dev-only
docker-compose.dev.yml — overlay swapping platform service
to Dockerfile.dev + bind-mounting
workspace-server/ source
Makefile — make {dev,up,down,logs,build,test}
WHAT THIS DOES NOT TOUCH
workspace-server/Dockerfile (production multi-stage build)
docker-compose.yml (prod-shape stack)
CI workflows (build prod image directly)
Tenant deployment / SaaS (image swap stays the model)
Pure additive. Existing 'docker compose up' path unchanged; production
stays on the static binary. Air install pinned via go install at image
build time so the dev image is reproducible-enough for local use (we
don't pin air to a SHA — the dev image is rebuilt locally and updates
opportunistically).
PHASE 4 SELF-REVIEW (FIVE-AXIS)
Correctness: No finding — additive change, no existing path modified.
.air.toml watches .go + .yaml under workspace-server/, excludes
_test.go and tests dir so test edits don't trigger rebuild.
Dockerfile.dev mirrors prod's 'go mod download' so first rebuild
is fast.
Readability: No finding — three small files plus a Makefile, each
with header comments explaining the WHY, not just the WHAT. The
Makefile uses the standard ## help-target pattern.
Architecture: No finding — overlay pattern (docker-compose.dev.yml
on top of docker-compose.yml) is the standard compose convention
for env-specific overrides. Doesn't fork the prod path.
Security: No finding because no production code path; dev-only image
isn't built in CI and isn't published to ECR.
Performance: No finding — air debounce=500ms, exclude_unchanged=true
so a save that doesn't change content is a no-op rebuild.
REFS
core#116 — this issue
Companion: core#117 (workspace-side config-watcher for hot-reload of
config.yaml) — different scope; this issue is platform-only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
44 lines
1.7 KiB
YAML
44 lines
1.7 KiB
YAML
# docker-compose.dev.yml — overlay over docker-compose.yml for local dev
|
|
# with air-driven live reload of the platform (workspace-server) service.
|
|
#
|
|
# Usage:
|
|
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up
|
|
# (or `make dev` shorthand from repo root)
|
|
#
|
|
# What this overlay changes vs docker-compose.yml alone:
|
|
# - Platform service uses workspace-server/Dockerfile.dev (air on top of
|
|
# golang:1.25-alpine) instead of the multi-stage prod Dockerfile.
|
|
# - Platform service bind-mounts the host's workspace-server/ source
|
|
# into /app/workspace-server so air sees source edits live.
|
|
# - Other services (postgres, redis, langfuse, etc.) inherit unchanged
|
|
# from docker-compose.yml.
|
|
#
|
|
# What stays the same:
|
|
# - All env vars, volumes, depends_on, healthchecks from docker-compose.yml.
|
|
# - Network topology + ports.
|
|
# - Postgres/Redis as service containers (no in-process replacements).
|
|
|
|
services:
|
|
platform:
|
|
build:
|
|
context: .
|
|
dockerfile: workspace-server/Dockerfile.dev
|
|
# Rebind source: edits under host's workspace-server/ propagate live.
|
|
# The named volume on go-build-cache speeds up first build per container.
|
|
volumes:
|
|
- ./workspace-server:/app/workspace-server
|
|
- go-build-cache:/root/.cache/go-build
|
|
- go-mod-cache:/go/pkg/mod
|
|
# Air signals the running binary on rebuild; ensure shell stops cleanly.
|
|
init: true
|
|
# Mark the service as dev-mode so the platform can short-circuit any
|
|
# behavior that's incompatible with hot-reload (e.g. background
|
|
# cron-style watchers that don't survive process restart). No-op
|
|
# today; reserved for future flag use.
|
|
environment:
|
|
MOLECULE_DEV_HOT_RELOAD: "1"
|
|
|
|
volumes:
|
|
go-build-cache:
|
|
go-mod-cache:
|