# Use BuildKit for better caching # syntax=docker/dockerfile:1.4 # Base stage for common settings FROM node:20-alpine AS base WORKDIR /app # Dependencies stage - caches npm install unless package.json changes FROM base AS deps COPY package.json package-lock.json ./ RUN --mount=type=cache,target=/root/.npm \ npm ci --force --prefer-offline # Build stage - only rebuilds when source files change FROM base AS builder WORKDIR /app # Copy node_modules from deps stage COPY --from=deps /app/node_modules ./node_modules # Get git and create git hash file before copying source RUN apk add --no-cache git # Copy package files first (these change less frequently) COPY package.json package-lock.json ./ COPY next.config.mjs tsconfig.json ./ # Copy source files (these change most frequently) COPY public ./public COPY app ./app COPY components ./components COPY lib ./lib COPY config ./config COPY services ./services COPY utils ./utils COPY middleware.ts ./ COPY .env* ./ COPY styles* ./ COPY hooks ./hooks COPY models ./models # Copy git directory if it exists or create dummy hash COPY .git ./.git 2>/dev/null || : RUN if [ -d .git ]; then \ git rev-parse --short HEAD > /app/git_commit_sha; \ else \ echo "unknown" > /app/git_commit_sha; \ fi # Set build env vars ENV NEXT_PUBLIC_API_URL=/api ENV NODE_ENV=production # Build (using build cache when possible) RUN --mount=type=cache,target=/app/.next/cache \ echo "Building with GIT_COMMIT_SHA=$(cat /app/git_commit_sha)" && \ npm run build # Production stage FROM node:20-alpine AS runner WORKDIR /app # Set production env vars ENV NODE_ENV=production ENV NEXT_PUBLIC_API_URL=/api ENV SERVER_API_URL=https://internal-api.inboxi.ng # Create non-root user for security RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs # Copy only necessary files COPY --from=builder /app/public ./public COPY --from=builder /app/next.config.mjs ./ COPY --from=builder /app/git_commit_sha /app/git_commit_sha COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Verify git hash is readable RUN cat /app/git_commit_sha # Instead of using ENV with command substitution, create a wrapper script RUN echo '#!/bin/sh' > /app/start.sh && \ echo 'export GIT_COMMIT_SHA=$(cat /app/git_commit_sha)' >> /app/start.sh && \ echo 'exec node server.js' >> /app/start.sh && \ chmod +x /app/start.sh && \ cat /app/start.sh # Switch to non-root user USER nextjs EXPOSE 3000 # Use the wrapper script CMD ["/app/start.sh"]