File size: 4,017 Bytes
ce16368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eec3202
 
 
ce16368
 
 
 
 
 
 
 
 
 
 
e9ab438
ce16368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
729e92f
ce16368
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Dockerfile for TisTru (Hugging Face Spaces / self-hosted Docker)
# Bundles FastAPI backend + Next.js frontend + local Ollama LLM server.
#
# Build:
#   docker build -t tistru .
#
# Run locally:
#   docker run -p 7860:7860 -e OLLAMA_MODEL=llama3.1 tistru
#
# For GPU support on HF Spaces, use a GPU-enabled Space template.
# HF Spaces requires the app to listen on port 7860 and run as UID 1000.

# ─────────────────────────────────────────────
# Stage 1: Build the Next.js frontend
# ─────────────────────────────────────────────
FROM node:20-slim AS frontend-builder

WORKDIR /app

# Install dependencies first (better layer caching)
COPY frontend/package*.json ./
RUN npm ci

# Copy source and build
COPY frontend ./

# NEXT_PUBLIC_API_URL is empty so the frontend calls the same origin (port 7860)
ENV NEXT_PUBLIC_API_URL=

# Produces .next/standalone + .next/static (requires output:'standalone' in next.config.js)
RUN npm run build

RUN test -d .next/standalone || \
    (echo "ERROR: .next/standalone not found. Add output:'standalone' to next.config.js" && exit 1)

# ─────────────────────────────────────────────
# Stage 2: Python runtime + Ollama + FastAPI
# ─────────────────────────────────────────────
FROM python:3.11-slim

# ── System deps + Ollama ──────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
        curl \
        ca-certificates \
        nodejs \
        npm \
        zstd \
    && curl -fsSL https://ollama.com/install.sh | sh \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# ── Create non-root user required by HF Spaces (UID must be 1000) ────────────
RUN useradd -m -u 1000 -s /bin/bash user \
    && mkdir -p /home/user/.ollama \
    && chown -R 1000:1000 /home/user

# ── App working directory ─────────────────────
WORKDIR /app

# ── Python dependencies ───────────────────────
COPY backend/requirements.txt ./backend/requirements.txt
RUN pip install --no-cache-dir -r backend/requirements.txt

# ── Backend source ────────────────────────────
COPY backend/app ./backend/app

# ── Frontend build artifacts (Next.js standalone output) ─────────────────────
# Requires next.config.js to have: output: 'standalone'
COPY --from=frontend-builder /app/.next/standalone   ./frontend/
COPY --from=frontend-builder /app/.next/static       ./frontend/.next/static
COPY --from=frontend-builder /app/public             ./frontend/public

# ── Startup script ────────────────────────────
COPY start.sh /start.sh
RUN chmod +x /start.sh

# ── Fix ownership so UID 1000 can write everywhere ────────────────────────────
RUN chown -R 1000:1000 /app /start.sh

# ── Switch to non-root user ───────────────────
USER 1000

# ── Environment defaults ──────────────────────
ENV HOME=/home/user
ENV PATH=/home/user/.local/bin:/usr/local/bin:$PATH

# Ollama config
ENV OLLAMA_HOST=0.0.0.0:11434
ENV OLLAMA_MODELS=/home/user/.ollama/models
ENV OLLAMA_BASE_URL=http://localhost:11434/v1
ENV OLLAMA_MODEL=llama3.2:3b

# App config
ENV USE_LOCAL_LLM=true
# HF Spaces only proxies port 7860
ENV PORT=7860

# ── Expose HF Spaces required port ───────────
EXPOSE 7860

CMD ["/start.sh"]