# Build stage: Install dependencies using pixi FROM ghcr.io/prefix-dev/pixi:latest AS builder WORKDIR /app # Copy project files COPY pixi.toml . COPY pyproject.toml . COPY scripts/ scripts/ COPY bttoxin/ bttoxin/ COPY web/ web/ COPY Data/ Data/ COPY frontend/ frontend/ # Install all pixi environments RUN pixi install # Create shell hook for webbackend environment RUN pixi shell-hook -e webbackend > /shell-hook.sh RUN echo 'exec "$@"' >> /shell-hook.sh # =========================== # Stage 1: Build frontend # =========================== FROM node:20 AS frontend-builder WORKDIR /app COPY --from=builder /app/frontend ./ RUN npm install -g pnpm && pnpm install && pnpm build # =========================== # Stage 2: Production (Nginx + Backend) # =========================== FROM ubuntu:24.04 AS production WORKDIR /app # Install Nginx and runtime dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ nginx \ curl \ && rm -rf /var/lib/apt/lists/* # Copy pixi executable from builder COPY --from=builder /usr/local/bin/pixi /usr/local/bin/pixi RUN chmod +x /usr/local/bin/pixi # Copy backend environment from builder COPY --from=builder /app/.pixi /app/.pixi COPY --from=builder /shell-hook.sh /shell-hook.sh # Copy backend code COPY --from=builder /app/web /app/web COPY --from=builder /app/Data /app/Data COPY --from=builder /app/bttoxin /app/bttoxin COPY --from=builder /app/scripts /app/scripts # Copy built frontend COPY --from=frontend-builder /app/dist /var/www/html # Create jobs directory RUN mkdir -p /app/jobs && chmod 777 /app/jobs # Configure Nginx RUN cat > /etc/nginx/sites-available/default << 'EOF' server { listen 80; server_name _; root /var/www/html; index index.html; # Gzip compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; # Allow uploads up to 100M client_max_body_size 100M; # Frontend routes - serve index.html for SPA location / { try_files $uri $uri/ /index.html; } # API proxy to backend location /api/ { proxy_pass http://127.0.0.1:8000/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } # Health check endpoint location /health { proxy_pass http://127.0.0.1:8000/api/health; } } EOF # Expose port EXPOSE 80 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD curl -f http://localhost/health || exit 1 # Entrypoint ENTRYPOINT ["/bin/bash", "/shell-hook.sh"] # Command: Start Nginx and Backend CMD ["bash", "-c", "\ mkdir -p /app/jobs && \ uvicorn web.backend.main:app --host 127.0.0.1 --port 8000 & \ nginx -g 'daemon off;' \ "]