diff --git a/app/templates/base.html b/app/templates/base.html
index 668e50f..b682e51 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -689,7 +689,7 @@
Geschichte
-
diff --git a/compose.yml b/compose.yml
index 9a59b86..4f398fc 100644
--- a/compose.yml
+++ b/compose.yml
@@ -198,7 +198,7 @@ services:
- GRAMPSWEB_ADMIN_EMAIL=${GRAMPSWEB_ADMIN_EMAIL:-admin@localhost}
- GRAMPSWEB_ADMIN_PASSWORD=${GRAMPSWEB_ADMIN_PASSWORD:-gramps_dev_password}
- 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__result_backend=redis://redis:6379/0
- GRAMPSWEB_RATELIMIT_STORAGE_URI=redis://redis:6379/1
@@ -207,7 +207,7 @@ services:
- sh
- -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 ..."
python3 << 'PYEOF' 2>&1 | grep -v Gtk
from gramps_webapi.app import create_app
diff --git a/deploy-production/nginx.conf b/deploy-production/nginx.conf
index ccaf93f..00827f3 100644
--- a/deploy-production/nginx.conf
+++ b/deploy-production/nginx.conf
@@ -1,13 +1,13 @@
# HTTP server block - redirect to HTTPS
server {
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
- return 301 https://$server_name$request_uri;
+ return 301 https://$host$request_uri;
}
-# HTTPS server block
+# HTTPS server block — Stiftung Django app
server {
listen 443 ssl http2;
server_name vhtv-stiftung.de www.vhtv-stiftung.de;
@@ -82,73 +82,6 @@ server {
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 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 so the SPA router knows its prefix
- sub_filter '' '';
-
- # HTML: inject History API interceptor — ensures pushState/replaceState
- # always include the /ahnenforschung/ prefix for correct SPA routing on reload
- sub_filter '' '';
-
- # 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
location /health/ {
access_log off;
@@ -165,3 +98,50 @@ server {
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;
+ }
+}
diff --git a/env-template.txt b/env-template.txt
index 75e4b88..0a62fe6 100644
--- a/env-template.txt
+++ b/env-template.txt
@@ -64,7 +64,7 @@ GRAMPSWEB_SECRET_KEY=your-grampsweb-secret-key-here
GRAMPSWEB_ADMIN_EMAIL=admin@vhtv-stiftung.de
GRAMPSWEB_ADMIN_PASSWORD=your-grampsweb-admin-password-here
GRAMPSWEB_TREE=Stiftung
-# Full external URL including subpath (used by GrampsWeb for email links, OIDC, etc.)
-GRAMPSWEB_BASE_URL=https://vhtv-stiftung.de/ahnenforschung
+# Full external URL (used by GrampsWeb for email links, OIDC, etc.)
+GRAMPSWEB_BASE_URL=https://ahnenforschung.vhtv-stiftung.de
\ No newline at end of file