| # Stage 1: Build the React frontend | |
| FROM node:18 AS frontend-builder | |
| WORKDIR /app/frontend | |
| COPY frontend/package*.json ./ | |
| RUN npm install | |
| COPY frontend/ ./ | |
| # Explicitly set NODE_ENV to production to use .env.production | |
| ENV NODE_ENV=production | |
| RUN npm run build | |
| # Stage 2: Set up the Python backend and Nginx | |
| FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim | |
| # Install nginx | |
| RUN apt-get update && apt-get install -y nginx && rm -rf /var/lib/apt/lists/* | |
| # Create app directory and set permissions | |
| RUN mkdir /app && \ | |
| useradd -m -u 1000 user && \ | |
| chown -R user:user /app | |
| # Set the working directory | |
| WORKDIR /app | |
| # Copy the backend app and set permissions | |
| COPY --chown=user . /app | |
| # Copy the built frontend from the previous stage | |
| COPY --from=frontend-builder --chown=user /app/frontend/build /app/static | |
| # Configure nginx as root | |
| COPY nginx.conf /etc/nginx/nginx.conf | |
| RUN mkdir -p /var/log/nginx && \ | |
| chown -R user:user /var/log/nginx && \ | |
| chown -R user:user /var/lib/nginx && \ | |
| touch /var/run/nginx.pid && \ | |
| chown -R user:user /var/run/nginx.pid | |
| # Switch to user for Python setup | |
| USER user | |
| # Set the environment variables | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH \ | |
| UVICORN_WS_PROTOCOL=websockets | |
| # Install the Python dependencies | |
| RUN uv sync | |
| # Switch back to root to create start script | |
| USER root | |
| # Create start script that handles both nginx and uvicorn | |
| RUN echo '#!/bin/bash\n\ | |
| nginx -g "daemon off;" &\n\ | |
| echo "Nginx started..."\n\ | |
| su -c "bash -c \"source /app/.venv/bin/activate && uvicorn api:app --host 0.0.0.0 --port 8000\"" user\n\ | |
| ' > /app/start.sh && chmod +x /app/start.sh | |
| # Expose the Hugging Face port | |
| EXPOSE 7860 | |
| # Run both nginx and the backend | |
| CMD ["./start.sh"] |