From a859138a50a7b7a53fd0b918c94cd7174689ff95 Mon Sep 17 00:00:00 2001 From: Christian Cleberg Date: Sat, 18 Apr 2026 22:40:21 -0500 Subject: add docker deployment option --- Dockerfile | 18 ++++++++++++++++++ README.md | 26 ++++++++++++++++++++++++++ compose.yml | 35 +++++++++++++++++++++++++++++++++++ docker/nginx.conf | 27 +++++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 Dockerfile create mode 100644 compose.yml create mode 100644 docker/nginx.conf diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5a27dca --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +# ── Stage 1: build ─────────────────────────────────────────────────────────── +FROM node:22-alpine AS build + +WORKDIR /app + +COPY package*.json ./ +RUN npm ci + +COPY . . +RUN npm run build + +# ── Stage 2: serve ─────────────────────────────────────────────────────────── +FROM nginx:alpine + +COPY --from=build /app/dist /usr/share/nginx/html +COPY docker/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 diff --git a/README.md b/README.md index 82ba080..6312725 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,32 @@ Larger models produce better-structured output. If generation fails with a JSON error, try a bigger model. Generation typically takes 15–60 seconds depending on hardware. +## Self-hosting with Docker + +A `Dockerfile` and `compose.yml` are included for deploying the app alongside +Ollama on a server. + +```bash +docker compose up -d --build +``` + +The app is served on port 8000. Ollama's API is proxied through nginx at `/api/` +so the browser never makes a cross-origin request — no CORS configuration +needed. + +**After first boot, pull at least one model:** + +```bash +docker compose exec ollama ollama pull llama3.2 +``` + +Then open the app, go to Settings (⚙), enable AI, and set the Ollama base URL +to `http://your-server:8000` (no path suffix). + +**GPU support:** If your server has an NVIDIA GPU, uncomment the `deploy` block +in `compose.yml` (requires the +[NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)). + ## Project structure ``` diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..361301c --- /dev/null +++ b/compose.yml @@ -0,0 +1,35 @@ +services: + + app: + build: . + ports: + - "8000:80" + depends_on: + - ollama + restart: unless-stopped + + ollama: + image: ollama/ollama + volumes: + - ollama_data:/root/.ollama + restart: unless-stopped + # Expose port 11434 if you want to reach Ollama directly from your host + # (e.g. to run `ollama pull` without exec-ing into the container). + ports: + - "11434:11434" + + # ── GPU support ────────────────────────────────────────────────────────── + # Uncomment the block below if your server has an NVIDIA GPU. + # Requires the NVIDIA Container Toolkit: + # https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html + # + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: all + # capabilities: [gpu] + +volumes: + ollama_data: diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..49cd069 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,27 @@ +server { + listen 80; + root /usr/share/nginx/html; + index index.html; + + # SPA fallback — let React Router handle unknown paths + location / { + try_files $uri $uri/ /index.html; + } + + # Proxy Ollama's API through the same origin so the browser never has to + # make a cross-origin request and CORS is a non-issue. + # In the app's Settings panel, set the Ollama base URL to just: + # http:// (no port, no path suffix) + location /api/ { + proxy_pass http://ollama:11434/api/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # Ollama responses (especially streamed ones) can be large and slow; + # disable buffering so cancellation works promptly. + proxy_buffering off; + proxy_read_timeout 120s; + } +} -- cgit v1.2.3