FROM python:3.10.9-slim ENV PYTHONUNBUFFERED=1 ENV DEBIAN_FRONTEND=noninteractive # ------------------------- # System dependencies # ------------------------- RUN apt-get update && apt-get install -y \ curl \ ca-certificates \ gnupg \ && rm -rf /var/lib/apt/lists/* # ------------------------- # Grafana APT repository (REQUIRED) # ------------------------- RUN mkdir -p /usr/share/keyrings \ && curl -fsSL https://apt.grafana.com/gpg.key \ | gpg --dearmor -o /usr/share/keyrings/grafana.gpg \ && echo "deb [signed-by=/usr/share/keyrings/grafana.gpg] https://apt.grafana.com stable main" \ > /etc/apt/sources.list.d/grafana.list # ------------------------- # Install Prometheus & Grafana # ------------------------- RUN apt-get update && apt-get install -y \ prometheus \ grafana \ && rm -rf /var/lib/apt/lists/* # ------------------------- # Non-root user (HF requirement) # ------------------------- RUN useradd -m -u 1000 appuser WORKDIR /app # ------------------------- # Python dependencies # ------------------------- COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # ------------------------- # Copy app # ------------------------- COPY --chown=appuser:appuser . . # ------------------------- # HF writable directories # ------------------------- RUN mkdir -p /tmp/prometheus /tmp/grafana /tmp/chroma_db \ && chown -R appuser:appuser /tmp/prometheus /tmp/grafana /tmp/chroma_db \ && chmod -R 700 /tmp/prometheus /tmp/grafana /tmp/chroma_db # ------------------------- # Grafana ENV (HF reverse proxy) # ------------------------- ENV GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s/grafana ENV GF_SERVER_SERVE_FROM_SUB_PATH=true ENV GF_SERVER_HTTP_PORT=3000 ENV GF_PATHS_DATA=/tmp/grafana ENV GF_PATHS_LOGS=/tmp/grafana ENV GF_PATHS_PLUGINS=/tmp/grafana ENV GF_AUTH_ANONYMOUS_ENABLED=true ENV GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer # ------------------------- # Startup script (HF safe) # ------------------------- RUN printf '%s\n' \ '#!/usr/bin/env bash' \ 'set -e' \ 'echo "Starting Prometheus..."' \ 'prometheus \ --config.file=/app/monitoring/prometheus.yml \ --storage.tsdb.path=/tmp/prometheus \ --storage.tsdb.retention.time=1d \ --log.level=warn \ --log.format=logfmt &' \ '' \ 'echo "Starting Grafana..."' \ '/usr/sbin/grafana-server --homepath=/usr/share/grafana &' \ '' \ 'echo "Waiting for Grafana..."' \ 'until curl -sf http://127.0.0.1:3000/api/health; do sleep 1; done' \ '' \ 'echo "Starting FastAPI..."' \ 'exec python -m uvicorn main:app --host 0.0.0.0 --port 7860' \ > /app/start.sh \ && chown appuser:appuser /app/start.sh \ && chmod +x /app/start.sh # ------------------------- # Runtime # ------------------------- USER appuser EXPOSE 7860 HEALTHCHECK --interval=60s --timeout=5s \ CMD curl --fail http://localhost:7860/health || exit 1 CMD ["/app/start.sh"]