molecule-core/workspace-server/Dockerfile.dev
claude-ceo-assistant c3596d6271 fix(org-import): use ws.FilesDir as persona-dir lookup, add docker-cli-buildx to dev image
## org_import.go — persona env injection root-cause fix

The Phase-3 fix from earlier today (`feedback/per-agent-gitea-identity-default`)
introduced loadPersonaEnvFile to inject persona-specific creds into
workspace_secrets on /org/import. It passed `ws.Role` as the persona-dir
lookup key, but in our dev-tree org.yaml shape `role:` carries the
multi-line descriptive text the agent reads from its prompt
("Engineering planning and team coordination — leads Core Platform,
Controlplane, ..."), while `files_dir:` holds the short slug
(`core-lead`, `dev-lead`, etc.) matching
`~/.molecule-ai/personas/<files_dir>/env`.

isSafeRoleName silently rejected the multi-word role text → no persona
env loaded → every imported workspace booted with zero
workspace_secrets rows → no ANTHROPIC / CLAUDE_CODE / MINIMAX auth in
the container env → claude_agent_sdk wedged on `query.initialize()`
with a 60s control-request timeout.

After the fix, /org/import on the dev tree (27 personas) populates
8 workspace_secrets per workspace (Gitea identity + MODEL/MODEL_PROVIDER
+ provider-specific token), 5 of 6 leads boot online, and the
remaining wedges trace to a separate runtime-template-repo bug
(workspace-template-claude-code's claude_sdk_executor.py doesn't
dispatch on MODEL_PROVIDER=minimax — filed separately).

## Dockerfile.dev — docker-cli + docker-cli-buildx

Without these, every claude-code/tier-2 workspace POST fails-fast:
- docker-cli alone produces `exec: "docker": executable file not found`
- docker-cli alone (no buildx) fails on `docker build` with
  `ERROR: BuildKit is enabled but the buildx component is missing or broken`

Both packages are now installed in the dev image; verified with
`docker exec molecule-core-platform-1 docker buildx version`.

## Stage A verified

Local /org/import dev-only path: 27 workspaces created, all 27 receive
persona env injection (8 secrets each — Gitea identity + provider creds).
Lead workspaces (claude-code-OAuth tier) boot online.

## Stage B — N/A

Local-dev-only path (docker-compose.dev.yml + dev image). Tenant EC2
provisioning uses Dockerfile.tenant (untouched).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 13:50:46 -07:00

45 lines
1.9 KiB
Docker

# Dockerfile.dev — local-development image with air-driven live reload.
#
# Selected by docker-compose.dev.yml (overlay over docker-compose.yml).
# Production stays on workspace-server/Dockerfile (static binary, no air).
#
# Workflow:
# 1. docker compose -f docker-compose.yml -f docker-compose.dev.yml up
# 2. Edit any .go file under workspace-server/
# 3. air detects, rebuilds, kills old binary, starts new one (~3-5s)
# 4. No `docker compose up --build` needed
#
# Templates + plugins are NOT pre-cloned here — air-mode assumes the
# developer's filesystem has the workspace-configs-templates/ + plugins/
# dirs available, mounted at runtime via docker-compose.dev.yml.
FROM golang:1.25-alpine
# air + git (for go mod) + ca-certs (for TLS) + tzdata (for time-zone DB)
# + docker-cli + docker-cli-buildx so the platform binary can shell out to
# /var/run/docker.sock (bind-mounted from host) for local-build provisioning.
# docker-cli alone is insufficient: alpine's docker-cli enables BuildKit by
# default but ships without buildx, producing
# `ERROR: BuildKit is enabled but the buildx component is missing or broken`
# on every `docker build`. docker-cli-buildx provides the buildx subcommand.
RUN apk add --no-cache git ca-certificates tzdata wget docker-cli docker-cli-buildx \
&& go install github.com/air-verse/air@latest
WORKDIR /app/workspace-server
# Pre-fetch deps so the first `air` rebuild on a fresh container is fast.
# These are bind-mount-overridden at runtime, so the COPY here is just
# to warm the module cache.
COPY workspace-server/go.mod workspace-server/go.sum ./
RUN go mod download
# Source is bind-mounted at runtime (see docker-compose.dev.yml volumes
# block) so the Dockerfile doesn't need to COPY it. air watches the
# bind-mounted dir for changes.
ENV CGO_ENABLED=0
ENV GOFLAGS="-buildvcs=false"
# Run air with the .air.toml in the bind-mounted source dir.
CMD ["air", "-c", ".air.toml"]