From 8d3e8ebf1850b8a206033e1a997ed2c06efeb85e Mon Sep 17 00:00:00 2001 From: Nils Pukropp Date: Thu, 19 Feb 2026 18:27:19 +0100 Subject: [PATCH] simplified .env configuration with DOMAIN-based defaults and improved docker-compose orchestration --- .env.example | 24 ++++++++++++------------ backend/holy_backend/settings.py | 21 ++++++++++++++------- docker-compose.yml | 9 ++++++--- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/.env.example b/.env.example index e6a8dd7..529be19 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,7 @@ -# --- Application Security --- +# --- Essential Site Configuration --- +# Your primary domain (e.g., holy.narl.io). Used to derive ALLOWED_HOSTS, CORS, and CSRF settings. +DOMAIN="localhost" + # Set to a long, random string in production (e.g. 50+ chars) SECRET_KEY="django-insecure-replace-this-in-production" @@ -8,15 +11,12 @@ DEBUG=true # Custom URL for the Django Admin interface (e.g., my-secret-admin/) ADMIN_URL="admin" -# --- Hosting & Networking --- -# The primary domain where your app is hosted (e.g., holy.narl.io) -ALLOWED_HOSTS=localhost,127.0.0.1,backend,holy.narl.io - -# CSRF protection: Comma-separated list of trusted origins (MUST start with https:// in production) -CSRF_TRUSTED_ORIGINS=https://holy.narl.io - -# CORS protection: Comma-separated list of allowed origins -CORS_ALLOWED_ORIGINS=https://holy.narl.io +# --- Advanced Networking (Optional, derived from DOMAIN if unset) --- +# ALLOWED_HOSTS=holy.narl.io,another-domain.com +# CSRF_TRUSTED_ORIGINS=https://holy.narl.io +# CORS_ALLOWED_ORIGINS=https://holy.narl.io +# FRONTEND_URL=https://holy.narl.io +# VITE_API_URL=https://holy.narl.io/api/ # --- SMTP Configuration (Required for Email Verification) --- # For development, if EMAIL_HOST is empty, emails are printed to the console. @@ -32,8 +32,8 @@ EMAIL_HOST_PASSWORD="your-password" EMAIL_SKIP_CERT_VERIFICATION=false # --- Frontend Configuration --- -# The base URL of the backend API (MUST end with /api/) -VITE_API_URL=https://holy.narl.io/api/ +# Optional: defaults to ${DOMAIN}/api/ if not set +# VITE_API_URL=https://holy.narl.io/api/ VITE_ALLOWED_HOSTS=localhost,holy.narl.io # --- Impressum / Contact Details (Required for German Law ยง 5 TMG) --- diff --git a/backend/holy_backend/settings.py b/backend/holy_backend/settings.py index 7ec54cf..3ad0a8d 100644 --- a/backend/holy_backend/settings.py +++ b/backend/holy_backend/settings.py @@ -26,8 +26,17 @@ SECRET_KEY = os.environ.get('SECRET_KEY', 'django-insecure-zos99ue2a89!4jrv4g@_b # SECURITY WARNING: don't run with debug turned on in production! DEBUG = os.environ.get('DEBUG', 'false').lower() == 'true' -ALLOWED_HOSTS_STRING = os.environ.get('ALLOWED_HOSTS', 'localhost,127.0.0.1,backend,holy.narl.io') -ALLOWED_HOSTS = [host.strip() for host in ALLOWED_HOSTS_STRING.split(',')] +# Simplification: Use a single DOMAIN variable to derive multiple settings +DOMAIN = os.environ.get('DOMAIN', 'holy.narl.io') + +# Helper to build lists from env or defaults +def get_env_list(var_name, default_list): + val = os.environ.get(var_name) + if val: + return [item.strip() for item in val.split(',')] + return default_list + +ALLOWED_HOSTS = get_env_list('ALLOWED_HOSTS', ['localhost', '127.0.0.1', 'backend', 'worker', DOMAIN]) # Application definition @@ -166,8 +175,7 @@ if not DEBUG: SECURE_HSTS_PRELOAD = True # Read CSRF trusted origins from environment variable -CSRF_TRUSTED_ORIGINS_STRING = os.environ.get('CSRF_TRUSTED_ORIGINS', 'https://holy.narl.io,http://localhost:5173') -CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in CSRF_TRUSTED_ORIGINS_STRING.split(',')] +CSRF_TRUSTED_ORIGINS = get_env_list('CSRF_TRUSTED_ORIGINS', [f'https://{DOMAIN}', 'http://localhost:5173']) # Custom User Model AUTH_USER_MODEL = 'api.User' @@ -188,10 +196,9 @@ REST_FRAMEWORK = { } # CORS -CORS_ALLOWED_ORIGINS_STRING = os.environ.get('CORS_ALLOWED_ORIGINS', 'https://holy.narl.io,http://localhost:5173,http://127.0.0.1:5173') -CORS_ALLOWED_ORIGINS = [origin.strip() for origin in CORS_ALLOWED_ORIGINS_STRING.split(',')] +CORS_ALLOWED_ORIGINS = get_env_list('CORS_ALLOWED_ORIGINS', [f'https://{DOMAIN}', 'http://localhost:5173', 'http://127.0.0.1:5173']) -FRONTEND_URL = os.environ.get('FRONTEND_URL', 'https://holy.narl.io').rstrip('/') +FRONTEND_URL = os.environ.get('FRONTEND_URL', f'https://{DOMAIN}').rstrip('/') import os # ... (near top of file) diff --git a/docker-compose.yml b/docker-compose.yml index de97f3a..fc3ecd1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,6 +14,7 @@ services: - ./legacy:/app/legacy environment: - PYTHONUNBUFFERED=1 + - DOMAIN=${DOMAIN:-holy.narl.io} dns: - 8.8.8.8 - 1.1.1.1 @@ -22,7 +23,7 @@ services: - "traefik.docker.network=narl" # Ultra-clean rule for maximum Traefik compatibility - "traefik.http.routers.holy-energy-backend.priority=100" - - "traefik.http.routers.holy-energy-backend.rule=Host(`holy.narl.io`) && (PathPrefix(`/api`) || PathPrefix(`/admin/`) || PathPrefix(`/static`) || PathPrefix(`/media`))" + - "traefik.http.routers.holy-energy-backend.rule=Host(`${DOMAIN:-holy.narl.io}`) && (PathPrefix(`/api`) || PathPrefix(`/admin/`) || PathPrefix(`/static`) || PathPrefix(`/media`))" - "traefik.http.routers.holy-energy-backend.entrypoints=websecure" - "traefik.http.routers.holy-energy-backend.tls.certresolver=https_resolver" - "traefik.http.services.holy-energy-backend.loadbalancer.server.port=8000" @@ -46,6 +47,8 @@ services: - 1.1.1.1 env_file: - .env + environment: + - DOMAIN=${DOMAIN:-holy.narl.io} volumes: - ./backend:/app - ./legacy:/app/legacy @@ -57,7 +60,7 @@ services: build: context: ./frontend args: - - VITE_API_URL=https://holy.narl.io/api/ + - VITE_API_URL=https://${DOMAIN:-holy.narl.io}/api/ - VITE_IMPRESSUM_NAME=${VITE_IMPRESSUM_NAME} - VITE_IMPRESSUM_STREET=${VITE_IMPRESSUM_STREET} - VITE_IMPRESSUM_CITY=${VITE_IMPRESSUM_CITY} @@ -76,7 +79,7 @@ services: - "traefik.enable=true" - "traefik.docker.network=narl" - "traefik.http.routers.holy-energy-frontend.priority=10" - - "traefik.http.routers.holy-energy-frontend.rule=Host(`holy.narl.io`)" + - "traefik.http.routers.holy-energy-frontend.rule=Host(`${DOMAIN:-holy.narl.io}`)" - "traefik.http.routers.holy-energy-frontend.entrypoints=websecure" - "traefik.http.routers.holy-energy-frontend.tls.certresolver=https_resolver" - "traefik.http.services.holy-energy-frontend.loadbalancer.server.port=80"