- Update Ansible playbooks and roles for application deployment - Add new Gitea/Traefik troubleshooting playbooks - Update Docker Compose configurations (base, local, staging, production) - Enhance EncryptedEnvLoader with improved error handling - Add deployment scripts (autossh setup, migration, secret testing) - Update CI/CD workflows and documentation - Add Semaphore stack configuration
245 lines
6.2 KiB
Bash
245 lines
6.2 KiB
Bash
#!/bin/bash
|
||
#
|
||
# Migration Script: .env → .env.base + .env.local
|
||
#
|
||
# This script helps migrate from the legacy single .env file
|
||
# to the new Base+Override Pattern (.env.base + .env.local)
|
||
#
|
||
# Usage:
|
||
# ./scripts/migrate-env-to-base-override.sh
|
||
#
|
||
|
||
set -e
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||
|
||
cd "$PROJECT_ROOT"
|
||
|
||
echo "🔄 Migration: .env → .env.base + .env.local"
|
||
echo ""
|
||
|
||
# Check if .env exists
|
||
if [ ! -f .env ]; then
|
||
echo "❌ .env Datei nicht gefunden"
|
||
echo "💡 Erstelle zuerst .env aus .env.example"
|
||
exit 1
|
||
fi
|
||
|
||
# Backup existing .env
|
||
BACKUP_FILE=".env.backup.$(date +%Y%m%d-%H%M%S)"
|
||
echo "📦 Backup erstellen: $BACKUP_FILE"
|
||
cp .env "$BACKUP_FILE"
|
||
echo "✅ Backup erstellt"
|
||
|
||
# Check if .env.base exists
|
||
if [ -f .env.base ]; then
|
||
echo ""
|
||
echo "⚠️ .env.base existiert bereits"
|
||
echo "💡 .env.base wird als Basis verwendet"
|
||
USE_EXISTING_BASE=true
|
||
else
|
||
USE_EXISTING_BASE=false
|
||
fi
|
||
|
||
# Check if .env.local exists
|
||
if [ -f .env.local ]; then
|
||
echo ""
|
||
echo "⚠️ .env.local existiert bereits"
|
||
read -p "Überschreiben? (j/n): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Jj]$ ]]; then
|
||
echo "❌ Abgebrochen"
|
||
exit 1
|
||
fi
|
||
BACKUP_LOCAL=".env.local.backup.$(date +%Y%m%d-%H%M%S)"
|
||
cp .env.local "$BACKUP_LOCAL"
|
||
echo "📦 Backup von .env.local erstellt: $BACKUP_LOCAL"
|
||
fi
|
||
|
||
echo ""
|
||
echo "📝 Analysiere .env Datei..."
|
||
|
||
# Common variables that should go to .env.base
|
||
# (These are typically environment-agnostic)
|
||
BASE_VARS=(
|
||
"APP_NAME"
|
||
"APP_TIMEZONE"
|
||
"APP_LOCALE"
|
||
"DB_DRIVER"
|
||
"DB_PORT"
|
||
"DB_CHARSET"
|
||
"REDIS_PORT"
|
||
"CACHE_DRIVER"
|
||
"SESSION_DRIVER"
|
||
"SESSION_LIFETIME"
|
||
"QUEUE_DRIVER"
|
||
"QUEUE_CONNECTION"
|
||
"QUEUE_WORKER_SLEEP"
|
||
"QUEUE_WORKER_TRIES"
|
||
"QUEUE_WORKER_TIMEOUT"
|
||
"SECURITY_RATE_LIMIT_PER_MINUTE"
|
||
"SECURITY_RATE_LIMIT_BURST"
|
||
"CACHE_PREFIX"
|
||
)
|
||
|
||
# Local-specific variables (development overrides)
|
||
LOCAL_VARS=(
|
||
"APP_ENV"
|
||
"APP_DEBUG"
|
||
"APP_URL"
|
||
"APP_KEY"
|
||
"APP_DOMAIN"
|
||
"DB_HOST"
|
||
"DB_DATABASE"
|
||
"DB_USERNAME"
|
||
"DB_PASSWORD"
|
||
"REDIS_HOST"
|
||
"REDIS_PASSWORD"
|
||
"SECURITY_ALLOWED_HOSTS"
|
||
"FORCE_HTTPS"
|
||
"XDEBUG_MODE"
|
||
"PHP_IDE_CONFIG"
|
||
)
|
||
|
||
# Variables that should NOT be in .env.base (secrets)
|
||
SECRET_PATTERNS=(
|
||
"PASSWORD"
|
||
"SECRET"
|
||
"KEY"
|
||
"TOKEN"
|
||
"ENCRYPTION"
|
||
"VAULT"
|
||
)
|
||
|
||
echo ""
|
||
echo "📋 Trenne Variablen in Base und Local..."
|
||
|
||
# Create temporary files
|
||
TMP_BASE=$(mktemp)
|
||
TMP_LOCAL=$(mktemp)
|
||
|
||
# Read .env line by line
|
||
while IFS= read -r line || [ -n "$line" ]; do
|
||
# Skip empty lines and comments
|
||
if [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]]; then
|
||
echo "$line" >> "$TMP_BASE"
|
||
echo "$line" >> "$TMP_LOCAL"
|
||
continue
|
||
fi
|
||
|
||
# Extract variable name
|
||
if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)= ]]; then
|
||
VAR_NAME="${BASH_REMATCH[1]}"
|
||
|
||
# Check if it's a secret
|
||
IS_SECRET=false
|
||
for pattern in "${SECRET_PATTERNS[@]}"; do
|
||
if [[ "$VAR_NAME" == *"$pattern"* ]]; then
|
||
IS_SECRET=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$IS_SECRET" = true ]; then
|
||
# Secrets go to .env.local (or should be in Docker Secrets)
|
||
echo "# TODO: Möglicherweise in Docker Secrets verschieben" >> "$TMP_LOCAL"
|
||
echo "$line" >> "$TMP_LOCAL"
|
||
continue
|
||
fi
|
||
|
||
# Check if it's a base variable
|
||
IS_BASE=false
|
||
for base_var in "${BASE_VARS[@]}"; do
|
||
if [[ "$VAR_NAME" == "$base_var" ]]; then
|
||
IS_BASE=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
# Check if it's a local variable
|
||
IS_LOCAL=false
|
||
for local_var in "${LOCAL_VARS[@]}"; do
|
||
if [[ "$VAR_NAME" == "$local_var" ]]; then
|
||
IS_LOCAL=true
|
||
break
|
||
fi
|
||
done
|
||
|
||
if [ "$IS_BASE" = true ]; then
|
||
# Go to .env.base
|
||
echo "$line" >> "$TMP_BASE"
|
||
elif [ "$IS_LOCAL" = true ]; then
|
||
# Go to .env.local
|
||
echo "$line" >> "$TMP_LOCAL"
|
||
else
|
||
# Unknown: Ask or put in local as default
|
||
echo "# TODO: Prüfen ob Base oder Local" >> "$TMP_LOCAL"
|
||
echo "$line" >> "$TMP_LOCAL"
|
||
fi
|
||
else
|
||
# Non-standard line format: keep in both (shouldn't happen)
|
||
echo "$line" >> "$TMP_BASE"
|
||
echo "$line" >> "$TMP_LOCAL"
|
||
fi
|
||
done < .env
|
||
|
||
# Create .env.base if it doesn't exist
|
||
if [ "$USE_EXISTING_BASE" = false ]; then
|
||
echo ""
|
||
echo "📝 Erstelle .env.base..."
|
||
cat > .env.base << 'EOF'
|
||
# Base Environment Configuration
|
||
# This file contains shared environment variables for all environments.
|
||
# Use with environment-specific override files:
|
||
# - .env.local (local development overrides)
|
||
# - .env.staging (staging-specific overrides, optional)
|
||
# - .env.production (production - generated by Ansible)
|
||
#
|
||
# Framework automatically loads: .env.base → .env.local (if exists)
|
||
# See ENV_SETUP.md for details
|
||
#
|
||
EOF
|
||
cat "$TMP_BASE" >> .env.base
|
||
echo "✅ .env.base erstellt"
|
||
else
|
||
echo ""
|
||
echo "ℹ️ .env.base existiert bereits, wird nicht überschrieben"
|
||
fi
|
||
|
||
# Create .env.local
|
||
echo ""
|
||
echo "📝 Erstelle .env.local..."
|
||
cat > .env.local << 'EOF'
|
||
# Local Development Environment Overrides
|
||
# This file overrides .env.base with local development-specific settings.
|
||
# This file is gitignored - each developer has their own version.
|
||
#
|
||
# Framework loads: .env.base → .env.local (this file) → System ENV vars
|
||
# See ENV_SETUP.md for details
|
||
#
|
||
EOF
|
||
cat "$TMP_LOCAL" >> .env.local
|
||
echo "✅ .env.local erstellt"
|
||
|
||
# Cleanup
|
||
rm -f "$TMP_BASE" "$TMP_LOCAL"
|
||
|
||
echo ""
|
||
echo "✅ Migration abgeschlossen!"
|
||
echo ""
|
||
echo "📋 Nächste Schritte:"
|
||
echo " 1. Prüfe .env.base - entferne Secrets falls vorhanden"
|
||
echo " 2. Prüfe .env.local - passe lokale Overrides an"
|
||
echo " 3. Teste die Anwendung: make up"
|
||
echo " 4. Optional: .env kann später entfernt werden (wird als Fallback geladen)"
|
||
echo ""
|
||
echo "📝 Backup-Dateien:"
|
||
echo " - $BACKUP_FILE"
|
||
if [ -n "$BACKUP_LOCAL" ]; then
|
||
echo " - $BACKUP_LOCAL"
|
||
fi
|
||
echo ""
|
||
echo "💡 Siehe ENV_SETUP.md für Details zur neuen Struktur"
|
||
|