# Build stage FROM node:20-alpine as build WORKDIR /app # Copy package files COPY package.json package-lock.json ./ # Install dependencies RUN npm install # Copy source code COPY . . # Build the application RUN npm run build # Production stage FROM nginx:alpine # Install necessary tools RUN apk add --no-cache curl # Create nginx configuration RUN echo 'server { \ listen 80; \ server_name localhost; \ root /usr/share/nginx/html; \ index index.html; \ \ # Gzip compression \ gzip on; \ gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; \ \ # Security headers \ add_header X-Frame-Options "SAMEORIGIN"; \ add_header X-XSS-Protection "1; mode=block"; \ add_header X-Content-Type-Options "nosniff"; \ \ # Trust proxy headers \ real_ip_header X-Forwarded-For; \ set_real_ip_from 0.0.0.0/0; \ \ # Handle proxy headers \ proxy_set_header Host $host; \ proxy_set_header X-Real-IP $remote_addr; \ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \ proxy_set_header X-Forwarded-Proto $scheme; \ \ location / { \ try_files $uri $uri/ /index.html; \ } \ \ # Cache static assets \ location /assets/ { \ expires 1y; \ add_header Cache-Control "public, no-transform"; \ } \ \ # Error pages \ error_page 404 /index.html; \ error_page 500 502 503 504 /50x.html; \ location = /50x.html { \ root /usr/share/nginx/html; \ } \ }' > /etc/nginx/conf.d/default.conf # Copy built assets from build stage COPY --from=build /app/dist /usr/share/nginx/html # Expose port 80 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]