Switch GrampsWeb from subpath to subdomain ahnenforschung.vhtv-stiftung.de (STI-91)
The subpath approach (/ahnenforschung/) required ~15 nginx sub_filter rules to rewrite JS/CSS/HTML paths, causing persistent issues with font loading, Service Worker, and API routes. GrampsWeb is not designed for subpath deployment. Switch to dedicated subdomain where GrampsWeb runs on root /: - nginx.conf: remove all sub_filter rules, add clean subdomain server block - base.html: update sidebar link to subdomain URL - compose.yml: update GRAMPSWEB_BASE_URL default - env-template.txt: update BASE_URL reference After deploy: run certbot for ahnenforschung.vhtv-stiftung.de SSL cert, update .env GRAMPSWEB_BASE_URL, restart containers. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -689,7 +689,7 @@
|
|||||||
<i class="fas fa-book-open"></i>
|
<i class="fas fa-book-open"></i>
|
||||||
<span>Geschichte</span>
|
<span>Geschichte</span>
|
||||||
</a>
|
</a>
|
||||||
<a class="sidebar-link" href="/ahnenforschung/" target="_blank">
|
<a class="sidebar-link" href="https://ahnenforschung.vhtv-stiftung.de" target="_blank">
|
||||||
<i class="fas fa-tree"></i>
|
<i class="fas fa-tree"></i>
|
||||||
<span>Ahnenforschung</span>
|
<span>Ahnenforschung</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ services:
|
|||||||
- GRAMPSWEB_ADMIN_EMAIL=${GRAMPSWEB_ADMIN_EMAIL:-admin@localhost}
|
- GRAMPSWEB_ADMIN_EMAIL=${GRAMPSWEB_ADMIN_EMAIL:-admin@localhost}
|
||||||
- GRAMPSWEB_ADMIN_PASSWORD=${GRAMPSWEB_ADMIN_PASSWORD:-gramps_dev_password}
|
- GRAMPSWEB_ADMIN_PASSWORD=${GRAMPSWEB_ADMIN_PASSWORD:-gramps_dev_password}
|
||||||
- GRAMPSWEB_TREE=${GRAMPSWEB_TREE:-Stiftung}
|
- GRAMPSWEB_TREE=${GRAMPSWEB_TREE:-Stiftung}
|
||||||
- GRAMPSWEB_BASE_URL=${GRAMPSWEB_BASE_URL:-https://vhtv-stiftung.de/ahnenforschung}
|
- GRAMPSWEB_BASE_URL=${GRAMPSWEB_BASE_URL:-https://ahnenforschung.vhtv-stiftung.de}
|
||||||
- GRAMPSWEB_CELERY_CONFIG__broker_url=redis://redis:6379/0
|
- GRAMPSWEB_CELERY_CONFIG__broker_url=redis://redis:6379/0
|
||||||
- GRAMPSWEB_CELERY_CONFIG__result_backend=redis://redis:6379/0
|
- GRAMPSWEB_CELERY_CONFIG__result_backend=redis://redis:6379/0
|
||||||
- GRAMPSWEB_RATELIMIT_STORAGE_URI=redis://redis:6379/1
|
- GRAMPSWEB_RATELIMIT_STORAGE_URI=redis://redis:6379/1
|
||||||
@@ -207,7 +207,7 @@ services:
|
|||||||
- sh
|
- sh
|
||||||
- -c
|
- -c
|
||||||
- |
|
- |
|
||||||
# All subpath rewriting is handled by nginx sub_filter — no container patching needed.
|
# GrampsWeb runs on its own subdomain — no subpath rewriting needed.
|
||||||
echo "[grampsweb] Ensuring admin user exists ..."
|
echo "[grampsweb] Ensuring admin user exists ..."
|
||||||
python3 << 'PYEOF' 2>&1 | grep -v Gtk
|
python3 << 'PYEOF' 2>&1 | grep -v Gtk
|
||||||
from gramps_webapi.app import create_app
|
from gramps_webapi.app import create_app
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# HTTP server block - redirect to HTTPS
|
# HTTP server block - redirect to HTTPS
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
server_name vhtv-stiftung.de www.vhtv-stiftung.de;
|
server_name vhtv-stiftung.de www.vhtv-stiftung.de ahnenforschung.vhtv-stiftung.de;
|
||||||
|
|
||||||
# Redirect all HTTP traffic to HTTPS
|
# Redirect all HTTP traffic to HTTPS
|
||||||
return 301 https://$server_name$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
# HTTPS server block
|
# HTTPS server block — Stiftung Django app
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
server_name vhtv-stiftung.de www.vhtv-stiftung.de;
|
server_name vhtv-stiftung.de www.vhtv-stiftung.de;
|
||||||
@@ -82,73 +82,6 @@ server {
|
|||||||
proxy_send_timeout 300s;
|
proxy_send_timeout 300s;
|
||||||
}
|
}
|
||||||
|
|
||||||
# GrampsWeb: fix double fonts/ path from CSS relative URL resolution
|
|
||||||
# fonts.css at /ahnenforschung/fonts/ references url('fonts/file.woff2')
|
|
||||||
# which resolves to /ahnenforschung/fonts/fonts/file.woff2
|
|
||||||
location /ahnenforschung/fonts/fonts/ {
|
|
||||||
proxy_pass http://127.0.0.1:8090/fonts/;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
# GrampsWeb Ahnenforschung
|
|
||||||
# All path rewriting happens here via sub_filter — no container-side patching needed.
|
|
||||||
# GrampsWeb SPA uses Vaadin Router with absolute paths; the injected History API
|
|
||||||
# interceptor ensures pushState/replaceState calls get the /ahnenforschung/ prefix,
|
|
||||||
# while <base href> lets the router strip it back for route matching.
|
|
||||||
location /ahnenforschung/ {
|
|
||||||
proxy_pass http://127.0.0.1:8090/;
|
|
||||||
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_set_header X-Script-Name /ahnenforschung;
|
|
||||||
|
|
||||||
# Disable upstream compression so sub_filter can operate on response bodies
|
|
||||||
proxy_set_header Accept-Encoding "";
|
|
||||||
|
|
||||||
# Apply sub_filter to HTML, JS, and CSS responses
|
|
||||||
sub_filter_types application/javascript text/javascript text/css;
|
|
||||||
sub_filter_once off;
|
|
||||||
|
|
||||||
# HTML: set <base href> so the SPA router knows its prefix
|
|
||||||
sub_filter '<base href="/">' '<base href="/ahnenforschung/">';
|
|
||||||
|
|
||||||
# HTML: inject History API interceptor — ensures pushState/replaceState
|
|
||||||
# always include the /ahnenforschung/ prefix for correct SPA routing on reload
|
|
||||||
sub_filter '</head>' '<script>!function(){var p="/ahnenforschung",o=history.pushState,r=history.replaceState;function w(u){return"string"==typeof u&&"/"===u[0]&&0!==u.indexOf(p)?p+u:u}history.pushState=function(s,t,u){return o.call(this,s,t,w(u))},history.replaceState=function(s,t,u){return r.call(this,s,t,w(u))}}();</script></head>';
|
|
||||||
|
|
||||||
# JS: rewrite hardcoded absolute API/resource paths
|
|
||||||
sub_filter '"/api/' '"/ahnenforschung/api/';
|
|
||||||
sub_filter '`/api/' '`/ahnenforschung/api/';
|
|
||||||
sub_filter '"/lang/' '"/ahnenforschung/lang/';
|
|
||||||
sub_filter '`/lang/' '`/ahnenforschung/lang/';
|
|
||||||
sub_filter '"/fonts/' '"/ahnenforschung/fonts/';
|
|
||||||
sub_filter '`/fonts/' '`/ahnenforschung/fonts/';
|
|
||||||
sub_filter '"/assets/' '"/ahnenforschung/assets/';
|
|
||||||
sub_filter '`/assets/' '`/ahnenforschung/assets/';
|
|
||||||
|
|
||||||
# JS: rewrite root redirects
|
|
||||||
sub_filter 'location.href="/"' 'location.href="/ahnenforschung/"';
|
|
||||||
sub_filter 'document.location.href="/"' 'document.location.href="/ahnenforschung/"';
|
|
||||||
|
|
||||||
# JS: service worker route handling
|
|
||||||
sub_filter 'createHandlerBoundToURL("/index.html")' 'createHandlerBoundToURL("/ahnenforschung/index.html")';
|
|
||||||
|
|
||||||
# CSS font paths: handled by separate location block for /ahnenforschung/fonts/fonts/
|
|
||||||
|
|
||||||
# WebSocket support
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
|
|
||||||
proxy_read_timeout 300s;
|
|
||||||
proxy_connect_timeout 60s;
|
|
||||||
proxy_send_timeout 300s;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Health check endpoint
|
# Health check endpoint
|
||||||
location /health/ {
|
location /health/ {
|
||||||
access_log off;
|
access_log off;
|
||||||
@@ -165,3 +98,50 @@ server {
|
|||||||
deny all;
|
deny all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# HTTPS server block — GrampsWeb Ahnenforschung (subdomain)
|
||||||
|
# No sub_filter or path rewriting needed — GrampsWeb runs on root /
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name ahnenforschung.vhtv-stiftung.de;
|
||||||
|
|
||||||
|
# SSL — will be updated by certbot after first run
|
||||||
|
ssl_certificate /etc/letsencrypt/live/vhtv-stiftung.de/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/vhtv-stiftung.de/privkey.pem;
|
||||||
|
|
||||||
|
# SSL Security Settings
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
ssl_session_cache shared:SSL:10m;
|
||||||
|
ssl_session_timeout 10m;
|
||||||
|
|
||||||
|
# HSTS
|
||||||
|
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||||
|
add_header X-XSS-Protection "1; mode=block" always;
|
||||||
|
add_header X-Content-Type-Options "nosniff" always;
|
||||||
|
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||||
|
|
||||||
|
# Large file uploads (GEDCOM imports)
|
||||||
|
client_max_body_size 100M;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8090;
|
||||||
|
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;
|
||||||
|
|
||||||
|
# WebSocket support
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_read_timeout 300s;
|
||||||
|
proxy_connect_timeout 60s;
|
||||||
|
proxy_send_timeout 300s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ GRAMPSWEB_SECRET_KEY=your-grampsweb-secret-key-here
|
|||||||
GRAMPSWEB_ADMIN_EMAIL=admin@vhtv-stiftung.de
|
GRAMPSWEB_ADMIN_EMAIL=admin@vhtv-stiftung.de
|
||||||
GRAMPSWEB_ADMIN_PASSWORD=your-grampsweb-admin-password-here
|
GRAMPSWEB_ADMIN_PASSWORD=your-grampsweb-admin-password-here
|
||||||
GRAMPSWEB_TREE=Stiftung
|
GRAMPSWEB_TREE=Stiftung
|
||||||
# Full external URL including subpath (used by GrampsWeb for email links, OIDC, etc.)
|
# Full external URL (used by GrampsWeb for email links, OIDC, etc.)
|
||||||
GRAMPSWEB_BASE_URL=https://vhtv-stiftung.de/ahnenforschung
|
GRAMPSWEB_BASE_URL=https://ahnenforschung.vhtv-stiftung.de
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user