feat: replace Python Dockerfile with Go multi-stage build
- Convert from Python 3.10 Flask app to Go 1.21 Alpine build - Add multi-stage Docker build for optimized production image - Create non-root user for security - Update health check for new port 8080 - Add comprehensive .dockerignore for Go project
This commit is contained in:
		
							parent
							
								
									bb91aff5fd
								
							
						
					
					
						commit
						485320737b
					
				
					 2 changed files with 46 additions and 43 deletions
				
			
		|  | @ -1,9 +1,13 @@ | ||||||
|  | .env | ||||||
| .git | .git | ||||||
| __pycache__/ | .gitignore | ||||||
| *.py[cod] | README.md | ||||||
|  | Dockerfile | ||||||
|  | .dockerignore | ||||||
|  | .air.toml | ||||||
|  | tmp/ | ||||||
|  | .vscode/ | ||||||
|  | .idea/ | ||||||
| *.log | *.log | ||||||
| !.env | coverage.out | ||||||
| venv/ | rideaware-api | ||||||
| .venv/ |  | ||||||
| dist/ |  | ||||||
| build/ |  | ||||||
							
								
								
									
										71
									
								
								Dockerfile
									
										
									
									
									
								
							
							
						
						
									
										71
									
								
								Dockerfile
									
										
									
									
									
								
							|  | @ -1,53 +1,52 @@ | ||||||
| FROM python:3.10-slim AS builder | # Build stage | ||||||
| 
 | FROM golang:1.21-alpine AS builder | ||||||
| ENV PYTHONDONTWRITEBYTECODE=1 \ |  | ||||||
|     PYTHONUNBUFFERED=1 \ |  | ||||||
|     PIP_NO_CACHE_DIR=1 |  | ||||||
| 
 | 
 | ||||||
|  | # Set working directory | ||||||
| WORKDIR /app | WORKDIR /app | ||||||
| 
 | 
 | ||||||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | # Install git (needed for some Go modules) | ||||||
|     build-essential gcc \ | RUN apk add --no-cache git | ||||||
|  && rm -rf /var/lib/apt/lists/* |  | ||||||
| 
 | 
 | ||||||
| COPY requirements.txt . | # Copy go mod files | ||||||
|  | COPY go.mod go.sum ./ | ||||||
| 
 | 
 | ||||||
| RUN python -m pip install --upgrade pip && \ | # Download dependencies | ||||||
|     pip wheel --no-deps -r requirements.txt -w /wheels && \ | RUN go mod download | ||||||
|     pip wheel --no-deps gunicorn -w /wheels |  | ||||||
| 
 | 
 | ||||||
| FROM python:3.10-slim AS runtime | # Copy source code | ||||||
|  | COPY . . | ||||||
| 
 | 
 | ||||||
| ENV PYTHONDONTWRITEBYTECODE=1 \ | # Build the application | ||||||
|     PYTHONUNBUFFERED=1 \ | RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o rideaware-api . | ||||||
|     PIP_NO_CACHE_DIR=1 \ |  | ||||||
|     PORT=5000 \ |  | ||||||
|     WSGI_MODULE=server:app \ |  | ||||||
|     GUNICORN_WORKERS=2 \ |  | ||||||
|     GUNICORN_THREADS=4 \ |  | ||||||
|     GUNICORN_TIMEOUT=60 \ |  | ||||||
|     FLASK_APP=server.py |  | ||||||
| 
 | 
 | ||||||
| WORKDIR /app | # Production stage | ||||||
|  | FROM alpine:latest | ||||||
| 
 | 
 | ||||||
| RUN groupadd -g 10001 app && useradd -m -u 10001 -g app app | # Install ca-certificates for HTTPS requests and timezone data | ||||||
|  | RUN apk --no-cache add ca-certificates tzdata | ||||||
| 
 | 
 | ||||||
| COPY --from=builder /wheels /wheels | # Create non-root user | ||||||
| RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels | RUN addgroup -g 1001 -S appgroup && \ | ||||||
|  |     adduser -u 1001 -S appuser -G appgroup | ||||||
| 
 | 
 | ||||||
| # Install python-dotenv if not already in requirements.txt | # Set working directory | ||||||
| RUN pip install python-dotenv | WORKDIR /home/appuser | ||||||
| 
 | 
 | ||||||
| USER app | # Copy binary from builder stage | ||||||
|  | COPY --from=builder /app/rideaware-api . | ||||||
| 
 | 
 | ||||||
| COPY --chown=app:app . . | # Change ownership to non-root user | ||||||
|  | RUN chown -R appuser:appgroup /home/appuser | ||||||
| 
 | 
 | ||||||
| # Copy .env file specifically | # Switch to non-root user | ||||||
| COPY --chown=app:app .env .env | USER appuser | ||||||
| 
 | 
 | ||||||
| EXPOSE 5000 | # Expose port | ||||||
|  | EXPOSE 8080 | ||||||
| 
 | 
 | ||||||
| HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \ | # Health check | ||||||
|   CMD python -c "import os,socket; s=socket.socket(); s.settimeout(2); s.connect(('127.0.0.1', int(os.getenv('PORT', '5000')))); s.close()" | HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ | ||||||
|  |     CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 | ||||||
| 
 | 
 | ||||||
| CMD ["sh", "-c", "exec gunicorn $WSGI_MODULE --bind=0.0.0.0:$PORT --workers=$GUNICORN_WORKERS --threads=$GUNICORN_THREADS --timeout=$GUNICORN_TIMEOUT --access-logfile=- --error-logfile=- --keep-alive=5"] | # Run the application | ||||||
|  | CMD ["./rideaware-api"] | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Cipher Vance
						Cipher Vance