mirror of
https://github.com/hanzoai/mcp.git
synced 2026-10-15 12:30:12 +00:00
This repo committed BOTH package-lock.json and pnpm-lock.yaml — two descriptions of one dependency tree, neither reconciled against the other. CI then ran `npm ci || npm install`, which is the shape that lets that persist: when the lockfile stops matching package.json, the fallback silently resolves a different tree and the run still goes green. A lockfile nobody fails on is not a lockfile. Now there is one. pnpm-lock.yaml is tracked, package-lock.json is deleted and ignored along with every other manager's, corepack takes the pnpm version from `packageManager`, and Docker and CI both install with --frozen-lockfile so a drifted tree stops the build instead of being papered over. The `pnpm.onlyBuiltDependencies` field in package.json was dead — pnpm 11 reads settings from pnpm-workspace.yaml and prints a warning that it ignored it. Its five entries moved there verbatim, documented, so the build-script denial is actually in effect rather than merely written down. esbuild goes ^0.27.4 -> ^0.28.1, the version console already builds with. 0.27.4's install script overwrites its own bin/esbuild with a raw ELF, and pnpm's shim reads a missing shebang as "run this with node", so `pnpm build` died on `SyntaxError: Invalid or unexpected token` at the first byte. Same minor series, and it is what makes the build work under pnpm at all. Verified: frozen-lockfile install clean, `pnpm build` emits a 617KB bundle, 354 tests passing. Co-authored-by: Hanzo Dev <[email protected]>
94 lines
2.2 KiB
Docker
94 lines
2.2 KiB
Docker
# Production-ready Dockerfile for Hanzo MCP Server
|
|
# Multi-stage build optimized for TypeScript CLI applications
|
|
|
|
# ===== Base Stage =====
|
|
FROM ghcr.io/hanzoai/nodejs:v24.18.0 AS base
|
|
|
|
# Install system dependencies and security updates
|
|
RUN apk update && apk upgrade && \
|
|
apk add --no-cache \
|
|
dumb-init \
|
|
tini \
|
|
ca-certificates && \
|
|
rm -rf /var/cache/apk/*
|
|
|
|
# Create app directory with proper permissions
|
|
WORKDIR /app
|
|
RUN addgroup --system --gid 1001 nodejs && \
|
|
adduser --system --uid 1001 mcp && \
|
|
chown -R mcp:nodejs /app
|
|
|
|
# ===== Dependencies Stage =====
|
|
FROM base AS deps
|
|
|
|
# Copy package files
|
|
COPY --chown=mcp:nodejs package.json package-lock.json* ./
|
|
|
|
# Switch to mcp user for security
|
|
USER mcp
|
|
|
|
# Install dependencies
|
|
RUN corepack enable && pnpm install --prod --frozen-lockfile && pnpm store prune
|
|
|
|
# Install dev dependencies for building
|
|
RUN corepack enable && pnpm install --frozen-lockfile
|
|
|
|
# ===== Builder Stage =====
|
|
FROM deps AS builder
|
|
|
|
# Copy source code
|
|
COPY --chown=mcp:nodejs . .
|
|
|
|
# Build the application
|
|
RUN pnpm build
|
|
|
|
# ===== Development Stage =====
|
|
FROM deps AS development
|
|
|
|
# Copy source code
|
|
COPY --chown=mcp:nodejs . .
|
|
|
|
# Set environment
|
|
ENV NODE_ENV=development
|
|
|
|
# Development command with hot reload
|
|
CMD ["pnpm", "dev"]
|
|
|
|
# ===== Production Stage =====
|
|
FROM base AS production
|
|
|
|
# Install only runtime dependencies
|
|
COPY --chown=mcp:nodejs package.json package-lock.json* ./
|
|
|
|
# Switch to mcp user for security
|
|
USER mcp
|
|
|
|
# Install only production dependencies
|
|
RUN corepack enable && pnpm install --prod --frozen-lockfile && pnpm store prune
|
|
|
|
# Copy built application from builder
|
|
COPY --from=builder --chown=mcp:nodejs /app/dist ./dist
|
|
|
|
# Make CLI executable
|
|
RUN chmod +x ./dist/cli.js
|
|
|
|
# Set environment variables
|
|
ENV NODE_ENV=production
|
|
|
|
# Create symlink for global access (optional)
|
|
USER root
|
|
RUN ln -sf /app/dist/cli.js /usr/local/bin/hanzo-mcp
|
|
USER mcp
|
|
|
|
# Health check for MCP server
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD node -e "process.exit(0);" || exit 1
|
|
|
|
# Use tini for proper signal handling
|
|
ENTRYPOINT ["/sbin/tini", "--"]
|
|
|
|
# Default command runs the MCP server
|
|
CMD ["node", "dist/index.js"]
|
|
|
|
# ===== Default to production =====
|
|
FROM production |