# Multi-stage build to optimize performance and security # Stage 1: Builder - Install dependencies and build as root FROM python:3.11-slim AS builder # Set working directory WORKDIR /app # Install system dependencies for sentence-transformers and FAISS RUN apt-get update && apt-get install -y \ gcc \ g++ \ wget \ curl \ git \ && rm -rf /var/lib/apt/lists/* # Install Node.js for frontend build RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - && \ apt-get install -y nodejs # Copy frontend package files and install dependencies first (for better caching) COPY crossword-app/frontend/package*.json ./frontend/ RUN cd frontend && npm ci # Copy Python backend requirements and install dependencies COPY crossword-app/backend-py/requirements.txt ./backend-py/ #COPY crossword-app/backend-py/requirements-dev.txt ./backend-py/ RUN pip install --no-cache-dir --upgrade pip && \ pip install --no-cache-dir torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 && \ pip install --no-cache-dir -r backend-py/requirements.txt # Copy all source code COPY crossword-app/frontend/ ./frontend/ COPY crossword-app/backend-py/ ./backend-py/ COPY crossword-app/words/ ./backend-py/words/ # Copy cache directory with pre-built models and NLTK data COPY cache-dir/ ./cache-dir/ RUN chmod -R 755 ./cache-dir/ || true # Build the React frontend RUN cd frontend && npm run build # Copy built frontend files to Python backend public directory RUN mkdir -p backend-py/public && cp -r frontend/dist/* backend-py/public/ # Stage 2: Runtime - Copy only necessary files as non-root user FROM python:3.11-slim AS runtime # Copy Python packages from builder stage COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=builder /usr/local/bin /usr/local/bin # Install minimal runtime dependencies RUN apt-get update && apt-get install -y \ curl \ && rm -rf /var/lib/apt/lists/* # Create non-root user RUN useradd -m -u 1000 appuser # Set working directory WORKDIR /app/backend-py # Copy built application files with correct ownership COPY --from=builder --chown=appuser:appuser /app/backend-py ./ # Copy cache directory to backend-py/cache for model and NLTK data COPY --from=builder --chown=appuser:appuser /app/cache-dir /app/backend-py/cache # Switch to non-root user USER appuser # Expose port 7860 (Hugging Face Spaces standard) EXPOSE 7860 # Set environment variables for production ENV NODE_ENV=production ENV PORT=7860 ENV PYTHONPATH=/app/backend-py ENV PYTHONUNBUFFERED=1 ENV PIP_NO_CACHE_DIR=1 # Set cache directory for thematic service and NLTK ENV CACHE_DIR=/app/backend-py/cache ENV NLTK_DATA=/app/backend-py/cache/nltk_data # Set vocabulary source and path for Norvig vocabulary ENV VOCAB_SOURCE=norvig ENV NORVIG_VOCAB_PATH=/app/backend-py/words/norvig/count_1w100k.txt # Health check # HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ # CMD curl -f http://localhost:7860/health || exit 1 # Start the Python backend server with uvicorn for better production performance CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]