FROM node:18-alpine AS frontend-builder # Build frontend WORKDIR /app/frontend COPY frontend/package*.json ./ RUN npm ci COPY frontend/ ./ # Set environment for single container (use relative paths) ENV NEXT_PUBLIC_API_URL="" RUN npm run build # Main container with Python and built frontend FROM python:3.11-slim WORKDIR /app # Install system dependencies RUN apt-get update && apt-get install -y \ gcc \ g++ \ libldap2-dev \ libsasl2-dev \ libssl-dev \ default-libmysqlclient-dev \ pkg-config \ curl \ && rm -rf /var/lib/apt/lists/* # Copy and install Python dependencies COPY backend/requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt # Copy backend application COPY backend/ ./ # Copy built frontend from builder stage COPY --from=frontend-builder /app/frontend/out ./frontend/out # Create necessary directories RUN mkdir -p logs uploads # Set environment variables ENV FLASK_APP=app.py ENV PYTHONUNBUFFERED=1 ENV FLASK_ENV=production # Expose only one port EXPOSE 12011 # Health check HEALTHCHECK --interval=30s --timeout=10s --retries=3 --start-period=40s \ CMD curl -f http://localhost:12011/api/health/ || exit 1 # Run with Gunicorn for production (supports 200+ users) CMD ["gunicorn", "--bind", "0.0.0.0:12011", "--worker-class", "gthread", "--workers", "4", "--threads", "8", "--timeout", "120", "--keep-alive", "10", "--max-requests", "2000", "--max-requests-jitter", "200", "--forwarded-allow-ips", "*", "--access-logfile", "-", "app:app"]