feat: ENV-Struktur massiv vereinfacht (Phase 6)

- Von 16 .env Dateien auf 2 zentrale reduziert
  * docker/dev/.env - Development Secrets
  * docker/prod/.env - Production Secrets

- Alle ENV-Variablen jetzt in docker-compose.yml environment sections
- .env COPY aus allen Dockerfiles entfernt (wurden durch volume mounts überschrieben)
- Frontend env.sh umgeschrieben: Liest ENV-Variablen statt .env Datei
- CLIENT_URL komplett entfernt (wurde nirgendwo verwendet)

- Fix: management.js nutzt platform_name statt name (DB-Schema korrekt)

ENV-Handling jetzt deutlich einfacher und wartbarer!
Von 4 Frontend ENV-Variablen auf 3 reduziert (API_URL, PUBLIC_HOST, INTERNAL_HOST)
This commit is contained in:
Matthias Lotz 2025-11-30 13:19:24 +01:00
parent d76b4b2c9c
commit dd71dcab44
14 changed files with 81 additions and 71 deletions

View File

@ -74,10 +74,10 @@ Implementierung eines Telegram Bots zur automatischen Benachrichtigung der Werks
--- ---
### Phase 5: Tägliche Lösch-Warnungen ⭐ **CURRENT** ### Phase 5: Tägliche Lösch-Warnungen
**Ziel:** Cron-Job für bevorstehende Löschungen **Ziel:** Cron-Job für bevorstehende Löschungen
**Status:** 🟡 Dokumentation ausstehend **Status:** 🟢 Abgeschlossen
**Dependencies:** Phase 4 abgeschlossen **Dependencies:** Phase 4 abgeschlossen
@ -87,21 +87,35 @@ Implementierung eines Telegram Bots zur automatischen Benachrichtigung der Werks
- [x] Admin-Route für manuellen Trigger (`POST /api/admin/telegram/warning`) - [x] Admin-Route für manuellen Trigger (`POST /api/admin/telegram/warning`)
- [x] SchedulerService Integration (09:00 daily) - [x] SchedulerService Integration (09:00 daily)
- [x] Docker ENV-Variablen konfiguriert - [x] Docker ENV-Variablen konfiguriert
- [ ] README.md Update - [x] README.md Update
--- ---
### Phase 6: Production Deployment ### Phase 6: Production Deployment ⭐ **CURRENT**
**Ziel:** Rollout in Production-Umgebung **Ziel:** Rollout in Production-Umgebung + ENV-Vereinfachung
**Status:** 🟡 In Arbeit
**Dependencies:** Phase 1-5 abgeschlossen + getestet **Dependencies:** Phase 1-5 abgeschlossen + getestet
**Deliverables:** **Deliverables:**
- [ ] Production ENV-Variablen - [x] ENV-Struktur vereinfachen (zu viele .env-Dateien!)
- [ ] Docker Prod Environment konfiguriert - [x] Production ENV-Variablen in docker/prod/.env konfigurieren
- [ ] Bot in echte Werkstatt-Gruppe eingefügt - [x] docker/prod/docker-compose.yml mit Telegram-ENV erweitern
- [ ] Monitoring/Logging - [ ] Bot in echte Werkstatt-Gruppe einfügen (Produktions-Chat-ID)
- [ ] README.md Update - [ ] Production Testing & Deployment-Anleitung
- [ ] README.md Update mit Production-Setup
**ENV-Vereinfachung (Abgeschlossen):**
```
Vorher: 16 .env-Dateien mit redundanter Konfiguration
Nachher: 2 zentrale .env-Dateien
✅ docker/dev/.env (alle dev secrets)
✅ docker/prod/.env (alle prod secrets)
✅ docker-compose.yml nutzt ${VAR} Platzhalter
✅ Gemountete .env-Dateien entfernt (wurden überschrieben)
✅ Alle ENV-Variablen in docker-compose environment
```
--- ---
@ -360,8 +374,8 @@ git commit -m "docs: Update README with Telegram features"
| Phase 2 | 🟢 Abgeschlossen | 2025-11-29 | | Phase 2 | 🟢 Abgeschlossen | 2025-11-29 |
| Phase 3 | 🟢 Abgeschlossen | 2025-11-29 | | Phase 3 | 🟢 Abgeschlossen | 2025-11-29 |
| Phase 4 | 🟢 Abgeschlossen | 2025-11-30 | | Phase 4 | 🟢 Abgeschlossen | 2025-11-30 |
| Phase 5 | 🟡 Dokumentation | 2025-11-30 | | Phase 5 | 🟢 Abgeschlossen | 2025-11-30 |
| Phase 6 | ⚪ Ausstehend | - | | Phase 6 | 🟡 ENV vereinfacht | 2025-11-30 |
**Legende:** **Legende:**
- 🟢 Abgeschlossen - 🟢 Abgeschlossen

View File

@ -609,7 +609,6 @@ For detailed testing instructions, see: [`tests/TESTING-CLEANUP.md`](tests/TESTI
| Variable | Default | Description | | Variable | Default | Description |
|----------|---------|-------------| |----------|---------|-------------|
| `API_URL` | `http://localhost:5001` | Backend API endpoint | | `API_URL` | `http://localhost:5001` | Backend API endpoint |
| `CLIENT_URL` | `http://localhost` | Frontend application URL |
| `TELEGRAM_ENABLED` | `false` | Enable/disable Telegram notifications | | `TELEGRAM_ENABLED` | `false` | Enable/disable Telegram notifications |
| `TELEGRAM_BOT_TOKEN` | - | Telegram Bot API token (from @BotFather) | | `TELEGRAM_BOT_TOKEN` | - | Telegram Bot API token (from @BotFather) |
| `TELEGRAM_CHAT_ID` | - | Telegram chat/group ID for notifications | | `TELEGRAM_CHAT_ID` | - | Telegram chat/group ID for notifications |

View File

@ -285,7 +285,7 @@ router.put('/:token/consents', async (req, res) => {
if (telegramService.isAvailable()) { if (telegramService.isAvailable()) {
// Hole Platform-Name für Benachrichtigung // Hole Platform-Name für Benachrichtigung
const platform = await dbManager.get( const platform = await dbManager.get(
'SELECT name FROM social_media_platforms WHERE id = ?', 'SELECT platform_name FROM social_media_platforms WHERE id = ?',
[platformId] [platformId]
); );
@ -295,7 +295,7 @@ router.put('/:token/consents', async (req, res) => {
title: groupData.title, title: groupData.title,
consentType: 'social_media', consentType: 'social_media',
action: action, action: action,
platform: platform ? platform.name : `Platform ${platformId}` platform: platform ? platform.platform_name : `Platform ${platformId}`
}).catch(err => { }).catch(err => {
console.error('[Telegram] Consent change notification failed:', err.message); console.error('[Telegram] Consent change notification failed:', err.message);
}); });

View File

@ -6,7 +6,4 @@
# Production: http://backend:5000 (container-to-container) # Production: http://backend:5000 (container-to-container)
API_URL=http://backend:5000 API_URL=http://backend:5000
# Client URL - the URL where users access the frontend # Public/Internal host separation (optional)
# Development: http://localhost:3000 (dev server)
# Production: http://localhost (nginx on port 80)
CLIENT_URL=http://localhost

View File

@ -1,6 +1,9 @@
# Docker Compose Environment Variables for Development # Docker Compose Environment Variables for Development
# Copy this file to .env and adjust values # Copy this file to .env and adjust values
# Admin Session Secret (optional, has default: dev-session-secret-change-me)
#ADMIN_SESSION_SECRET=your-secret-here
# Telegram Bot Configuration (optional) # Telegram Bot Configuration (optional)
TELEGRAM_ENABLED=false TELEGRAM_ENABLED=false
TELEGRAM_SEND_TEST_ON_START=false TELEGRAM_SEND_TEST_ON_START=false

View File

@ -12,8 +12,8 @@ RUN npm install
# Copy backend source code # Copy backend source code
COPY backend/ . COPY backend/ .
# Copy development environment configuration # Note: Environment variables are set via docker-compose.yml
COPY docker/dev/backend/config/.env ./.env # No .env file needed in the image
# Expose port # Expose port
EXPOSE 5000 EXPOSE 5000

View File

@ -15,7 +15,6 @@ services:
volumes: volumes:
- ../../frontend:/app:cached - ../../frontend:/app:cached
- dev_frontend_node_modules:/app/node_modules - dev_frontend_node_modules:/app/node_modules
- ./frontend/config/.env:/app/.env:ro
environment: environment:
- CHOKIDAR_USEPOLLING=true - CHOKIDAR_USEPOLLING=true
- API_URL=http://localhost:5001 - API_URL=http://localhost:5001
@ -38,9 +37,11 @@ services:
volumes: volumes:
- ../../backend:/usr/src/app:cached - ../../backend:/usr/src/app:cached
- dev_backend_node_modules:/usr/src/app/node_modules - dev_backend_node_modules:/usr/src/app/node_modules
- ./backend/config/.env:/usr/src/app/.env:ro
environment: environment:
- NODE_ENV=development - NODE_ENV=development
- PORT=5000
- REMOVE_IMAGES=false
- ADMIN_SESSION_SECRET=${ADMIN_SESSION_SECRET:-dev-session-secret-change-me}
- PUBLIC_HOST=public.test.local - PUBLIC_HOST=public.test.local
- INTERNAL_HOST=internal.test.local - INTERNAL_HOST=internal.test.local
- ENABLE_HOST_RESTRICTION=true - ENABLE_HOST_RESTRICTION=true

View File

@ -13,9 +13,9 @@ WORKDIR /app
# Copy package files first to leverage Docker cache for npm install # Copy package files first to leverage Docker cache for npm install
COPY frontend/package*.json ./ COPY frontend/package*.json ./
# Copy environment configuration # Copy environment shell script (generates env-config.js from ENV at runtime)
COPY docker/dev/frontend/config/env.sh ./env.sh COPY docker/dev/frontend/config/env.sh ./env.sh
COPY docker/dev/frontend/config/.env ./.env # Note: ENV variables are set via docker-compose.yml, not from .env file
# Make env.sh executable # Make env.sh executable
RUN chmod +x ./env.sh RUN chmod +x ./env.sh

View File

@ -7,23 +7,18 @@ touch ./env-config.js
# Add assignment # Add assignment
echo "window._env_ = {" >> ./env-config.js echo "window._env_ = {" >> ./env-config.js
# Read each line in .env file # List of environment variables to export (add more as needed)
# Each line represents key=value pairs ENV_VARS="API_URL PUBLIC_HOST INTERNAL_HOST"
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%s\n' "$line" | grep -q -e '='; then
varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
fi
# Read value of current variable if exists as Environment variable # Read each environment variable and add to config
value=$(printf '%s\n' "${!varname}") for varname in $ENV_VARS; do
# Otherwise use value from .env file # Get value from environment using indirect expansion
[[ -z $value ]] && value=${varvalue} value="${!varname}"
# Append configuration property to JS file # Only add if value exists
echo " $varname: \"$value\"," >> ./env-config.js if [ -n "$value" ]; then
done < .env echo " $varname: \"$value\"," >> ./env-config.js
fi
done
echo "}" >> ./env-config.js echo "}" >> ./env-config.js

View File

@ -1,17 +1,18 @@
# Docker Compose Environment Variables for Production # Docker Compose Environment Variables for Production
# Copy this file to .env and adjust values # Copy this file to .env and adjust values
# IMPORTANT: Keep this file secure and never commit .env to git!
# Admin Session Secret (IMPORTANT: Generate new secret!) # Admin Session Secret (REQUIRED: Generate new secret!)
# Generate with: openssl rand -base64 32 # Generate with: openssl rand -base64 32
ADMIN_SESSION_SECRET=CHANGE-ME-IN-PRODUCTION ADMIN_SESSION_SECRET=CHANGE-ME-IN-PRODUCTION
# Telegram Bot Configuration (optional) # Telegram Bot Configuration (optional)
# Set to true to enable Telegram notifications in production
TELEGRAM_ENABLED=false TELEGRAM_ENABLED=false
TELEGRAM_SEND_TEST_ON_START=false # Bot-Token from @BotFather (production bot)
# Bot-Token from @BotFather
# Example: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz1234567890 # Example: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz1234567890
TELEGRAM_BOT_TOKEN=your-bot-token-here TELEGRAM_BOT_TOKEN=your-production-bot-token-here
# Chat-ID of the Telegram group (negative for groups!) # Chat-ID of the production Telegram group (negative for groups!)
# Get via: https://api.telegram.org/bot<TOKEN>/getUpdates # Get via: https://api.telegram.org/bot<TOKEN>/getUpdates
# Example: -1001234567890 # Example: -1001234567890
TELEGRAM_CHAT_ID=your-chat-id-here TELEGRAM_CHAT_ID=your-production-chat-id-here

View File

@ -15,8 +15,8 @@ services:
- backend - backend
environment: environment:
- API_URL=http://backend:5000 - API_URL=http://backend:5000
- PUBLIC_HOST=deinprojekt.hobbyhimmel.de - PUBLIC_HOST=public.test.local
- INTERNAL_HOST=deinprojekt.lan.hobbyhimmel.de - INTERNAL_HOST=internal.test.local
networks: networks:
- npm-nw - npm-nw
@ -42,13 +42,18 @@ services:
# ⚠️ Für HTTP-only Labs per Override auf "false" setzen (nicht im Repo committen) # ⚠️ Für HTTP-only Labs per Override auf "false" setzen (nicht im Repo committen)
- ADMIN_SESSION_COOKIE_SECURE=true - ADMIN_SESSION_COOKIE_SECURE=true
# Host Configuration (Public/Internal Separation) # Host Configuration (Public/Internal Separation)
- PUBLIC_HOST=deinprojekt.hobbyhimmel.de - PUBLIC_HOST=public.test.local
- INTERNAL_HOST=deinprojekt.lan.hobbyhimmel.de - INTERNAL_HOST=internal.test.local
- ENABLE_HOST_RESTRICTION=true - ENABLE_HOST_RESTRICTION=true
- PUBLIC_UPLOAD_RATE_LIMIT=20 - PUBLIC_UPLOAD_RATE_LIMIT=20
- PUBLIC_UPLOAD_RATE_WINDOW=3600000 - PUBLIC_UPLOAD_RATE_WINDOW=3600000
# Trust nginx-proxy-manager (1 hop) # Trust nginx-proxy-manager (1 hop)
- TRUST_PROXY_HOPS=1 - TRUST_PROXY_HOPS=1
# Telegram Bot Configuration (optional)
- TELEGRAM_ENABLED=${TELEGRAM_ENABLED:-false}
- TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_CHAT_ID=${TELEGRAM_CHAT_ID}
- TELEGRAM_SEND_TEST_ON_START=false

View File

@ -20,10 +20,10 @@ COPY --from=build /app/build /usr/share/nginx/html
# Default port exposure # Default port exposure
EXPOSE 80 EXPOSE 80
# Copy .env file and shell script to container # Copy .env shell script to container (generates env-config.js from ENV at runtime)
WORKDIR /usr/share/nginx/html WORKDIR /usr/share/nginx/html
COPY docker/prod/frontend/config/env.sh ./env.sh COPY docker/prod/frontend/config/env.sh ./env.sh
COPY docker/prod/frontend/config/.env ./.env # Note: ENV variables are set via docker-compose.yml, not from .env file
# Add bash # Add bash
RUN apk add --no-cache bash RUN apk add --no-cache bash

View File

@ -7,23 +7,18 @@ touch ./env-config.js
# Add assignment # Add assignment
echo "window._env_ = {" >> ./env-config.js echo "window._env_ = {" >> ./env-config.js
# Read each line in .env file # List of environment variables to export (add more as needed)
# Each line represents key=value pairs ENV_VARS="API_URL PUBLIC_HOST INTERNAL_HOST"
while read -r line || [[ -n "$line" ]];
do
# Split env variables by character `=`
if printf '%s\n' "$line" | grep -q -e '='; then
varname=$(printf '%s\n' "$line" | sed -e 's/=.*//')
varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//')
fi
# Read value of current variable if exists as Environment variable # Read each environment variable and add to config
value=$(printf '%s\n' "${!varname}") for varname in $ENV_VARS; do
# Otherwise use value from .env file # Get value from environment using indirect expansion
[[ -z $value ]] && value=${varvalue} value="${!varname}"
# Append configuration property to JS file # Only add if value exists
echo " $varname: \"$value\"," >> ./env-config.js if [ -n "$value" ]; then
done < .env echo " $varname: \"$value\"," >> ./env-config.js
fi
done
echo "}" >> ./env-config.js echo "}" >> ./env-config.js

View File

@ -318,10 +318,10 @@ function MultiUploadPage() {
</div> </div>
<p className="text-small" style={{ color: '#666', marginBottom: '4px' }}> <p className="text-small" style={{ color: '#666', marginBottom: '4px' }}>
<strong>Wichtig:</strong> Bewahren Sie diesen Link sicher auf! Jeder mit diesem Link kann Ihren Upload verwalten. <strong>Wichtig:</strong> Bewahre diesen Link sicher auf! Jeder mit diesem Link kann Deinen Upload verwalten.
</p> </p>
<p className="text-small" style={{ color: '#666', fontStyle: 'italic' }}> <p className="text-small" style={{ color: '#666', fontStyle: 'italic' }}>
<strong>Hinweis:</strong> Über diesen Link können Sie nur die Bilder in der Werkstatt verwalten. Bereits auf Social Media Plattformen veröffentlichte Bilder müssen separat dort gelöscht werden. <strong>Hinweis:</strong> Über diesen Link kannst Du nur die Bilder in der Werkstatt verwalten. Bereits auf Social Media Plattformen veröffentlichte Bilder müssen separat dort gelöscht werden.
</p> </p>
</div> </div>
)} )}