BankBot-AI / Dockerfile
mohsin-devs's picture
Deploy to HF
a282d4b
# ============================================================
# 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"]