yashprmr/MeridianFinancial
0
1# ─── Meridian Financial — HuggingFace Spaces Dockerfile ─────────────────────2# Runs BOTH FastAPI (port 8000 internal) + Streamlit (port 7860 public)3# in a single container managed by supervisord.4#5# HuggingFace Spaces exposes port 7860 publicly.6# The dashboard connects to the API at http://localhost:8000 (internal).7#8# Build: (HF Spaces builds this automatically on push)9# ─────────────────────────────────────────────────────────────────────────────10 11FROM python:3.11-slim12 13LABEL org.opencontainers.image.title="Meridian Financial — HF Spaces"14LABEL org.opencontainers.image.description="FastAPI + Streamlit in one container"15 16# ── System dependencies ────────────────────────────────────────────────────────17RUN apt-get update && apt-get install -y --no-install-recommends \18 curl \19 supervisor \20 && rm -rf /var/lib/apt/lists/*21 22WORKDIR /app23 24# ── Install Python dependencies ────────────────────────────────────────────────25# Backend first (heavy)26COPY requirements.txt ./requirements.txt27RUN pip install --no-cache-dir --upgrade pip \28 && pip install --no-cache-dir -r requirements.txt29 30# Dashboard (lightweight)31COPY dashboard/requirements.txt ./dashboard/requirements.txt32RUN pip install --no-cache-dir -r dashboard/requirements.txt33 34# ── Copy source code ───────────────────────────────────────────────────────────35COPY src/ ./src/36COPY config/ ./config/37COPY dashboard/ ./dashboard/38COPY scripts/ ./scripts/39 40# ── Copy pre-built artifacts ───────────────────────────────────────────────────41# The model.pkl, preprocessor.pkl, and chroma_store/ must be present.42# Commit them to the Space repo (see README) or pull from HF Hub at startup.43COPY artifacts/ ./artifacts/44COPY chroma_store/ ./chroma_store/45 46# ── Streamlit configuration ────────────────────────────────────────────────────47RUN mkdir -p /app/.streamlit48RUN cat > /app/.streamlit/config.toml << 'EOF'49[server]50headless = true51port = 786052enableCORS = false53enableXsrfProtection = false54 55[theme]56base = "dark"57primaryColor = "#6366f1"58backgroundColor = "#0f172a"59secondaryBackgroundColor = "#1e293b"60textColor = "#f1f5f9"61 62[browser]63gatherUsageStats = false64EOF65 66# ── supervisord configuration ──────────────────────────────────────────────────67RUN cat > /etc/supervisor/conf.d/meridian.conf << 'EOF'68[supervisord]69nodaemon=true70logfile=/tmp/supervisord.log71pidfile=/tmp/supervisord.pid72user=root73 74[program:api]75command=python -m uvicorn src.serving.app:app --host 0.0.0.0 --port 8000 --workers 176directory=/app77environment=PYTHONPATH="/app",APP_ENV="production"78autostart=true79autorestart=true80stdout_logfile=/tmp/api.log81stderr_logfile=/tmp/api_err.log82startretries=583startsecs=1084 85[program:dashboard]86command=streamlit run dashboard/app.py --server.port=7860 --server.address=0.0.0.087directory=/app88environment=PYTHONPATH="/app",API_BASE_URL="http://localhost:8000",ENVIRONMENT="production"89autostart=true90autorestart=true91# Dashboard starts after API has time to initialize92startdelay=2093stdout_logfile=/tmp/dashboard.log94stderr_logfile=/tmp/dashboard_err.log95startretries=596EOF97 98# ── Environment ────────────────────────────────────────────────────────────────99ENV PYTHONPATH=/app \100 PYTHONDONTWRITEBYTECODE=1 \101 PYTHONUNBUFFERED=1 \102 API_BASE_URL=http://localhost:8000 \103 ENVIRONMENT=production \104 APP_PORT=8000105 106# HF Spaces requires port 7860107EXPOSE 7860108 109# ── Healthcheck (checks Streamlit) ─────────────────────────────────────────────110HEALTHCHECK --interval=30s --timeout=15s --start-period=120s --retries=5 \111 CMD curl -sf http://localhost:7860/_stcore/health || exit 1112 113# ── Start both services ────────────────────────────────────────────────────────114CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]115 