# Multi-stage build for Astro static site # Build stage - use Node.js with pnpm for building FROM node:20-alpine AS builder # Install pnpm RUN corepack enable && corepack prepare pnpm@9.12.3 --activate # Set working directory WORKDIR /app # Copy package files for dependency installation COPY package.json pnpm-lock.yaml ./ # Install dependencies with frozen lockfile for reproducible builds RUN pnpm install --frozen-lockfile # Copy source code COPY . . # Build the Astro application RUN pnpm build # Production stage - minimal nginx:alpine for serving static files FROM nginx:1.25-alpine AS production # Install dumb-init for proper signal handling RUN apk add --no-cache dumb-init # Copy custom nginx configuration COPY docker/nginx/astro.conf /etc/nginx/conf.d/default.conf COPY docker/nginx/nginx.conf /etc/nginx/nginx.conf # Copy built static files from builder stage COPY --from=builder /app/dist /usr/share/nginx/html # Create nginx user and set proper permissions RUN addgroup -g 1001 -S nginx-user && \ adduser -S -D -H -u 1001 -h /var/cache/nginx -s /sbin/nologin -G nginx-user nginx-user && \ chown -R nginx-user:nginx-user /usr/share/nginx/html && \ chown -R nginx-user:nginx-user /var/cache/nginx && \ chown -R nginx-user:nginx-user /var/log/nginx && \ chown -R nginx-user:nginx-user /etc/nginx/conf.d && \ touch /var/run/nginx.pid && \ chown -R nginx-user:nginx-user /var/run/nginx.pid # Switch to non-root user USER nginx-user # Expose port 8080 (non-privileged port) EXPOSE 8080 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1 # Use dumb-init as entrypoint for proper signal handling ENTRYPOINT ["/usr/bin/dumb-init", "--"] # Start nginx in foreground CMD ["nginx", "-g", "daemon off;"]