# ============================================================ # 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-alpine AS frontend-builder WORKDIR /frontend COPY frontend/package.json frontend/package-lock.json* ./ RUN npm ci --legacy-peer-deps --quiet COPY frontend/ . # 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 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 \ && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ && apt-get install -y --no-install-recommends nodejs \ && rm -rf /var/lib/apt/lists/* # ── 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"]