# Multi-stage build for Gallus CMS Backend # Stage 1: Builder FROM node:20-alpine AS builder WORKDIR /app # Install build dependencies for native modules (better-sqlite3, sharp) RUN apk add --no-cache python3 make g++ vips-dev # Install dependencies COPY package*.json ./ # Use npm ci when lockfile exists, fallback to npm install for local/dev RUN npm ci || npm install # Copy source COPY . . # Build TypeScript RUN npm run build # Stage 2: Production FROM node:20-alpine WORKDIR /app # Install runtime dependencies (git for simple-git, sqlite3 CLI tool, vips for sharp) # Note: python3, make, g++ are needed for native module compilation RUN apk add --no-cache git sqlite vips vips-dev python3 make g++ # Copy package files first COPY --from=builder /app/package*.json ./ # Install all production dependencies and rebuild sharp for linuxmusl-x64 RUN npm ci --omit=dev || npm install --production && \ npm rebuild sharp # Clean up build dependencies after installation to reduce image size RUN apk del python3 make g++ vips-dev # Copy built files from builder COPY --from=builder /app/dist ./dist COPY --from=builder /app/src/db/migrations ./dist/db/migrations # Copy migration script and migrated images COPY --from=builder /app/migrate-production.js ./migrate-production.js COPY --from=builder /app/data/images ./data/images # Create directories RUN mkdir -p /app/workspace /app/data # Ensure proper permissions RUN chown -R node:node /app # Switch to non-root user USER node # Expose port EXPOSE 8080 # Set environment ENV NODE_ENV=production ENV PORT=8080 ENV DATABASE_PATH=/app/data/gallus_cms.db # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:8080/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" # Run DB migrations if present, then start application CMD ["/bin/sh", "-lc", "[ -f dist/migrate.js ] && node dist/migrate.js || true; node dist/index.js"]