summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-18 22:40:21 -0500
committerChristian Cleberg <[email protected]>2026-04-18 22:40:21 -0500
commita859138a50a7b7a53fd0b918c94cd7174689ff95 (patch)
tree2132fa7394403331a47809c46ad7e30a99d31c2a
parentaf6ac085443bf28a2229e8fc502a1cb290f03505 (diff)
downloadbrand-bench-a859138a50a7b7a53fd0b918c94cd7174689ff95.tar.gz
brand-bench-a859138a50a7b7a53fd0b918c94cd7174689ff95.tar.bz2
brand-bench-a859138a50a7b7a53fd0b918c94cd7174689ff95.zip
add docker deployment option
-rw-r--r--Dockerfile18
-rw-r--r--README.md26
-rw-r--r--compose.yml35
-rw-r--r--docker/nginx.conf27
4 files changed, 106 insertions, 0 deletions
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://<your-server> (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;
+ }
+}