feat: update deployment configuration and encrypted env loader

- 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
This commit is contained in:
2025-11-02 20:38:06 +01:00
parent 7b7f0b41d2
commit 24cbbccf4c
44 changed files with 5280 additions and 276 deletions

184
Makefile
View File

@@ -6,29 +6,56 @@
PROJECT_NAME = michaelschiemer
ENV ?= dev
# Standart Docker Compose Befehle
# Docker Compose Konfiguration
COMPOSE_BASE = docker-compose.base.yml
COMPOSE_LOCAL = docker-compose.local.yml
COMPOSE_STAGING = docker-compose.staging.yml
COMPOSE_PRODUCTION = docker-compose.production.yml
COMPOSE_FILES = -f $(COMPOSE_BASE) -f $(COMPOSE_LOCAL)
up: ## Startet alle Docker-Container
docker compose up -d
# Standart Docker Compose Befehle (Lokale Entwicklung)
up: ## Startet alle Docker-Container (lokale Entwicklung)
docker compose $(COMPOSE_FILES) up -d
down: ## Stoppt alle Container
docker compose down
docker compose $(COMPOSE_FILES) down
build:
docker compose build
build: ## Baut alle Docker-Images
docker compose $(COMPOSE_FILES) build
restart: ## Neustart aller Container
./bin/restart
logs: ## Zeigt Logs aus Docker
docker compose logs -f
docker compose $(COMPOSE_FILES) logs -f
ps: ## Docker PS
docker compose ps
docker compose $(COMPOSE_FILES) ps
reload: ## Dump Autoload & Restart PHP
docker-compose exec php composer dump-autoload -o
docker-compose restart php
docker compose $(COMPOSE_FILES) exec php composer dump-autoload -o
docker compose $(COMPOSE_FILES) restart php
# Staging Environment
up-staging: ## Startet Staging-Container
docker compose -f $(COMPOSE_BASE) -f $(COMPOSE_STAGING) up -d
down-staging: ## Stoppt Staging-Container
docker compose -f $(COMPOSE_BASE) -f $(COMPOSE_STAGING) down
logs-staging: ## Zeigt Staging-Logs
docker compose -f $(COMPOSE_BASE) -f $(COMPOSE_STAGING) logs -f
# Production Environment
up-production: ## Startet Production-Container (nur auf Server)
docker compose -f $(COMPOSE_BASE) -f $(COMPOSE_PRODUCTION) up -d
down-production: ## Stoppt Production-Container (nur auf Server)
docker compose -f $(COMPOSE_BASE) -f $(COMPOSE_PRODUCTION) down
logs-production: ## Zeigt Production-Logs (nur auf Server)
docker compose -f $(COMPOSE_BASE) -f $(COMPOSE_PRODUCTION) logs -f
flush-redis: ## Clear Redis cache (FLUSHALL)
docker exec redis redis-cli FLUSHALL
@@ -48,39 +75,39 @@ deploy: ## Führt Ansible Deploy aus
test: ## Führt alle Tests mit PHP 8.4 aus
@echo "🧪 Running tests with PHP 8.4..."
docker compose --profile test run --rm php-test ./vendor/bin/pest
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest
test-php85: ## Führt alle Tests mit PHP 8.5 aus (Development)
@echo "🧪 Running tests with PHP 8.5..."
docker exec php ./vendor/bin/pest
test-coverage: ## Führt Tests mit Coverage-Report aus (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest --coverage
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest --coverage
test-coverage-html: ## Generiert HTML Coverage-Report (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest --coverage-html coverage-html
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest --coverage-html coverage-html
@echo "📊 Coverage-Report verfügbar unter: coverage-html/index.html"
test-unit: ## Führt nur Unit-Tests aus (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest tests/Unit/
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest tests/Unit/
test-framework: ## Führt nur Framework-Tests aus (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest tests/Framework/
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest tests/Framework/
test-domain: ## Führt nur Domain-Tests aus (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest tests/Domain/
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest tests/Domain/
test-watch: ## Führt Tests im Watch-Modus aus (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest --watch
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest --watch
test-parallel: ## Führt Tests parallel aus (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest --parallel
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest --parallel
test-profile: ## Profiling der langsamsten Tests (PHP 8.4)
docker compose --profile test run --rm php-test ./vendor/bin/pest --profile
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest --profile
test-filter: ## Führt spezifische Tests aus (PHP 8.4) (Usage: make test-filter FILTER="EventDispatcher")
docker compose --profile test run --rm php-test ./vendor/bin/pest --filter="$(FILTER)"
docker compose $(COMPOSE_FILES) --profile test run --rm php-test ./vendor/bin/pest --filter="$(FILTER)"
# Security Checks
security-check: ## Führt Composer Security Audit aus
@@ -130,7 +157,7 @@ console: ## Run console commands (Usage: make console ARGS="command arguments")
composer: ## Use Composer
docker compose exec php composer $(ARGS)
docker compose $(COMPOSE_FILES) exec php composer $(ARGS)
fix-perms: ## Fix permissions
sudo chown -R $(USER):$(USER) .
@@ -139,10 +166,10 @@ cs:
@$(MAKE) composer ARGS="cs"
cs-fix-file: ## Fix code style for a specific file
docker compose exec -e PHP_CS_FIXER_IGNORE_ENV=1 php ./vendor/bin/php-cs-fixer fix $(subst \,/,$(FILE))
docker compose $(COMPOSE_FILES) exec -e PHP_CS_FIXER_IGNORE_ENV=1 php ./vendor/bin/php-cs-fixer fix $(subst \,/,$(FILE))
cs-fix: ## Fix code style for all PHP files
docker compose exec -e PHP_CS_FIXER_IGNORE_ENV=1 php ./vendor/bin/php-cs-fixer fix
docker compose $(COMPOSE_FILES) exec -e PHP_CS_FIXER_IGNORE_ENV=1 php ./vendor/bin/php-cs-fixer fix
phpstan: ## Run PHPStan static analysis
@$(MAKE) composer ARGS="phpstan"
@@ -150,12 +177,38 @@ phpstan: ## Run PHPStan static analysis
phpstan-baseline: ## Generate PHPStan baseline
@$(MAKE) composer ARGS="phpstan-baseline"
ssh: ## SSH-Verbindung zum Production-Server öffnen (nutzt ~/.ssh/config 'production')
@echo "🔌 Verbinde zum Production-Server..."
ssh production
ssh-production: ## SSH-Verbindung zum Production-Server öffnen
@echo "🔌 Verbinde zum Production-Server..."
ssh production
ssh-git: ## SSH-Verbindung zum Git-Server öffnen
@echo "🔌 Verbinde zum Git-Server..."
ssh git.michaelschiemer.de
ssh-status: ## Status der autossh-Services prüfen
@echo "📊 Prüfe autossh Service-Status..."
@systemctl --user status autossh-production.service --no-pager || echo "⚠️ autossh-production.service nicht aktiv"
@echo ""
@ps aux | grep autossh | grep -v grep || echo "⚠️ Keine autossh-Prozesse gefunden"
ssh-logs: ## Logs der autossh-Services anzeigen
@echo "📋 Zeige autossh Logs..."
@journalctl --user -u autossh-production.service -n 20 --no-pager || echo "⚠️ Keine Logs verfügbar"
setup-ssh: ## SSH-Schlüssel korrekt einrichten
mkdir -p ~/.ssh
cp /mnt/c/Users/Mike/.ssh/test.michaelschiemer.de ~/.ssh/staging
chmod 600 ~/.ssh/staging
@echo "SSH-Schlüssel für Staging korrekt eingerichtet"
setup-autossh: ## Autossh für persistente SSH-Verbindungen einrichten
@echo "🔧 Richte autossh für persistente SSH-Verbindungen ein..."
@bash scripts/setup-autossh.sh both
fix-ssh-perms: ## Korrigiert SSH-Schlüsselberechtigungen (veraltet)
chmod 600 /mnt/c/Users/Mike/.ssh/test.michaelschiemer.de
@echo "SSH-Schlüsselberechtigungen korrigiert"
@@ -257,4 +310,87 @@ ssl-backup: ## Backup Let's Encrypt certificates
push-staging: ## Pusht den aktuellen Stand nach origin/staging
git push origin HEAD:staging
.PHONY: up down build restart logs ps phpinfo deploy setup clean clean-coverage status fix-ssh-perms setup-ssh test test-coverage test-coverage-html test-unit test-framework test-domain test-watch test-parallel test-profile test-filter security-check security-audit-json security-check-prod update-production restart-production deploy-production-quick status-production logs-production logs-staging logs-staging-php ssl-init ssl-init-staging ssl-test ssl-renew ssl-status ssl-backup push-staging
# ENV File Management
env-base: ## Erstellt .env.base aus .env.example (gemeinsame Variablen)
@if [ ! -f .env.example ]; then \
echo "❌ .env.example nicht gefunden"; \
exit 1; \
fi
@if [ -f .env.base ]; then \
echo "⚠️ .env.base existiert bereits. Überschreiben? (j/n)"; \
read confirm; \
if [ "$$confirm" != "j" ]; then \
echo "❌ Abgebrochen"; \
exit 1; \
fi
fi
@echo "📝 Erstelle .env.base aus .env.example..."
@cp .env.example .env.base
@echo "✅ .env.base erstellt"
@echo "💡 Bearbeite .env.base und entferne environment-spezifische Variablen"
@echo "💡 Siehe ENV_SETUP.md für Details"
env-local: ## Erstellt .env.local für lokale Development-Overrides
@if [ -f .env.local ]; then \
echo "⚠️ .env.local existiert bereits. Überschreiben? (j/n)"; \
read confirm; \
if [ "$$confirm" != "j" ]; then \
echo "❌ Abgebrochen"; \
exit 1; \
fi
fi
@echo "📝 Erstelle .env.local..."
@if [ -f .env ]; then \
cp .env .env.local; \
echo "✅ .env.local erstellt aus .env"; \
else \
echo "APP_ENV=development" > .env.local; \
echo "APP_DEBUG=true" >> .env.local; \
echo "✅ .env.local erstellt (Minimal-Version)"; \
fi
@echo "💡 Bearbeite .env.local mit deinen lokalen Overrides"
@echo "💡 Siehe ENV_SETUP.md für Details"
env-check: ## Prüft .env.base auf Secrets (sollte keine enthalten)
@echo "🔍 Prüfe .env.base auf Secrets..."
@if [ ! -f .env.base ]; then \
echo "✅ .env.base existiert nicht (optional)"; \
exit 0; \
fi
@if grep -E "(PASSWORD|KEY|SECRET|TOKEN)" .env.base | grep -v "^#" | grep -v "=" | grep -v "^$$" > /dev/null; then \
echo "⚠️ Warnung: .env.base könnte Secrets enthalten:"; \
grep -E "(PASSWORD|KEY|SECRET|TOKEN)" .env.base | grep -v "^#" | grep -v "=" || true; \
echo "💡 Secrets sollten in .env.local oder Docker Secrets sein"; \
exit 1; \
else \
echo "✅ .env.base enthält keine Secrets"; \
fi
@echo ""
@echo "🔍 Prüfe docker-compose.base.yml auf hardcodierte Passwörter..."
@if grep -E "(PASSWORD|SECRET|TOKEN).*:-[^}]*[^}]}" docker-compose.base.yml | grep -v "^#" | grep -v "FILE=" > /dev/null 2>&1; then \
echo "⚠️ Warnung: docker-compose.base.yml enthält möglicherweise hardcodierte Passwörter:"; \
grep -E "(PASSWORD|SECRET|TOKEN).*:-[^}]*[^}]}" docker-compose.base.yml | grep -v "^#" | grep -v "FILE=" || true; \
echo "💡 Passwörter müssen explizit gesetzt werden, keine Fallbacks in Base-Datei"; \
exit 1; \
else \
echo "✅ docker-compose.base.yml enthält keine hardcodierten Passwörter"; \
fi
env-validate: ## Validiert ENV-Files (Base+Override Pattern)
@echo "🔍 Validiere ENV-Files..."
@if [ -f .env.base ]; then \
echo "✅ .env.base existiert"; \
else \
echo "⚠️ .env.base nicht gefunden (optional für Migration)"; \
fi
@if [ -f .env.local ]; then \
echo "✅ .env.local existiert"; \
else \
echo "⚠️ .env.local nicht gefunden"; \
fi
@if [ -f .env ] && [ ! -f .env.base ]; then \
echo "✅ Legacy .env verwendet (Fallback)"; \
fi
@echo "💡 Framework lädt: .env.base → .env.local → System ENV"
.PHONY: up down build restart logs ps phpinfo deploy setup clean clean-coverage status fix-ssh-perms setup-ssh setup-autossh ssh ssh-production ssh-git ssh-status ssh-logs test test-coverage test-coverage-html test-unit test-framework test-domain test-watch test-parallel test-profile test-filter security-check security-audit-json security-check-prod update-production restart-production deploy-production-quick status-production logs-production logs-staging logs-staging-php ssl-init ssl-init-staging ssl-test ssl-renew ssl-status ssl-backup push-staging env-base env-local env-check env-validate