Some checks failed
CI/CD / typecheck (pull_request) Successful in 56s
CI/CD / test (pull_request) Successful in 1m9s
CI/CD / lint (pull_request) Successful in 2m40s
CI/CD / smoke (pull_request) Failing after 1m43s
CI/CD / build (pull_request) Failing after 7m6s
CI/CD / publish (pull_request) Has been skipped
Two tuning knobs that were leaving most of the host idle: 1) vitest.config.ts pool=threads with maxThreads ≈ cores/2. Default left this 64-core workstation at ~10% CPU during \`pnpm test:run\`. Threads pool uses the box: same 152-file/2050-test suite now runs at ~700% CPU instead of ~150%. Wall time gain is modest (workload is dominated by a handful of slow individual files that one thread must run serially), but the parallel headroom is there for when the suite grows. Cap = max(2, cores/2) keeps laptops reasonable; override with \`VITEST_MAX_THREADS=N\` in the env. 2) Dockerfile.mcpd uses BuildKit cache mounts on both pnpm install steps. Adds \`# syntax=docker/dockerfile:1.6\` and a \`--mount=type=cache,target=/root/.local/share/pnpm/store\` so pnpm's content-addressed store survives across image rebuilds. Cold rebuilds where the lockfile changed are unaffected; warm rebuilds where only source changed drop the install step from ~60s to <5s. fulldeploy.sh's mcpd image rebuild gets that back minus the docker push hash mismatch. Test parity: 2050/2050 across 152 files; per-package mcpd 837/837. Both unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
87 lines
3.1 KiB
Docker
87 lines
3.1 KiB
Docker
# syntax=docker/dockerfile:1.6
|
|
# `# syntax=...` enables BuildKit's --mount feature on the builder so we can
|
|
# share the pnpm content-addressed store across image builds. Without it the
|
|
# next two RUN steps fall back to plain mode and the cache mount is ignored
|
|
# (build still works, just slower).
|
|
|
|
# Stage 1: Build TypeScript
|
|
FROM node:20-alpine AS builder
|
|
|
|
RUN corepack enable && corepack prepare pnpm@9.15.0 --activate
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy workspace config and package manifests
|
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json tsconfig.base.json ./
|
|
COPY src/mcpd/package.json src/mcpd/tsconfig.json src/mcpd/
|
|
COPY src/db/package.json src/db/tsconfig.json src/db/
|
|
COPY src/shared/package.json src/shared/tsconfig.json src/shared/
|
|
COPY src/web/package.json src/web/tsconfig.json src/web/
|
|
|
|
# Install all dependencies. The cache mount keeps pnpm's CAS store warm
|
|
# across builds: only newly-changed packages get downloaded; everything
|
|
# else hardlinks from the cache. Drops install from ~60s to <5s on a
|
|
# warm cache. `--frozen-lockfile` still guarantees lockfile fidelity.
|
|
RUN --mount=type=cache,id=pnpm-store-mcpd-builder,target=/root/.local/share/pnpm/store \
|
|
pnpm install --frozen-lockfile
|
|
|
|
# Copy source code
|
|
COPY src/mcpd/src/ src/mcpd/src/
|
|
COPY src/db/src/ src/db/src/
|
|
COPY src/db/prisma/ src/db/prisma/
|
|
COPY src/shared/src/ src/shared/src/
|
|
COPY src/web/src/ src/web/src/
|
|
COPY src/web/index.html src/web/vite.config.ts src/web/
|
|
|
|
# Generate Prisma client and build TypeScript + web SPA
|
|
RUN pnpm -F @mcpctl/db db:generate
|
|
RUN pnpm -F @mcpctl/shared build && pnpm -F @mcpctl/db build && pnpm -F @mcpctl/mcpd build
|
|
RUN pnpm -F @mcpctl/web build
|
|
|
|
# Stage 2: Production runtime
|
|
FROM node:20-alpine
|
|
|
|
RUN apk add --no-cache git openssh-client \
|
|
&& corepack enable && corepack prepare pnpm@9.15.0 --activate
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy workspace config, manifests, and lockfile
|
|
COPY pnpm-workspace.yaml pnpm-lock.yaml package.json ./
|
|
COPY src/mcpd/package.json src/mcpd/
|
|
COPY src/db/package.json src/db/
|
|
COPY src/shared/package.json src/shared/
|
|
|
|
# Install all deps (prisma CLI needed at runtime for db push). Same
|
|
# cache-mount trick as the builder stage; separate cache id so the two
|
|
# stages don't compete for the same lock.
|
|
RUN --mount=type=cache,id=pnpm-store-mcpd-runtime,target=/root/.local/share/pnpm/store \
|
|
pnpm install --frozen-lockfile
|
|
|
|
# Copy prisma schema and generate client
|
|
COPY src/db/prisma/ src/db/prisma/
|
|
RUN pnpm -F @mcpctl/db db:generate
|
|
|
|
# Copy built output from builder
|
|
COPY --from=builder /app/src/shared/dist/ src/shared/dist/
|
|
COPY --from=builder /app/src/db/dist/ src/db/dist/
|
|
COPY --from=builder /app/src/mcpd/dist/ src/mcpd/dist/
|
|
|
|
# Copy the web SPA bundle. registerWebUi() looks for it at this path
|
|
# (or wherever MCPD_WEB_ROOT is set).
|
|
COPY --from=builder /app/src/web/dist/ /usr/share/mcpd/web/
|
|
|
|
# Copy templates for seeding
|
|
COPY templates/ templates/
|
|
|
|
# Copy entrypoint
|
|
COPY deploy/entrypoint.sh /entrypoint.sh
|
|
RUN chmod +x /entrypoint.sh
|
|
|
|
EXPOSE 3100
|
|
|
|
HEALTHCHECK --interval=10s --timeout=5s --retries=3 --start-period=10s \
|
|
CMD wget -q --spider http://localhost:3100/healthz || exit 1
|
|
|
|
ENTRYPOINT ["/entrypoint.sh"]
|