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:
Cipher Vance 2025-09-18 20:06:37 -05:00
parent bb91aff5fd
commit 485320737b
2 changed files with 46 additions and 43 deletions

View file

@ -1,9 +1,13 @@
.env
.git
__pycache__/
*.py[cod]
.gitignore
README.md
Dockerfile
.dockerignore
.air.toml
tmp/
.vscode/
.idea/
*.log
!.env
venv/
.venv/
dist/
build/
coverage.out
rideaware-api

View file

@ -1,53 +1,52 @@
FROM python:3.10-slim AS builder
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1
# Build stage
FROM golang:1.21-alpine AS builder
# Set working directory
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential gcc \
&& rm -rf /var/lib/apt/lists/*
# Install git (needed for some Go modules)
RUN apk add --no-cache git
COPY requirements.txt .
# Copy go mod files
COPY go.mod go.sum ./
RUN python -m pip install --upgrade pip && \
pip wheel --no-deps -r requirements.txt -w /wheels && \
pip wheel --no-deps gunicorn -w /wheels
# Download dependencies
RUN go mod download
FROM python:3.10-slim AS runtime
# Copy source code
COPY . .
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PORT=5000 \
WSGI_MODULE=server:app \
GUNICORN_WORKERS=2 \
GUNICORN_THREADS=4 \
GUNICORN_TIMEOUT=60 \
FLASK_APP=server.py
# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o rideaware-api .
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
RUN pip install --no-cache-dir /wheels/* && rm -rf /wheels
# Create non-root user
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
# Install python-dotenv if not already in requirements.txt
RUN pip install python-dotenv
# Set working directory
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
COPY --chown=app:app .env .env
# Switch to non-root user
USER appuser
EXPOSE 5000
# Expose port
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
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()"
# Health check
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"]