FROM python:3.11-slim ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ UPLOAD_DIR=/app/uploads \ TTS_OUTPUT_DIR=/app/generated/audio \ GENERATED_VIDEO_JOBS_DIR=/app/generated-video-jobs \ GENERATED_VIDEO_OUTPUT_DIR=/app/generated-videos \ LEARN_LESSON_CACHE_DIR=/app/generated/learn-anything \ DOCDOE_RENDER_ROOT=/app \ DOCDOE_CONTENT_MANIFEST=/app/shared/content-manifest.json \ DOCDOE_TUITION_CONTRACT=/app/shared/tuition-content-contract.json # The final-video path invokes the repository's Remotion script. Keep the HF # image self-contained: Python alone cannot render videos. RUN apt-get update && apt-get install -y --no-install-recommends \ ffmpeg curl ca-certificates build-essential \ libnss3 libatk-bridge2.0-0 libxss1 libasound2 libxshmfence1 libgbm1 \ libxkbcommon0 libgtk-3-0 fonts-liberation \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir --upgrade pip \ && pip install --no-cache-dir -r requirements.txt COPY package.json package-lock.json /app/ RUN npm ci --include=optional --no-audit --no-fund RUN useradd -m -u 1000 user \ && chown -R user:user /app COPY --chown=user:user . . # Install the pinned Remotion browser during image construction, not a student's job. RUN npx remotion browser ensure && chown -R user:user /app USER user EXPOSE 7860 # Liveness only: /health always returns 200 and does not check Supabase/R2, so a # healthy container here does NOT mean the backend can serve real requests. Use # /health/deep for readiness. HEALTHCHECK --interval=30s --timeout=10s --start-period=20s --retries=3 \ CMD curl -fsS http://127.0.0.1:${PORT:-7860}/health || exit 1 CMD ["sh", "-c", "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-7860}"]