# Dockerfile for pre-built application
# Use this when Docker has limited memory for building
#
# Usage:
# 1. Build locally first: npm run build
# 2. Then build Docker image: docker build -f containers/Dockerfile.prebuilt -t spec-workflow-mcp .
FROM node:24-alpine
WORKDIR /app
# Install dumb-init for proper signal handling
RUN apk add --no-cache dumb-init
# Copy package files and install production dependencies only
COPY package*.json ./
RUN npm ci --only=production
# Copy pre-built application (must run `npm run build` locally first)
COPY dist ./dist
RUN mkdir -p /workspace /workspace/.spec-workflow-mcp
# Change ownership of the app directory to the node user (uid=1000)
RUN chown -R node:node /app /workspace
# Switch to non-root user for security
USER node
WORKDIR /workspace
# Security: Set environment variables for secure defaults
ENV SPEC_WORKFLOW_HOME=/workspace/.spec-workflow-mcp
ENV NODE_ENV=production
# Docker networking: Bind to 0.0.0.0 inside container (required for port forwarding to work)
# Security is controlled by Docker's port mapping (see docker-compose.yml)
# - Default: 127.0.0.1:5000:5000 exposes only to host's localhost (secure)
# - Optional: 0.0.0.0:5000:5000 or 5000:5000 exposes to all interfaces (use with caution)
ENV SPEC_WORKFLOW_BIND_ADDRESS=0.0.0.0
ENV SPEC_WORKFLOW_ALLOW_EXTERNAL_ACCESS=true
EXPOSE 5000
# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]
# Run as non-root user with secure defaults
# Use shell form for CMD to enable environment variable expansion
CMD node /app/dist/index.js ${SPEC_WORKFLOW_PATH:-/workspace} --dashboard --port ${DASHBOARD_PORT:-5000}