# Multi-stage Dockerfile optimized for n8n integration # Stage 1: Build stage FROM node:20-alpine AS builder # Install build dependencies RUN apk add --no-cache python3 make g++ git # Set working directory WORKDIR /app # Copy package files COPY package*.json ./ # Install all dependencies (including dev deps for building) RUN npm ci # Copy source code COPY . . # Build the application RUN npm run build # Stage 2: Production stage FROM node:20-alpine # Install runtime dependencies RUN apk add --no-cache \ curl \ tini \ && rm -rf /var/cache/apk/* # Create non-root user with unpredictable UID/GID # Using a hash of the build time to generate unpredictable IDs RUN BUILD_HASH=$(date +%s | sha256sum | head -c 8) && \ UID=$((10000 + 0x${BUILD_HASH} % 50000)) && \ GID=$((10000 + 0x${BUILD_HASH} % 50000)) && \ addgroup -g ${GID} n8n-mcp && \ adduser -u ${UID} -G n8n-mcp -s /bin/sh -D n8n-mcp # Set working directory WORKDIR /app # Copy package files (use runtime-only dependencies) COPY package.runtime.json package.json # Install production dependencies only RUN npm install --production --no-audit --no-fund && \ npm cache clean --force # Copy built application from builder stage COPY --from=builder /app/dist ./dist COPY --from=builder /app/data ./data # Create necessary directories and set permissions RUN mkdir -p /app/logs /app/data && \ chown -R n8n-mcp:n8n-mcp /app # Switch to non-root user USER n8n-mcp # Set environment variables for n8n mode ENV NODE_ENV=production \ N8N_MODE=true \ N8N_API_URL="" \ N8N_API_KEY="" \ PORT=3000 # Expose port EXPOSE 3000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:${PORT}/health || exit 1 # Use tini for proper signal handling ENTRYPOINT ["/sbin/tini", "--"] # Start the application in n8n mode CMD ["node", "dist/index.js", "n8n"]