Commit f5c756707f
f5c756707ff30fbcb1bddb2dedd453fe6e276cd1
parent: 2db29e40bb
Unsigned
cmc <hello@cleberg.net> · 2026-04-19 03:40 UTC
add docker deployment option
Layout: unified · split
Dockerfile
added
+18
| @@ -0,0 +1,18 @@ |
| 1 | # ── Stage 1: build ─────────────────────────────────────────────────────────── |
| 2 | FROM node:22-alpine AS build |
| 3 | |
| 4 | WORKDIR /app |
| 5 | |
| 6 | COPY package*.json ./ |
| 7 | RUN npm ci |
| 8 | |
| 9 | COPY . . |
| 10 | RUN npm run build |
| 11 | |
| 12 | # ── Stage 2: serve ─────────────────────────────────────────────────────────── |
| 13 | FROM nginx:alpine |
| 14 | |
| 15 | COPY --from=build /app/dist /usr/share/nginx/html |
| 16 | COPY docker/nginx.conf /etc/nginx/conf.d/default.conf |
| 17 | |
| 18 | EXPOSE 80 |
README.md
+26
| @@ -74,6 +74,32 @@ Larger models produce better-structured output. If generation fails with a JSON |
| 74 | 74 | error, try a bigger model. Generation typically takes 15–60 seconds depending on |
| 75 | 75 | hardware. |
| 76 | 76 | |
| 77 | ## Self-hosting with Docker |
| 78 | |
| 79 | A `Dockerfile` and `compose.yml` are included for deploying the app alongside |
| 80 | Ollama on a server. |
| 81 | |
| 82 | ```bash |
| 83 | docker compose up -d --build |
| 84 | ``` |
| 85 | |
| 86 | The app is served on port 8000. Ollama's API is proxied through nginx at `/api/` |
| 87 | so the browser never makes a cross-origin request — no CORS configuration |
| 88 | needed. |
| 89 | |
| 90 | **After first boot, pull at least one model:** |
| 91 | |
| 92 | ```bash |
| 93 | docker compose exec ollama ollama pull llama3.2 |
| 94 | ``` |
| 95 | |
| 96 | Then open the app, go to Settings (⚙), enable AI, and set the Ollama base URL |
| 97 | to `http://your-server:8000` (no path suffix). |
| 98 | |
| 99 | **GPU support:** If your server has an NVIDIA GPU, uncomment the `deploy` block |
| 100 | in `compose.yml` (requires the |
| 101 | [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html)). |
| 102 | |
| 77 | 103 | ## Project structure |
| 78 | 104 | |
| 79 | 105 | ``` |
compose.yml
added
+35
| @@ -0,0 +1,35 @@ |
| 1 | services: |
| 2 | |
| 3 | app: |
| 4 | build: . |
| 5 | ports: |
| 6 | - "8000:80" |
| 7 | depends_on: |
| 8 | - ollama |
| 9 | restart: unless-stopped |
| 10 | |
| 11 | ollama: |
| 12 | image: ollama/ollama |
| 13 | volumes: |
| 14 | - ollama_data:/root/.ollama |
| 15 | restart: unless-stopped |
| 16 | # Expose port 11434 if you want to reach Ollama directly from your host |
| 17 | # (e.g. to run `ollama pull` without exec-ing into the container). |
| 18 | ports: |
| 19 | - "11434:11434" |
| 20 | |
| 21 | # ── GPU support ────────────────────────────────────────────────────────── |
| 22 | # Uncomment the block below if your server has an NVIDIA GPU. |
| 23 | # Requires the NVIDIA Container Toolkit: |
| 24 | # https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html |
| 25 | # |
| 26 | # deploy: |
| 27 | # resources: |
| 28 | # reservations: |
| 29 | # devices: |
| 30 | # - driver: nvidia |
| 31 | # count: all |
| 32 | # capabilities: [gpu] |
| 33 | |
| 34 | volumes: |
| 35 | ollama_data: |
docker/nginx.conf
added
+27
| @@ -0,0 +1,27 @@ |
| 1 | server { |
| 2 | listen 80; |
| 3 | root /usr/share/nginx/html; |
| 4 | index index.html; |
| 5 | |
| 6 | # SPA fallback — let React Router handle unknown paths |
| 7 | location / { |
| 8 | try_files $uri $uri/ /index.html; |
| 9 | } |
| 10 | |
| 11 | # Proxy Ollama's API through the same origin so the browser never has to |
| 12 | # make a cross-origin request and CORS is a non-issue. |
| 13 | # In the app's Settings panel, set the Ollama base URL to just: |
| 14 | # http://<your-server> (no port, no path suffix) |
| 15 | location /api/ { |
| 16 | proxy_pass http://ollama:11434/api/; |
| 17 | proxy_http_version 1.1; |
| 18 | proxy_set_header Host $host; |
| 19 | proxy_set_header X-Real-IP $remote_addr; |
| 20 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
| 21 | |
| 22 | # Ollama responses (especially streamed ones) can be large and slow; |
| 23 | # disable buffering so cancellation works promptly. |
| 24 | proxy_buffering off; |
| 25 | proxy_read_timeout 120s; |
| 26 | } |
| 27 | } |