# Backend Dockerfile # Multi-stage build for optimized production image # Stage 1: Build stage FROM node:20-alpine AS builder WORKDIR /app # Copy package files COPY package*.json ./ # Install dependencies # Use npm ci if package-lock.json exists, otherwise npm install RUN if [ -f package-lock.json ]; then \ npm ci --omit=dev; \ else \ npm install --only=production; \ fi # Stage 2: Production stage FROM node:20-alpine # Install required packages RUN apk add --no-cache \ sqlite \ tini # Create app user RUN addgroup -g 1001 -S oltalama && \ adduser -S oltalama -u 1001 -G oltalama WORKDIR /app # Copy dependencies from builder COPY --from=builder /app/node_modules ./node_modules # Copy application code COPY --chown=oltalama:oltalama . . # Copy entrypoint script COPY --chown=oltalama:oltalama docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh # Create necessary directories RUN mkdir -p database logs && \ chown -R oltalama:oltalama /app # Switch to non-root user USER oltalama # Expose port EXPOSE 3000 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" # Use tini and custom entrypoint for proper signal handling and auto-config ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"] # Start application CMD ["node", "src/app.js"]