buildmymcpserver/apps/api/Dockerfile
Marco Sadjadi a288179954 fix(docker): healthcheck must hit 127.0.0.1, not localhost
The servers bind IPv4 (0.0.0.0) only. busybox wget resolves `localhost`
to ::1 first and does not fall back to IPv4, so the healthcheck failed
with "connection refused" and the container showed as unhealthy while
serving fine. Verified on the production api container.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 18:07:01 +02:00

36 lines
1.4 KiB
Docker

# syntax=docker/dockerfile:1
# Control plane (Fastify). Runs via tsx — workspace packages are consumed as raw
# TypeScript, so there is no separate compile step (same model as runner-template).
# Build context must be the repo root: docker build -f apps/api/Dockerfile .
FROM node:20-alpine AS base
RUN corepack enable && corepack prepare pnpm@9.12.0 --activate
WORKDIR /app
# ---- deps: install the whole workspace from the lockfile ----
FROM base AS deps
COPY pnpm-lock.yaml pnpm-workspace.yaml package.json ./
COPY apps/api/package.json apps/api/
COPY apps/web/package.json apps/web/
COPY apps/generator/package.json apps/generator/
COPY apps/runner-template/package.json apps/runner-template/
COPY packages/auth/package.json packages/auth/
COPY packages/db/package.json packages/db/
COPY packages/llm/package.json packages/llm/
COPY packages/types/package.json packages/types/
RUN pnpm install --frozen-lockfile
# ---- runtime ----
FROM deps AS runtime
# docker CLI: the API stops/removes generated MCP containers via the host daemon.
RUN apk add --no-cache docker-cli
ENV NODE_ENV=production
COPY . .
WORKDIR /app/apps/api
EXPOSE 4000
# Use 127.0.0.1, not localhost: the server binds IPv4 only, and busybox wget
# resolves localhost to ::1 first — which would refuse and fail the check.
HEALTHCHECK --interval=20s --timeout=4s --start-period=20s --retries=3 \
CMD wget -qO- http://127.0.0.1:4000/health || exit 1
CMD ["pnpm", "start"]