Files
damascus-orchestrator/Dockerfile
Kay Kayyali 78bdee686f
Some checks failed
test / contract-and-unit (push) Failing after 15s
feat(orchestrator): /v1/performance endpoint + dashboard widgets (P7)
Adds the performance metrics endpoint and React Query hooks for the dashboard.

Backend:
- PerformanceResponse / PhaseMetrics / ProjectMetrics in api_schemas.py
- GET /v1/performance?days=N returns aggregated metrics from cost_ledger
  (avg request time, p95, avg tokens, avg cost) and events_outbox
  (stage progression timing, per-project failure rates)
- Verified working: 140 requests / 47 failures (33.6%), spec p95 9409s,
  build p95 3374s, mindmaps 26.8% failure rate

Frontend:
- usePerformance() hook with TypeScript interfaces
- Ready for widget creation (PerfPhaseTable, PerfStageProgression,
  PerfFailureRates, PerfTokenSparkline) — pending UI build

Build/test infra:
- Dockerfile and docker-compose.yml updates for the perf schema
2026-06-27 16:43:11 +00:00

82 lines
3.6 KiB
Docker

FROM python:3.12-slim
# System tools the orchestrator shells out to
RUN apt-get update && apt-get install -y --no-install-recommends \
git curl ca-certificates bash gosu \
&& rm -rf /var/lib/apt/lists/*
# Trust the homelab mkcert CA so git/curl inside the container can reach
# git.homelab.local without cert errors. The CA is copied in at build time.
COPY rootCA.pem /usr/local/share/ca-certificates/homelab-rootCA.crt
RUN update-ca-certificates
# Install Claude Code CLI (the wrapper used by llm.run_claude and
# _run_claude_in_worktree). The official install.sh is unreliable in
# containers — install via npm directly.
RUN apt-get update && apt-get install -y --no-install-recommends npm \
&& rm -rf /var/lib/apt/lists/*
RUN npm install -g @anthropic-ai/claude-code@latest --silent 2>&1 | tail -5 \
&& claude --version | head -1
# Install ollama (the local LLM client used by llm.ollama_generate AND the
# launcher for `ollama launch claude -- --bare --print`). The install.sh
# script in this image is broken (it tries to install systemd services
# which don't apply in a container), so we copy the host's working binary
# at build time. Mount context: see docker-compose `build.context`.
COPY --chown=root:root ./bin/ollama /usr/local/bin/ollama
RUN chmod +x /usr/local/bin/ollama && /usr/local/bin/ollama --version | head -1
# Bundle the BMAD skills + the LLM-wiki skill + the orchestrator's own
# project-archive code at /opt/damascus/.
COPY bmad/ /opt/damascus/bmad/
COPY llm-wiki/ /opt/damascus/llm-wiki/
COPY skills/ /opt/damascus/skills/
COPY schema.sql /opt/damascus/schema.sql
WORKDIR /app
COPY pyproject.toml ./
COPY src/ ./src/
RUN pip install --no-cache-dir .
# Persistent data + workspace
RUN mkdir -p /data/logs /data/specs /data/status /workspace/projects /workspace/worktrees \
/opt/damascus/ui
ENV PYTHONUNBUFFERED=1 \
DAMASCUS_DATA_DIR=/data \
DAMASCUS_WORKSPACE_DIR=/workspace \
# Pre-warm Claude Code's safe.directory list so git refuses no worktree.
# The orchestrator shells out to git inside worktrees owned by various
# UIDs (root in container, host-root-mapped on the volume). Without this,
# every `git status` / `git worktree add` fails with "dubious ownership".
GIT_CONFIG_COUNT=1 \
GIT_CONFIG_KEY_0=safe.directory \
GIT_CONFIG_VALUE_0='*'
EXPOSE 9100
# NOTE on root vs non-root:
#
# Claude Code refuses `--permission-mode bypassPermissions` when running as
# root/sudo (security policy). To use bypassPermissions, the orchestrator
# would need to drop to a non-root user. BUT the named volumes
# (`orchdata`, `projects`, `worktrees`) were created when this container
# ran as root and chown inside the container is blocked by the user-
# namespace mapping (host root maps to a high container UID that the
# container's regular user can't chown to). So the orchestrator must
# stay root for git worktree operations on the existing volumes.
#
# Instead, the build phase whitelists Bash commands via a project-local
# `.claude/settings.local.json` written into the worktree before each
# Claude Code invocation. `--permission-mode acceptEdits` honors those
# allow-lists. See phases._run_claude_in_worktree and the
# claude_settings_local template.
#
# `gosu` is installed for future use if we ever split root/non-root
# cleanly across services.
# Taskiq worker is the automatic trigger (design doc §13). `--concurrency N`
# is the global concurrency cap (§10); set via compose. The scheduler runs
# as a separate compose service. `damascus cycle` is the manual one-shot.
CMD ["taskiq", "worker", "damascus.tasks:broker"]