127 lines
4.0 KiB
Docker
127 lines
4.0 KiB
Docker
# =============================================================================
|
|
# Stage 1: Dependencies
|
|
# Install only production dependencies for optimal layer caching
|
|
# =============================================================================
|
|
FROM oven/bun:1-slim AS dependencies
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy workspace configuration
|
|
COPY package.json bun.lock ./
|
|
|
|
# Copy all package.json files to establish workspace structure
|
|
COPY packages/core/package.json ./packages/core/
|
|
COPY packages/api-server/package.json ./packages/api-server/
|
|
COPY packages/mcp-server/package.json ./packages/mcp-server/
|
|
|
|
# Install dependencies with frozen lockfile (production only)
|
|
RUN bun install --frozen-lockfile --production
|
|
|
|
# =============================================================================
|
|
# Stage 2: Build
|
|
# Build both services with minification for production
|
|
# =============================================================================
|
|
FROM oven/bun:1-slim AS build
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy workspace configuration
|
|
COPY package.json bun.lock ./
|
|
|
|
# Copy all package.json files
|
|
COPY packages/core/package.json ./packages/core/
|
|
COPY packages/api-server/package.json ./packages/api-server/
|
|
COPY packages/mcp-server/package.json ./packages/mcp-server/
|
|
|
|
# Install ALL dependencies (including devDependencies for TypeScript)
|
|
RUN bun install --frozen-lockfile
|
|
|
|
# Copy source code for all packages
|
|
COPY packages/core ./packages/core
|
|
COPY packages/api-server ./packages/api-server
|
|
COPY packages/mcp-server ./packages/mcp-server
|
|
|
|
# Build both services with minification
|
|
# Output: dist/api/index.js and dist/mcp/index.js
|
|
RUN bun build ./packages/api-server/src/index.ts \
|
|
--target=bun \
|
|
--outdir=./dist/api \
|
|
--minify && \
|
|
bun build ./packages/mcp-server/src/index.ts \
|
|
--target=bun \
|
|
--outdir=./dist/mcp \
|
|
--minify
|
|
|
|
# Verify builds succeeded
|
|
RUN ls -lh ./dist/api/index.js ./dist/mcp/index.js
|
|
|
|
# =============================================================================
|
|
# Stage 3: Runtime
|
|
# Minimal production image with both services
|
|
# =============================================================================
|
|
FROM oven/bun:1-slim AS runtime
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy production dependencies from dependencies stage
|
|
COPY --from=dependencies /app/node_modules ./node_modules
|
|
|
|
# Copy built artifacts from build stage
|
|
COPY --from=build /app/dist ./dist
|
|
|
|
# Create cookies directory (will be mounted as volume at runtime)
|
|
# This ensures the directory exists even if volume is not mounted
|
|
RUN mkdir -p /app/cookies && \
|
|
chown -R bun:bun /app/cookies
|
|
|
|
# Create startup script that runs both services
|
|
# Uses Bun's built-in capabilities for process management
|
|
RUN cat > /app/start.sh << 'EOF'
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
# Trap SIGTERM and SIGINT for graceful shutdown
|
|
trap 'echo "Received shutdown signal, stopping services..."; kill -TERM $API_PID $MCP_PID 2>/dev/null; wait' TERM INT
|
|
|
|
# Start API Server in background
|
|
echo "Starting API Server on port ${API_PORT:-4005}..."
|
|
bun /app/dist/api/index.js &
|
|
API_PID=$!
|
|
|
|
# Give API server a moment to initialize
|
|
sleep 1
|
|
|
|
# Start MCP Server in background
|
|
echo "Starting MCP Server on port ${API_PORT:-4006}..."
|
|
bun /app/dist/mcp/index.js &
|
|
MCP_PID=$!
|
|
|
|
echo "Both services started successfully"
|
|
echo "API Server PID: $API_PID"
|
|
echo "MCP Server PID: $MCP_PID"
|
|
|
|
# Wait for both processes
|
|
wait $API_PID $MCP_PID
|
|
EOF
|
|
|
|
RUN chmod +x /app/start.sh
|
|
|
|
# Expose both service ports
|
|
# API Server: 4005 (default), MCP Server: 4006 (default)
|
|
EXPOSE 4005 4006
|
|
|
|
# Environment variables for port configuration
|
|
ENV PORT=4005
|
|
ENV MCP_PORT=4006
|
|
|
|
# Volume mount point for cookies
|
|
# Mount your cookies directory here: -v /path/to/cookies:/app/cookies
|
|
VOLUME ["/app/cookies"]
|
|
|
|
# Health check that verifies both services are responding
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
|
CMD bun -e "Promise.all([fetch('http://localhost:4005/api/status'),fetch('http://localhost:4006/.well-known/mcp/server-card.json')]).then(r=>process.exit(0)).catch(()=>process.exit(1))"
|
|
|
|
# Run the startup script
|
|
CMD ["/app/start.sh"]
|