Spaces:
Running
Running
| # ============================================================ | |
| # BankBot AI β Hugging Face Spaces Dockerfile | |
| # | |
| # Single-container deployment: | |
| # Port 7860 (HF requirement) β Nginx | |
| # Nginx β Next.js (port 3000) for frontend | |
| # Nginx β FastAPI (port 8000) for /api/* and /ws | |
| # | |
| # Build args: | |
| # NEXT_PUBLIC_API_URL (default: relative /api proxy) | |
| # ============================================================ | |
| # βββ Stage 1: Build Next.js frontend βββββββββββββββββββββββββββββββββββββββββ | |
| FROM node:20-slim AS frontend-builder | |
| WORKDIR /frontend | |
| COPY frontend/package.json frontend/package-lock.json* ./ | |
| RUN npm install --legacy-peer-deps --quiet | |
| # Copy only the necessary frontend files (deterministic for HF build context) | |
| COPY frontend/package.json frontend/package-lock.json* ./ | |
| COPY frontend/next.config.mjs ./ | |
| COPY frontend/tsconfig.json ./ | |
| COPY frontend/postcss.config.mjs ./ | |
| COPY frontend/tailwind.config.ts ./ | |
| COPY frontend/components.json ./ | |
| COPY frontend/src ./src | |
| # Create public dir if it doesn't exist (Next.js requires it for standalone output) | |
| RUN mkdir -p public | |
| # Verify app layout exists (better failure message in CI/HF logs) | |
| RUN if [ ! -d "src/app" ]; then \ | |
| echo "ERROR: no 'src/app' directory found in frontend - Next.js requires an app directory"; \ | |
| ls -la /frontend || true; \ | |
| ls -la /frontend/src || true; \ | |
| exit 1; \ | |
| fi | |
| # In HF, frontend calls go through the same origin via Nginx proxy | |
| # So NEXT_PUBLIC_API_URL is empty β rewrites handle /api/* internally | |
| ARG NEXT_PUBLIC_API_URL="" | |
| ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL | |
| ENV NEXT_TELEMETRY_DISABLED=1 | |
| # Increase Node heap for Next.js builds to avoid OOM in constrained builders | |
| ENV NODE_OPTIONS="--max-old-space-size=4096" | |
| RUN npm run build | |
| # βββ Stage 2: Python dependencies ββββββββββββββββββββββββββββββββββββββββββββ | |
| FROM python:3.11-slim AS python-builder | |
| WORKDIR /build | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| libpq-dev \ | |
| && rm -rf /var/lib/apt/lists/* | |
| COPY backend/requirements.txt . | |
| RUN pip install --no-cache-dir --prefix=/install -r requirements.txt | |
| # βββ Stage 3: Final runtime image ββββββββββββββββββββββββββββββββββββββββββββ | |
| FROM python:3.11-slim AS runtime | |
| # Install Node.js, Nginx, supervisord, curl | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| nginx \ | |
| supervisor \ | |
| curl \ | |
| libpq5 \ | |
| ca-certificates \ | |
| tesseract-ocr \ | |
| tesseract-ocr-eng \ | |
| xz-utils \ | |
| && curl -fsSL https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz | tar -xJ --strip-components=1 -C /usr/local \ | |
| && rm -rf /var/lib/apt/lists/* | |
| ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/5/tessdata | |
| # ββ Python packages βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY --from=python-builder /install /usr/local | |
| # ββ Backend βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| WORKDIR /app/backend | |
| COPY backend/app/ ./app/ | |
| COPY backend/requirements.txt . | |
| # ββ Frontend (standalone build) βββββββββββββββββββββββββββββββββββββββββββββββ | |
| WORKDIR /app/frontend | |
| COPY --from=frontend-builder /frontend/.next/standalone ./ | |
| COPY --from=frontend-builder /frontend/.next/static ./.next/static | |
| COPY --from=frontend-builder /frontend/public ./public | |
| # ββ Nginx config ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY hf/nginx.conf /etc/nginx/nginx.conf | |
| # ββ Supervisord config ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY hf/supervisord.conf /etc/supervisor/conf.d/bankbot.conf | |
| # ββ Startup script ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| COPY hf/start.sh /app/start.sh | |
| RUN chmod +x /app/start.sh | |
| # ββ Writable dirs for non-root (HF runs as user 1000) ββββββββββββββββββββββββ | |
| RUN mkdir -p /app/data /var/log/supervisor /var/log/nginx /var/lib/nginx/body \ | |
| && chmod -R 777 /app/data /var/log/supervisor /var/log/nginx \ | |
| && chmod -R 777 /var/lib/nginx \ | |
| && touch /run/nginx.pid && chmod 777 /run/nginx.pid \ | |
| && chown -R 1000:1000 /app /var/log/supervisor /var/log/nginx /var/lib/nginx | |
| # HF Spaces requires port 7860 | |
| EXPOSE 7860 | |
| # Health check | |
| HEALTHCHECK --interval=30s --timeout=15s --start-period=60s --retries=5 \ | |
| CMD curl -f http://localhost:7860/health || exit 1 | |
| # Run as user 1000 (HF default) | |
| USER 1000 | |
| WORKDIR /app | |
| CMD ["/app/start.sh"] | |