Compare commits

...

3 Commits

Author SHA1 Message Date
SysAdmin Agent
fd626a9c66 Fix GrampsWeb: remove broken STATIC_PATH/STATIC_URL config (STI-90)
Some checks failed
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / deploy (push) Has been cancelled
Code Quality / quality (push) Has been cancelled
GRAMPSWEB_STATIC_PATH was set to /ahnenforschung/static (a URL path)
instead of a filesystem path, causing GrampsWeb to return 404 on all
routes. Removed STATIC_PATH and STATIC_URL (defaults work correctly)
and simplified BASE_URL to /.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 21:02:01 +00:00
SysAdmin Agent
5807bf85f1 GrampsWeb Phase 1: Production Compose, Reverse Proxy & Deployment (STI-91)
- Fix grampsweb port mapping: 8090:80 → 8090:5000 (gunicorn, not nginx)
- Add full subpath ENV vars: GRAMPSWEB_TREE, BASE_URL, STATIC_PATH, STATIC_URL
- Add Celery/Redis config: broker_url, result_backend, ratelimit storage
- Add GRAMPSWEB_NEW_DB_BACKEND=sqlite
- Add depends_on: redis and restart: unless-stopped
- Add GRAMPS_URL/USERNAME/PASSWORD/API_TOKEN to web service for Django integration
- Add nginx.conf with /ahnenforschung/ reverse proxy route (proxy to localhost:8090)
- Add GRAMPSWEB_STATIC_PATH and GRAMPSWEB_STATIC_URL to env-template.txt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 23:47:52 +00:00
SysAdmin Agent
f893172a2b GrampsWeb Phase 1: Sidebar-Link, Settings-Fix & Env-Template (STI-90)
- Fix GRAMPS_URL default port from 80 to 5000 to match dev compose
- Add "Ahnenforschung" sidebar link in navigation (links to /ahnenforschung/)
- Update env-template with all GRAMPSWEB_* variables for production setup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 23:40:55 +00:00
6 changed files with 150 additions and 7 deletions

View File

@@ -166,7 +166,7 @@ LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/login/"
# Gramps integration
GRAMPS_URL = os.environ.get("GRAMPS_URL", "http://grampsweb:80")
GRAMPS_URL = os.environ.get("GRAMPS_URL", "http://grampsweb:5000")
GRAMPS_API_TOKEN = os.environ.get("GRAMPS_API_TOKEN", "")
GRAMPS_STIFTER_IDS = os.environ.get("GRAMPS_STIFTER_IDS", "") # comma-separated
GRAMPS_USERNAME = os.environ.get("GRAMPS_USERNAME", "")

View File

@@ -689,6 +689,10 @@
<i class="fas fa-book-open"></i>
<span>Geschichte</span>
</a>
<a class="sidebar-link" href="/ahnenforschung/" target="_blank">
<i class="fas fa-tree"></i>
<span>Ahnenforschung</span>
</a>
{% if perms.stiftung.access_administration %}
<a class="sidebar-link" href="{% url 'stiftung:administration' %}">
<i class="fas fa-cogs"></i>

View File

@@ -197,9 +197,7 @@ services:
- GRAMPSWEB_ADMIN_EMAIL=${GRAMPSWEB_ADMIN_EMAIL}
- GRAMPSWEB_ADMIN_PASSWORD=${GRAMPSWEB_ADMIN_PASSWORD}
- GRAMPSWEB_TREE=${GRAMPSWEB_TREE:-Stiftung}
- GRAMPSWEB_BASE_URL=${GRAMPSWEB_BASE_URL:-/ahnenforschung}
- GRAMPSWEB_STATIC_PATH=${GRAMPSWEB_STATIC_PATH:-/ahnenforschung/static}
- GRAMPSWEB_STATIC_URL=${GRAMPSWEB_STATIC_URL:-/ahnenforschung/static/}
- GRAMPSWEB_BASE_URL=${GRAMPSWEB_BASE_URL:-/}
- 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

View File

@@ -49,6 +49,10 @@ services:
- REDIS_URL=${REDIS_URL}
- PAPERLESS_API_URL=${PAPERLESS_API_URL}
- PAPERLESS_API_TOKEN=${PAPERLESS_API_TOKEN}
- GRAMPS_URL=${GRAMPS_URL}
- GRAMPS_USERNAME=${GRAMPS_USERNAME}
- GRAMPS_PASSWORD=${GRAMPS_PASSWORD}
- GRAMPS_API_TOKEN=${GRAMPS_API_TOKEN}
ports:
- "8081:8000"
volumes:
@@ -111,14 +115,23 @@ services:
grampsweb:
image: ghcr.io/gramps-project/grampsweb:latest
restart: unless-stopped
ports:
- "8090:80"
- "8090:5000"
environment:
- GRAMPSWEB_SECRET_KEY=${GRAMPSWEB_SECRET_KEY}
- GRAMPSWEB_ADMIN_EMAIL=${GRAMPSWEB_ADMIN_EMAIL}
- GRAMPSWEB_ADMIN_PASSWORD=${GRAMPSWEB_ADMIN_PASSWORD}
- GRAMPSWEB_TREE=${GRAMPSWEB_TREE:-Stiftung}
- GRAMPSWEB_BASE_URL=${GRAMPSWEB_BASE_URL:-/}
- 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
- GRAMPSWEB_NEW_DB_BACKEND=sqlite
volumes:
- gramps_data:/app/data
depends_on:
- redis
paperless:
image: ghcr.io/paperless-ngx/paperless-ngx:latest

View File

@@ -0,0 +1,119 @@
# HTTP server block - redirect to HTTPS
server {
listen 80;
server_name vhtv-stiftung.de www.vhtv-stiftung.de;
# Redirect all HTTP traffic to HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS server block
server {
listen 443 ssl http2;
server_name vhtv-stiftung.de www.vhtv-stiftung.de;
# SSL Certificate Configuration
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 (HTTP Strict Transport Security)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Enhanced 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;
add_header Content-Security-Policy "default-src 'self' https: data: blob: 'unsafe-inline'" always;
# Static files
location /static/ {
alias /opt/stiftung/app/static/;
expires 1y;
add_header Cache-Control "public, immutable";
}
location /media/ {
alias /opt/stiftung/app/media/;
expires 1y;
add_header Cache-Control "public";
}
# Django application
location / {
proxy_pass http://127.0.0.1:8081;
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
# Paperless-ngx document management
location /paperless/ {
proxy_pass http://127.0.0.1:8080/;
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 /paperless;
# Large file uploads for documents
client_max_body_size 100M;
proxy_read_timeout 300s;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
}
# GrampsWeb Ahnenforschung
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;
# WebSocket support (GrampsWeb uses SSE/WS for real-time updates)
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;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Block access to sensitive files
location ~ /\. {
deny all;
}
location ~ ^/(\.env|docker-compose|Dockerfile) {
deny all;
}
}

View File

@@ -53,8 +53,17 @@ IMAP_FOLDER=INBOX
IMAP_USE_SSL=true
# Integration von Grampsweb zur Ahnenforschung und Prüfung
GRAMPS_URL=http://192.168.178.167:30179
# Django-App Verbindung zu GrampsWeb API (internes Docker-Netzwerk)
GRAMPS_URL=http://grampsweb:5000
GRAMPS_USERNAME=Stiftung
GRAMPS_PASSWORD=home4Gty94rj*de
GRAMPS_PASSWORD=your-gramps-password-here
GRAMPS_API_TOKEN=
# GrampsWeb Container Konfiguration
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
GRAMPSWEB_BASE_URL=/