|
| 1 | +######################################################################## |
| 2 | +# Stage 1: Frontend build |
| 3 | +######################################################################## |
| 4 | +FROM node:slim AS frontend-builder |
| 5 | +WORKDIR /app/frontend/nextjs |
| 6 | + |
| 7 | +# Copy package files and install dependencies |
| 8 | +COPY frontend/nextjs/package.json frontend/nextjs/package-lock.json* ./ |
| 9 | +RUN npm install --frozen-lockfile |
| 10 | + |
| 11 | +# Copy the rest of the frontend application and build it |
| 12 | +COPY frontend/nextjs/ ./ |
| 13 | +RUN npm run build |
| 14 | + |
| 15 | +######################################################################## |
| 16 | +# Stage 2: Browser and backend build tools installation |
| 17 | +######################################################################## |
| 18 | +FROM python:3.13.3-slim-bookworm AS install-browser |
| 19 | + |
| 20 | +# Configure apt for better reliability |
| 21 | +RUN echo 'Acquire::Retries "3";' > /etc/apt/apt.conf.d/80-retries && \ |
| 22 | + echo 'Acquire::http::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries && \ |
| 23 | + echo 'Acquire::https::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries && \ |
| 24 | + echo 'Acquire::ftp::Timeout "60";' >> /etc/apt/apt.conf.d/80-retries |
| 25 | + |
| 26 | +# Install Chromium, Chromedriver, Firefox, Geckodriver, and build tools in one layer |
| 27 | +RUN apt-get update \ |
| 28 | + && apt-get install -y gnupg wget ca-certificates --no-install-recommends \ |
| 29 | + && ARCH=$(dpkg --print-architecture) \ |
| 30 | + && wget -qO - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \ |
| 31 | + && echo "deb [arch=${ARCH}] http://dl.google.com/linux/chrome/deb/ stable main" \ |
| 32 | + > /etc/apt/sources.list.d/google-chrome.list \ |
| 33 | + && apt-get update \ |
| 34 | + && apt-get install -y chromium chromium-driver google-chrome-stable \ |
| 35 | + && chromium --version && chromedriver --version \ |
| 36 | + && apt-get install -y --no-install-recommends firefox-esr build-essential \ |
| 37 | + && GECKO_ARCH=$(case ${ARCH} in amd64) echo "linux64" ;; arm64) echo "linux-aarch64" ;; *) echo "linux64" ;; esac) \ |
| 38 | + && wget https://github.com/mozilla/geckodriver/releases/download/v0.36.0/geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \ |
| 39 | + && tar -xvzf geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \ |
| 40 | + && chmod +x geckodriver \ |
| 41 | + && mv geckodriver /usr/local/bin/ \ |
| 42 | + && rm geckodriver-v0.36.0-${GECKO_ARCH}.tar.gz \ |
| 43 | + && rm -rf /var/lib/apt/lists/* |
| 44 | + |
| 45 | +######################################################################## |
| 46 | +# Stage 3: Python dependencies installation |
| 47 | +######################################################################## |
| 48 | +FROM install-browser AS backend-builder |
| 49 | +WORKDIR /usr/src/app |
| 50 | + |
| 51 | +ENV PIP_ROOT_USER_ACTION=ignore |
| 52 | + |
| 53 | +COPY ./requirements.txt ./requirements.txt |
| 54 | +COPY ./multi_agents/requirements.txt ./multi_agents/requirements.txt |
| 55 | + |
| 56 | +# Install Python packages with retry logic and timeout configuration |
| 57 | +RUN pip config set global.timeout 60 && \ |
| 58 | + pip config set global.retries 3 && \ |
| 59 | + pip install --upgrade pip && \ |
| 60 | + pip install --no-cache-dir -r requirements.txt --upgrade --prefer-binary && \ |
| 61 | + pip install --no-cache-dir -r multi_agents/requirements.txt --upgrade --prefer-binary |
| 62 | + |
| 63 | +######################################################################## |
| 64 | +# Stage 4: Final image with backend, frontend, and supervisor |
| 65 | +######################################################################## |
| 66 | +FROM backend-builder AS final |
| 67 | + |
| 68 | +WORKDIR /usr/src/app |
| 69 | + |
| 70 | +# Install Node.js and supervisor with retry logic |
| 71 | +RUN apt-get update && \ |
| 72 | + apt-get install -y curl supervisor && \ |
| 73 | + curl -fsSL --retry 3 --retry-delay 10 https://deb.nodesource.com/setup_20.x | bash - && \ |
| 74 | + apt-get install -y nodejs && \ |
| 75 | + rm -rf /var/lib/apt/lists/* |
| 76 | + |
| 77 | +# Set backend server configuration |
| 78 | +ARG HOST=0.0.0.0 |
| 79 | +ENV HOST=${HOST} |
| 80 | + |
| 81 | +ARG PORT=8000 |
| 82 | +ENV PORT=${PORT} |
| 83 | +EXPOSE ${PORT} |
| 84 | + |
| 85 | +ARG NEXT_PORT=3000 |
| 86 | +ENV NEXT_PORT=${NEXT_PORT} |
| 87 | +EXPOSE ${NEXT_PORT} |
| 88 | + |
| 89 | +# Copy application files |
| 90 | +COPY ./ ./ |
| 91 | + |
| 92 | +# Copy built frontend from the frontend-builder stage |
| 93 | +COPY --from=frontend-builder /app/frontend/nextjs/.next ./frontend/nextjs/.next |
| 94 | +COPY --from=frontend-builder /app/frontend/nextjs/node_modules ./frontend/nextjs/node_modules |
| 95 | +COPY --from=frontend-builder /app/frontend/nextjs/public ./frontend/nextjs/public |
| 96 | +COPY --from=frontend-builder /app/frontend/nextjs/package.json ./frontend/nextjs/package.json |
| 97 | +# Ensure next.config.mjs and other necessary files are present |
| 98 | +COPY --from=frontend-builder /app/frontend/nextjs/next.config.mjs ./frontend/nextjs/next.config.mjs |
| 99 | + |
| 100 | +# Create a startup script that generates supervisor config with actual port values |
| 101 | +CMD /bin/bash -c 'cd /usr/src/app; \ |
| 102 | + (uvicorn main:app --host "$HOST" --port "$PORT") & \ |
| 103 | + (cd frontend/nextjs && npm run start -- -p "$NEXT_PORT") & \ |
| 104 | + wait' |
0 commit comments