# =============================================================================
# Multi-stage Dockerfile for a Node.js application
#
# Stage 1: Install dependencies and build the project
# Stage 2: Create a minimal production image
#
# Build:   docker build -t myapp:latest .
# Run:     docker run -p 3000:3000 --env-file .env myapp:latest
# =============================================================================

# --------------- Stage 1: Build ---------------
FROM node:20-alpine AS builder

# Install build tools needed for native modules (e.g. bcrypt, sharp)
RUN apk add --no-cache python3 make g++

WORKDIR /app

# Copy dependency manifests first to leverage Docker layer caching.
# Changes to source code won't bust the npm-install cache.
COPY package.json package-lock.json ./

RUN npm ci --ignore-scripts \
    && npm rebuild

# Copy the rest of the application source
COPY tsconfig.json ./
COPY src/ src/
COPY public/ public/

# Build the TypeScript project
RUN npm run build

# Remove development dependencies to shrink the final image
RUN npm prune --production

# --------------- Stage 2: Production ---------------
FROM node:20-alpine AS production

# Security: run as a non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

WORKDIR /app

# Copy only the artifacts we need from the build stage
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/public ./public
COPY --from=builder --chown=appuser:appgroup /app/package.json ./

# Expose the application port
EXPOSE 3000

# Use a non-root user for all subsequent commands
USER appuser

# Health check to let orchestrators know when the app is ready
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD wget -qO- http://localhost:3000/health || exit 1

# Set production environment variables
ENV NODE_ENV=production \
    PORT=3000

# Start the application
CMD ["node", "dist/server.js"]