From 1b05ef7ac8b3fbdb061925d7e3aa8ddb9bece87b Mon Sep 17 00:00:00 2001 From: SysVis AI Date: Sun, 28 Dec 2025 19:56:47 +0700 Subject: [PATCH] feat: add nginx reverse proxy for ollama --- Dockerfile | 12 ++---------- nginx.conf | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 nginx.conf diff --git a/Dockerfile b/Dockerfile index a001115..32052e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,16 +15,8 @@ FROM nginx:alpine # Copy built assets from builder stage COPY --from=builder /app/dist /usr/share/nginx/html -# Copy custom nginx config if needed (optional, using default for now but robust for SPA) -# We'll inline a simple config to handle SPA routing (try_files $uri /index.html) -RUN echo 'server { \ - listen 80; \ - location / { \ - root /usr/share/nginx/html; \ - index index.html index.htm; \ - try_files $uri $uri/ /index.html; \ - } \ -}' > /etc/nginx/conf.d/default.conf +# Copy custom nginx config +COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..0c16e6a --- /dev/null +++ b/nginx.conf @@ -0,0 +1,36 @@ +server { + listen 80; + + # Enable gzip compression + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + # Root directory for the app + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + # Proxy Ollama API requests + # This solves Mixed Content (HTTPS -> HTTP) and CORS issues + location /api/ { + proxy_pass http://ollama:11434/api/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # CORS headers (redundant if OLLAMA_ORIGINS is set, but good for safety) + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; + + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain; charset=utf-8'; + add_header 'Content-Length' 0; + return 204; + } + } +}