# ============================================ # Stage 1: Builder # ============================================ FROM python:3.13-alpine AS builder # Install build dependencies RUN apk add --no-cache \ gcc \ musl-dev \ libffi-dev \ openssl-dev \ cargo # Create virtual environment RUN python -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" # Set working directory WORKDIR /build # Copy requirements first for better caching COPY requirements.txt . # Install dependencies RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir -r requirements.txt # ============================================ # Stage 2: Runtime # ============================================ FROM python:3.13-alpine AS runtime # Install runtime dependencies only RUN apk add --no-cache \ libstdc++ \ ca-certificates # Create non-root user for security RUN addgroup -g 1000 appuser && \ adduser -D -u 1000 -G appuser appuser # Copy virtual environment from builder COPY --from=builder /opt/venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" # Create application directory RUN mkdir /app && \ chown -R appuser:appuser /app WORKDIR /app # Copy application files COPY --chown=appuser:appuser app.py . COPY --chown=appuser:appuser llm_config.py . COPY --chown=appuser:appuser lib.py . RUN echo $CREDENTIALS > credentials.json COPY --chown=appuser:appuser static ./static # Copy and setup entrypoint script COPY entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh # Switch to non-root user USER appuser # Expose default port (can be overridden via PORT env var) EXPOSE 8000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT:-8000}/ || exit 1 # Set environment variables ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ PORT=8000 \ HOST=0.0.0.0 \ WORKERS=1 \ LOG_LEVEL=info # Use entrypoint script ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]