Move Open-WebUI to chat.${DOMAIN} subdomain
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 34s

Open-WebUI's SvelteKit frontend hardcodes asset/API paths at build time,
so subpath hosting under /openwebui/ produced 404s on /_app/... assets.
Move it to its own subdomain so it can run at root.

- certbot: request cert with chat.${DOMAIN} as a third SAN via --expand
- nginx (prod): drop /openwebui blocks; add chat.${DOMAIN} HTTP redirect
  + HTTPS server with the existing admin auth gate
- nginx (dev): drop /openwebui blocks (no chat.localhost in dev)
- compose: WEBUI_URL points to https://chat.${DOMAIN}

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 17:29:29 +01:00
parent 26a35719eb
commit aa6de883be
4 changed files with 51 additions and 57 deletions

View File

@@ -1,7 +1,8 @@
#!/bin/sh
if [ ! -d /etc/letsencrypt/live/${DOMAIN} ]; then
certbot certonly --webroot -w /var/www/certbot --email ${EMAIL} -d ${DOMAIN} -d www.${DOMAIN} --agree-tos --non-interactive;
fi;
certbot certonly --webroot -w /var/www/certbot \
--email ${EMAIL} \
-d ${DOMAIN} -d www.${DOMAIN} -d chat.${DOMAIN} \
--agree-tos --non-interactive --expand;
trap exit TERM;

View File

@@ -184,7 +184,7 @@ services:
environment:
- OLLAMA_BASE_URL=${OLLAMA_BASE_URL}
- WEBUI_AUTH=False
- WEBUI_URL=https://www.${DOMAIN}/openwebui
- WEBUI_URL=https://chat.${DOMAIN}
volumes:
- openwebui_data:/app/backend/data

View File

@@ -79,7 +79,6 @@ http {
set $upstream_hasura http://$HASURA_HOST:$HASURA_PORT;
set $upstream_quartz http://$QUARTZ_HOST:$QUARTZ_PORT;
set $upstream_searxng http://$SEARXNG_HOST:$SEARXNG_PORT;
set $upstream_openwebui http://$OPENWEBUI_HOST:$OPENWEBUI_PORT;
root /etc/nginx/html;
index index.html;
@@ -289,14 +288,56 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
location /openwebui {
return 301 /openwebui/;
}
server {
listen 80;
server_name chat.$DOMAIN;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location /openwebui/ {
location / {
return 301 https://chat.$DOMAIN$request_uri;
}
}
server {
listen 443 ssl;
http2 on;
server_name chat.$DOMAIN;
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
set $upstream_openwebui http://$OPENWEBUI_HOST:$OPENWEBUI_PORT;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
client_max_body_size 50M;
location = /internal/auth/admin-validate {
internal;
rewrite ^ /auth/validate-admin break;
proxy_pass http://$BACKEND_HOST:$BACKEND_PORT;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Cookie $http_cookie;
}
location @auth_denied {
return 302 https://www.$DOMAIN/admin/login?redirect=https://chat.$DOMAIN$request_uri;
}
location / {
auth_request /internal/auth/admin-validate;
error_page 401 403 = @auth_denied;
rewrite ^/openwebui/(.*)$ /$1 break;
proxy_pass $upstream_openwebui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
@@ -309,8 +350,6 @@ http {
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
}

View File

@@ -52,7 +52,6 @@ http {
set $upstream_hasura http://$HASURA_HOST:$HASURA_PORT;
set $upstream_quartz http://$QUARTZ_HOST:$QUARTZ_PORT;
set $upstream_searxng http://$SEARXNG_HOST:$SEARXNG_PORT;
set $upstream_openwebui http://$OPENWEBUI_HOST:$OPENWEBUI_PORT;
location /uploads/ {
alias /uploads/;
@@ -206,28 +205,6 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
location /openwebui {
return 301 /openwebui/;
}
location /openwebui/ {
auth_request /internal/auth/admin-validate;
error_page 401 403 = @auth_denied;
rewrite ^/openwebui/(.*)$ /$1 break;
proxy_pass $upstream_openwebui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_buffering off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
server {
@@ -243,7 +220,6 @@ http {
set $upstream_hasura http://$HASURA_HOST:$HASURA_PORT;
set $upstream_quartz http://$QUARTZ_HOST:$QUARTZ_PORT;
set $upstream_searxng http://$SEARXNG_HOST:$SEARXNG_PORT;
set $upstream_openwebui http://$OPENWEBUI_HOST:$OPENWEBUI_PORT;
location /uploads/ {
alias /uploads/;
@@ -397,28 +373,6 @@ http {
proxy_set_header X-Forwarded-Proto $scheme;
}
location /openwebui {
return 301 /openwebui/;
}
location /openwebui/ {
auth_request /internal/auth/admin-validate;
error_page 401 403 = @auth_denied;
rewrite ^/openwebui/(.*)$ /$1 break;
proxy_pass $upstream_openwebui;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
proxy_buffering off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
}