# # Use an official Python runtime as a parent image # FROM python:3.11-slim # WORKDIR /app #add by P # # Set environment variables for Hugging Face cache # ENV DEBIAN_FRONTEND=noninteractive \ # PYTHONUNBUFFERED=1 \ # PYTHONDONTWRITEBYTECODE=1 \ # TRANSFORMERS_CACHE=/app/cache \ # HF_HOME=/app/cache \ # NLTK_DATA=/app/nltk_data \ # MPLCONFIGDIR=/app/.config/matplotlib # COPY requirements.txt requirements.txt # COPY templates/ /app/templates # COPY utils/ /app/utils # COPY app.py app.py # COPY blocks/ /app/blocks/ # COPY generated_projects/ /app/generated_projects/ # COPY blocks/sprites/ /app/blocks/sprites/ # COPY blocks/Backdrops/ /app/blocks/Backdrops/ # COPY blocks/sound/ /app/blocks/sound/ # # COPY OUTPUTS/ /app/OUTPUTS # COPY . /app/ # COPY . . # # Install system dependencies # RUN apt-get update && apt-get install -y \ # build-essential \ # libglib2.0-0 \ # libsm6 \ # libxext6 \ # libxrender-dev \ # tesseract-ocr \ # poppler-utils \ # libgl1 \ # # ffmpeg \ # # libopencv-dev \ # curl \ # ca-certificates \ # && apt-get clean \ # && rm -rf /var/lib/apt/lists/* # RUN pip install --upgrade pip && pip install -r requirements.txt # # Create necessary directories with correct permissions # RUN mkdir -p /app/nltk_data /app/.config/matplotlib \ # && mkdir -p /app/cache /app/data /app/logs /app/outputs /app/blocks \ # && mkdir -p /app/outputs/DETECTED_IMAGE /app/outputs/SCANNED_IMAGE /app/outputs/EXTRACTED_JSON \ # && chmod -R 777 /app/cache /app/blocks /app/data /app/logs /app/outputs /app/outputs/SCANNED_IMAGE /app/outputs/EXTRACTED_JSON /app/outputs/DETECTED_IMAGE \ # && chmod -R 777 /app # # Set Flask environment variables # ENV FLASK_APP=app.py \ # FLASK_ENV=production # # Expose port and start application # EXPOSE 7860 # # CMD ["python", "app.py"] # CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "2", "app:app"] # #CMD ["gunicorn", "--bind", "0.0.0.0:7860", "--workers", "", "--timeout", "360", "app:app"] # Dockerfile — CPU-optimized, permissions-fixed, non-root runtime FROM python:3.11-slim # Set working dir WORKDIR /app # Environment: Hugging Face cache + force CPU behavior ENV DEBIAN_FRONTEND=noninteractive \ PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ TRANSFORMERS_CACHE=/app/cache \ HF_HOME=/app/cache \ NLTK_DATA=/app/nltk_data \ MPLCONFIGDIR=/app/.config/matplotlib \ XDG_CACHE_HOME=/app/.cache \ # Force CPU-only (ensure no CUDA attempts) CUDA_VISIBLE_DEVICES= \ PYTORCH_ENABLE_MPS=0 \ PYTORCH_NO_CUDA=1 # Copy minimal files first (leverage layer caching) COPY requirements.txt ./requirements.txt COPY app.py ./app.py COPY templates/ ./templates/ COPY utils/ ./utils/ COPY blocks/ ./blocks/ COPY generated_projects/ ./generated_projects/ # Install system dependencies (including fontconfig/fonts) RUN apt-get update && apt-get install -y --no-install-recommends \ fontconfig \ fonts-dejavu-core \ build-essential \ curl \ ca-certificates \ libglib2.0-0 \ libsm6 \ libxext6 \ libxrender-dev \ libgl1 \ tesseract-ocr \ poppler-utils \ && apt-get clean && rm -rf /var/lib/apt/lists/* # Create runtime directories, cache dirs, and static dir BEFORE pip install to ensure permissions # We will chown to non-root user later RUN mkdir -p /app/.config/matplotlib \ /app/cache /app/nltk_data /nltk_data \ /app/.cache /app/.cache/fontconfig /root/.cache/fontconfig \ /app/logs /app/outputs /app/outputs/DETECTED_IMAGE /app/outputs/SCANNED_IMAGE /app/outputs/EXTRACTED_JSON \ /app/data /app/blocks /app/static \ && chmod -R 777 /app # Install Python dependencies RUN pip install --upgrade pip \ && pip install --no-cache-dir -r requirements.txt # Pre-download NLTK packages into the chosen directory so runtime import doesn't try to write ENV NLTK_DATA=/app/nltk_data RUN python -m nltk.downloader -d /app/nltk_data punkt averaged_perceptron_tagger wordnet || true # Populate font cache (will quiet fontconfig warnings) RUN fc-cache -f -v || true # Create a less-privileged user and give ownership of /app to that user RUN useradd -m -u 1000 appuser \ && chown -R appuser:appuser /app # Switch to non-root user (IMPORTANT: do this AFTER chown) USER appuser # Set Flask env ENV FLASK_APP=app.py \ FLASK_ENV=production # Expose port EXPOSE 7860 # HEALTHCHECK (optional) — uses lightweight endpoint; if you don't have /healthz, change it or remove. HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ CMD curl -f http://127.0.0.1:7860/healthz || exit 1 # Run Gunicorn as non-root appuser: single worker + threads, no timeout CMD ["gunicorn", "app:app", "-b", "0.0.0.0:7860", "-w", "1", "--threads", "4", "-k", "gthread", "--timeout", "0", "--graceful-timeout", "0"]