tradesenseAi / Dockerfile.cloudrun
Niranjan-Murugarasu024
feat: TradeSense AI Chairman Edition production release ready for Hugging Face Spaces
0125724
Raw History Blame Contribute Delete
2 kB
# ==============================================================================
# TradeSense AI — Production Google Cloud Run Dockerfile (Milestone 19)
# Multi-stage slim build, non-root execution, dynamic $PORT handling.
# ==============================================================================
FROM python:3.11-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
curl \
&& rm -rf /var/lib/apt/lists/*
COPY pyproject.toml .
# Install dependencies in virtual environment
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install --no-cache-dir --upgrade pip setuptools wheel
RUN pip install --no-cache-dir \
fastapi \
uvicorn \
pydantic \
numpy \
pandas \
scipy \
statsmodels \
scikit-learn \
yfinance \
pytest \
httpx
# Final slim runtime container
FROM python:3.11-slim AS runner
WORKDIR /app
ENV PATH="/opt/venv/bin:$PATH" \
PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PORT=8080 \
APP_ENV=production \
STORAGE_BACKEND=local
# Copy virtualenv from builder
COPY --from=builder /opt/venv /opt/venv
# Create unprivileged system user (UID 10001)
RUN groupadd -g 10001 appgroup && \
useradd -u 10001 -g appgroup -s /bin/sh -m appuser
# Copy application source code
COPY backend /app/backend
COPY quant /app/quant
COPY templates /app/templates
COPY static /app/static
COPY data /app/data
# Set ownership to non-root user
RUN chown -R appuser:appgroup /app
USER appuser
# Container local healthcheck (for Docker inspection)
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:' + str(os.environ.get('PORT', 8080)) + '/health').read()" || exit 1
# Cloud Run dynamic PORT binding
EXPOSE 8080
CMD ["sh", "-c", "exec uvicorn backend.app.main:app --host 0.0.0.0 --port ${PORT:-8080} --workers 2 --proxy-headers"]