You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							170 lines
						
					
					
						
							5.2 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							170 lines
						
					
					
						
							5.2 KiB
						
					
					
				| # TimeSafari Docker Build | |
| # Author: Matthew Raymer | |
| # Description: Multi-stage Docker build for TimeSafari web application | |
| #  | |
| # Build Process: | |
| # 1. Base stage: Node.js with build dependencies | |
| # 2. Builder stage: Copy pre-built web assets from host | |
| # 3. Production stage: Nginx server with optimized assets | |
| #  | |
| # Note: Web assets are built on the host using npm scripts before Docker build | |
| # | |
| # Security Features: | |
| # - Non-root user execution | |
| # - Minimal attack surface with Alpine Linux | |
| # - Multi-stage build to reduce image size | |
| # - No build dependencies in final image | |
| # | |
| # Usage: | |
| #   IMPORTANT: Build web assets first, then build Docker image | |
| #    | |
| #   Using npm scripts (recommended): | |
| #   Production: npm run build:web:docker:prod | |
| #   Test: npm run build:web:docker:test | |
| #   Development: npm run build:web:docker | |
| #    | |
| #   Manual workflow: | |
| #   1. Build web assets: npm run build:web:build -- --mode production | |
| #   2. Build Docker: docker build -t timesafari:latest . | |
| #    | |
| #   Note: For development, use npm run build:web directly (no Docker needed) | |
| # | |
| # Build Arguments: | |
| #   BUILD_MODE: development, test, or production (default: production) | |
| #   NODE_ENV: node environment (default: production) | |
| # | |
| # Environment Variables: | |
| #   NODE_ENV: Build environment (development/production) | |
| #   BUILD_MODE: Build mode for asset selection (development/test/production) | |
| # | |
| # Build Context: | |
| #   This Dockerfile is designed to work when the build context is set to | |
| #   ./crowd-funder-for-time-pwa from the parent directory (where docker-compose.yml is located) | |
|  | |
| # ============================================================================= | |
| # BASE STAGE - Common dependencies and setup | |
| # ============================================================================= | |
| FROM node:22-alpine3.20 AS base | |
|  | |
| # Install system dependencies for build process | |
| RUN apk add --no-cache \ | |
|     bash \ | |
|     git \ | |
|     python3 \ | |
|     py3-pip \ | |
|     py3-setuptools \ | |
|     make \ | |
|     g++ \ | |
|     gcc \ | |
|     && rm -rf /var/cache/apk/* | |
|  | |
| # Create non-root user for security | |
| RUN addgroup -g 1001 -S nodejs && \ | |
|     adduser -S nextjs -u 1001 | |
|  | |
| # Set working directory | |
| WORKDIR /app | |
|  | |
| # Copy package files for dependency installation | |
| # Note: These files are in the project root (crowd-funder-for-time-pwa directory) | |
| COPY package*.json ./ | |
|  | |
| # Install dependencies with security audit | |
| RUN npm ci --only=production --audit --fund=false && \ | |
|     npm audit fix --audit-level=moderate || true | |
|  | |
| # ============================================================================= | |
| # BUILDER STAGE - Copy pre-built assets | |
| # ============================================================================= | |
| FROM base AS builder | |
|  | |
| # Define build arguments with defaults | |
| ARG BUILD_MODE=production | |
| ARG NODE_ENV=production | |
| 
 | |
| # Set environment variables from build arguments | |
| ENV BUILD_MODE=${BUILD_MODE} | |
| ENV NODE_ENV=${NODE_ENV} | |
|  | |
| # Copy pre-built assets from host | |
| # Note: dist/ directory is in the project root (crowd-funder-for-time-pwa directory) | |
| COPY dist/ ./dist/ | |
|  | |
| # Verify build output exists | |
| RUN ls -la dist/ || (echo "Build output not found in dist/ directory" && exit 1) | |
|  | |
| # ============================================================================= | |
| # PRODUCTION STAGE - Nginx server | |
| # ============================================================================= | |
| FROM nginx:alpine AS production | |
|  | |
| # Define build arguments for production stage | |
| ARG BUILD_MODE=production | |
| ARG NODE_ENV=production | |
| 
 | |
| # Set environment variables | |
| ENV BUILD_MODE=${BUILD_MODE} | |
| ENV NODE_ENV=${NODE_ENV} | |
|  | |
| # Install security updates and clean cache | |
| RUN apk update && \ | |
|     apk upgrade && \ | |
|     apk add --no-cache \ | |
|     curl \ | |
|     && rm -rf /var/cache/apk/* | |
|  | |
| # Use existing nginx user from base image (nginx user and group already exist) | |
| # No need to create new user as nginx:alpine already has nginx user | |
|  | |
| # Copy main nginx configuration | |
| COPY docker/nginx.conf /etc/nginx/nginx.conf | |
|  | |
| # Copy production nginx configuration | |
| COPY docker/default.conf /etc/nginx/conf.d/default.conf | |
|  | |
| # Copy built assets from builder stage | |
| COPY --from=builder --chown=nginx:nginx /app/dist /usr/share/nginx/html | |
|  | |
| # Create necessary directories with proper permissions | |
| RUN mkdir -p /var/cache/nginx /var/log/nginx /tmp && \ | |
|     chown -R nginx:nginx /var/cache/nginx /var/log/nginx /tmp && \ | |
|     chown -R nginx:nginx /usr/share/nginx/html | |
|  | |
| # Switch to non-root user | |
| USER nginx | |
|  | |
| # Expose port 80 | |
| EXPOSE 80 | |
|  | |
| # Health check | |
| HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ | |
|     CMD curl -f http://localhost/ || exit 1 | |
|  | |
| # Start nginx with proper signal handling | |
| CMD ["nginx", "-g", "daemon off;"] | |
|  | |
| # ============================================================================= | |
| # TEST STAGE - For test environment testing | |
| # ============================================================================= | |
| FROM production AS test | |
|  | |
| # Define build arguments for test stage | |
| ARG BUILD_MODE=test | |
| ARG NODE_ENV=test | |
| 
 | |
| # Set environment variables | |
| ENV BUILD_MODE=${BUILD_MODE} | |
| ENV NODE_ENV=${NODE_ENV} | |
|  | |
| # Copy test-specific nginx configuration | |
| COPY docker/staging.conf /etc/nginx/conf.d/default.conf | |
|  | |
| # Expose port 80 | |
| EXPOSE 80 | |
|  | |
| # Health check for staging | |
| HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ | |
|     CMD curl -f http://localhost/health || exit 1 | |
|  | |
| # Start nginx | |
| CMD ["nginx", "-g", "daemon off;"]  |