Backwards compat shim (task 27) - requireCliAuth() falls back to body.user_id when BROKER_LEGACY_AUTH=1 and no bearer present. Sets Deprecation + Warning headers + bumps a broker_legacy_auth_hits_total metric so operators can watch the legacy traffic drain to 0 before removing the shim. - All handlers parse body BEFORE requireCliAuth so the fallback can read user_id out of it. HA readiness (task 29) - .artifacts/specs/2026-04-15-broker-ha-statelessness-audit.md documents every in-memory symbol and rollout plan (phase 0-4). - packaging/docker-compose.ha-local.yml spins up 2 broker replicas behind Traefik sticky sessions for local smoke testing. - apps/broker/src/audit.ts now wraps writes in a transaction that takes pg_advisory_xact_lock(meshId) and re-reads the tail hash inside the txn. Concurrent broker replicas can no longer fork the audit chain. Deploy gate (task 30) - /health stays permissive (200 even on transient DB blips) so Docker doesn't kill the container on a glitch. - New /health/ready checks DB + optional EXPECTED_MIGRATION pin, returns 503 if either fails. External deploy gate can poll this and refuse to promote a broken deploy. Metrics dashboard (task 32) - packaging/grafana/claudemesh-broker.json: ready-to-import Grafana dashboard covering active conns, queue depth, routed/rejected rates, grant drops, legacy-auth hits, conn rejects. Tests (task 28) - audit-canonical.test.ts (4 tests) pins canonical JSON semantics. - grants-enforcement.test.ts (6 tests) covers the member-then- session-pubkey lookup with default/explicit/blocked branches. Docs (task 34) - docs/env-vars.md catalogues every env var the broker + CLI read. Crypto review prep (task 35) - .artifacts/specs/2026-04-15-crypto-review-packet.md: reviewer brief, threat model, scope, test coverage list, deliverables. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
55 lines
2.4 KiB
Docker
55 lines
2.4 KiB
Docker
# claudemesh broker — production Dockerfile
|
|
# Bun runtime (executes .ts directly, no build step required).
|
|
# Build from repo root: docker build -f apps/broker/Dockerfile -t claudemesh-broker .
|
|
|
|
# Stage 1: resolve pnpm workspace + install deps (Bun base + standalone pnpm)
|
|
FROM oven/bun:1.2 AS deps
|
|
WORKDIR /app
|
|
|
|
# Install standalone pnpm binary (no Node needed — pnpm ships as a single ELF)
|
|
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && \
|
|
curl -fsSL "https://github.com/pnpm/pnpm/releases/download/v10.25.0/pnpm-linuxstatic-x64" -o /usr/local/bin/pnpm && \
|
|
chmod +x /usr/local/bin/pnpm && \
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy full workspace (pnpm needs lockfile + all package.jsons to resolve workspace:* and catalog:)
|
|
COPY . .
|
|
|
|
# Install all workspace deps, then flatten broker's prod subset into /deploy.
|
|
# pnpm deploy: resolves workspace:* to real copies, drops catalog: references,
|
|
# drops devDependencies (--prod), produces a self-contained runtime directory
|
|
# with only what this one package + its transitive prod deps need.
|
|
RUN pnpm install --frozen-lockfile --ignore-scripts && \
|
|
pnpm deploy --legacy --prod --ignore-scripts --filter=@claudemesh/broker /deploy
|
|
|
|
# Stage 2: minimal Bun runtime — copy only the flat /deploy subset
|
|
FROM oven/bun:1.2-slim AS runtime
|
|
WORKDIR /app
|
|
|
|
# Git SHA baked in at build-time → surfaced on /health (spec: apps/broker/DEPLOY_SPEC.md)
|
|
ARG GIT_SHA=unknown
|
|
ENV GIT_SHA=$GIT_SHA
|
|
|
|
ENV NODE_ENV=production
|
|
ENV BROKER_PORT=7900
|
|
|
|
COPY --from=deps --chown=bun:bun /deploy /app
|
|
|
|
# Copy migrations folder alongside the broker so runtime auto-migrate
|
|
# has files to apply. Workspace deploy subset drops them otherwise.
|
|
COPY --from=deps --chown=bun:bun /app/packages/db/migrations /app/migrations
|
|
|
|
EXPOSE 7900
|
|
|
|
# Liveness (Docker HEALTHCHECK) hits /health — permissive, tolerates
|
|
# transient DB blips so the container isn't killed during brief DB
|
|
# restarts. Deploy-time readiness is a separate /health/ready endpoint
|
|
# which checks DB + migration version; an external gate should poll
|
|
# that after container start and fail the deploy if not green.
|
|
HEALTHCHECK --interval=10s --timeout=5s --start-period=30s --retries=5 \
|
|
CMD bun -e "fetch('http://localhost:7900/health').then(r=>{process.exit(r.ok?0:1)}).catch(()=>process.exit(1))"
|
|
|
|
# Non-root user (oven/bun image ships with 'bun' uid 1000)
|
|
USER bun
|
|
CMD ["bun", "src/index.ts"]
|