# Backend Dockerfile FROM node:18-alpine AS builder # Install OpenSSL for Prisma compatibility RUN apk add --no-cache openssl openssl-dev # Set working directory WORKDIR /app # Copy package files COPY package*.json ./ # Install all dependencies (including devDependencies for build) RUN npm ci # Copy source code COPY . . # Build the application RUN npm run build # Production stage FROM node:18-alpine AS production # Install required system dependencies for Prisma and health checks RUN apk add --no-cache \ curl \ openssl \ openssl-dev \ libc6-compat \ && rm -rf /var/cache/apk/* # Install curl for healthcheck RUN apk add --no-cache curl # Create app user RUN addgroup -g 1001 -S nodejs RUN adduser -S backend -u 1001 # Set working directory WORKDIR /app # Copy package files COPY package*.json ./ # Install only production dependencies RUN npm ci --only=production && npm cache clean --force # Copy built application from builder stage COPY --from=builder /app/dist ./dist # Copy prisma schema for runtime COPY --from=builder /app/prisma ./prisma # Create uploads directory RUN mkdir -p uploads legacy-uploads && chown -R backend:nodejs uploads legacy-uploads # Create migration script for legacy uploads (via volumes) COPY </dev/null || true chown -R backend:nodejs /app/uploads echo "Upload migration completed." else echo "No legacy uploads found to migrate." fi EOF RUN chmod +x ./migrate-uploads.sh # Generate Prisma client RUN npx prisma generate # Switch to non-root user USER backend # Expose port EXPOSE 3001 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost:3001/api/health || exit 1 # Start the application CMD ["sh", "-c", "./migrate-uploads.sh && node dist/app.js"]