finai / Dockerfile
Sandy-sys's picture
Deploy FinAI
db7ef8e verified
Raw History Blame Contribute Delete
3.77 kB
# ────────────────────────────────────────────────────────────────────────
# FinAI β€” single-container build for HuggingFace Spaces (free tier)
# Runs Next.js (frontend) + FastAPI (backend) behind one exposed port.
# ────────────────────────────────────────────────────────────────────────
# Build stage 1: compile Next.js into standalone bundle
FROM node:20-bookworm-slim AS web-builder
WORKDIR /app/web
# pnpm is the project's package manager
RUN corepack enable
COPY apps/web/package.json apps/web/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile --prod=false
COPY apps/web/ ./
# Next.js 15 requires NEXT_TELEMETRY_DISABLED at build time too
ENV NEXT_TELEMETRY_DISABLED=1
ENV NEXT_PUBLIC_API_URL=http://127.0.0.1:8000
RUN pnpm build
# Build stage 2: runtime image with Python + Node
FROM python:3.11-slim-bookworm AS runtime
# Install Node.js 20 (for the Next.js standalone server)
RUN apt-get update \
&& apt-get install -y --no-install-recommends curl ca-certificates gnupg \
&& curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y --no-install-recommends nodejs \
&& rm -rf /var/lib/apt/lists/*
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
NEXT_TELEMETRY_DISABLED=1 \
# HF Spaces injects PORT β€” default to 7860 for local parity
PORT=7860
# Create a non-root user so HF Spaces is happy writing to /home/user
RUN useradd -m -u 1000 user
USER user
WORKDIR /home/user/app
# ── Python deps ────────────────────────────────────────────────────────
COPY --chown=user:user apps/api/requirements.txt ./apps/api/requirements.txt
ENV PATH="/home/user/.local/bin:${PATH}"
RUN pip install --user --upgrade pip \
&& pip install --user -r apps/api/requirements.txt
# ── Backend source ─────────────────────────────────────────────────────
COPY --chown=user:user apps/api/ ./apps/api/
# ── Frontend standalone bundle ─────────────────────────────────────────
# Next.js standalone layout (relative to apps/web):
# .next/standalone/server.js ← entrypoint
# .next/standalone/.next/... ← server assets
# .next/static ← static assets (copied next to .next)
# public ← public assets (copied to standalone root)
COPY --from=web-builder --chown=user:user /app/web/.next/standalone ./apps/web
COPY --from=web-builder --chown=user:user /app/web/.next/static ./apps/web/.next/static
COPY --from=web-builder --chown=user:user /app/web/public ./apps/web/public
# ── Data (DuckDB + schema) ─────────────────────────────────────────────
# Writable so KB uploads/renames work at runtime on HF Spaces.
COPY --chown=user:user data/ ./data/
# ── Launch script ──────────────────────────────────────────────────────
COPY --chown=user:user scripts/start.sh ./start.sh
RUN chmod +x ./start.sh
EXPOSE 7860
CMD ["./start.sh"]