From 8ef2b8547d0bc69b83238288d731523ca5496f7b Mon Sep 17 00:00:00 2001 From: Michael Schiemer Date: Mon, 27 Oct 2025 19:07:12 +0100 Subject: [PATCH] chore: remove retundant .env files. some additional fixes --- .env.analytics.example | 22 -- .env.backup.20250912_133135 | 53 --- .env.production | 116 ------- .env.production.example | 49 --- .env.secrets.example | 107 ------ cookies.txt | 6 - cookies_new.txt | 6 - .../docker-compose.development.yml | 310 ------------------ .../docker-compose.production.yml | 211 ------------ .../applications/docker-compose.staging.yml | 193 ----------- .../applications/environments/README.md | 149 --------- .../environments/production.env.template | 164 --------- .../environments/staging.env.template | 165 ---------- .../playbooks/deploy-rsync-based.yml | 9 +- docker-compose.production.yml | 42 ++- docker/postgres/postgresql.production.conf | 3 + final-test.txt | 1 - ip-test.txt | 1 - src/Framework/Core/ContainerBootstrapper.php | 21 ++ .../RateLimit/RateLimiterInitializer.php | 14 +- .../RateLimit/Storage/CacheStorage.php | 2 + 21 files changed, 74 insertions(+), 1570 deletions(-) delete mode 100644 .env.analytics.example delete mode 100644 .env.backup.20250912_133135 delete mode 100644 .env.production delete mode 100644 .env.production.example delete mode 100644 .env.secrets.example delete mode 100644 cookies.txt delete mode 100644 cookies_new.txt delete mode 100644 deployment/applications/docker-compose.development.yml delete mode 100644 deployment/applications/docker-compose.production.yml delete mode 100644 deployment/applications/docker-compose.staging.yml delete mode 100644 deployment/applications/environments/README.md delete mode 100644 deployment/applications/environments/production.env.template delete mode 100644 deployment/applications/environments/staging.env.template delete mode 100644 final-test.txt delete mode 100644 ip-test.txt diff --git a/.env.analytics.example b/.env.analytics.example deleted file mode 100644 index 14f5cbb5..00000000 --- a/.env.analytics.example +++ /dev/null @@ -1,22 +0,0 @@ -# Analytics-System Konfiguration - -# Allgemeine Analytics-Einstellungen -ANALYTICS_ENABLED=true -ANALYTICS_SAMPLING_RATE=1.0 -ANALYTICS_DATA_PATH=/var/www/html/storage/analytics -ANALYTICS_BUFFER_SIZE=1000 -ANALYTICS_RETENTION_DAYS=365 - -# Security Analytics -SECURITY_ANALYTICS_ENABLED=true - -# Tracking-Features (alle standardmäßig aktiviert) -ANALYTICS_TRACK_PAGE_VIEWS=true -ANALYTICS_TRACK_API_CALLS=true -ANALYTICS_TRACK_USER_ACTIONS=true -ANALYTICS_TRACK_ERRORS=true -ANALYTICS_TRACK_PERFORMANCE=true - -# Produktions-Optimierungen -# ANALYTICS_SAMPLING_RATE=0.1 # 10% Sampling für hohe Last -# ANALYTICS_BUFFER_SIZE=5000 # Größerer Buffer für Performance \ No newline at end of file diff --git a/.env.backup.20250912_133135 b/.env.backup.20250912_133135 deleted file mode 100644 index be789923..00000000 --- a/.env.backup.20250912_133135 +++ /dev/null @@ -1,53 +0,0 @@ -COMPOSE_PROJECT_NAME=michaelschiemer - -APP_ENV=development -APP_PORT=8000 -APP_SSL_PORT=443 - -APP_DEBUG=true - -APP_KEY=base64:kJH8fsd89fs8df7sdf8sdf7sd8f7sdf - -# JavaScript Logger Configuration -VITE_LOG_LEVEL=debug -APP_TIMEZONE=Europe/Berlin -APP_LOCALE=de - -# Session Fingerprinting Configuration (minimal mode for better compatibility) -SESSION_FINGERPRINT_STRICT=false -SESSION_FINGERPRINT_USER_AGENT=true -SESSION_FINGERPRINT_ACCEPT_LANGUAGE=false -SESSION_FINGERPRINT_IP_PREFIX=false -SESSION_FINGERPRINT_THRESHOLD=0.5 - -# Database Configuration (Development) -DB_DRIVER=mysql -DB_HOST=db -DB_PORT=3306 -DB_DATABASE=database -DB_USERNAME=mdb-user -DB_PASSWORD=dfghreh5465fghfgh -DB_CHARSET=utf8mb4 - -DB_ROOT_PASSWORD=qwee65132ertert - -# External APIs (Development - optional) -SHOPIFY_WEBHOOK_SECRET=dev-webhook-secret -RAPIDMAIL_USERNAME=dev-username -RAPIDMAIL_PASSWORD=dev-password -RAPIDMAIL_TEST_MODE=true - -# Analytics Configuration -ANALYTICS_ENABLED=true -ANALYTICS_TRACK_PAGE_VIEWS=true -ANALYTICS_TRACK_API_CALLS=true -ANALYTICS_TRACK_USER_ACTIONS=true -ANALYTICS_TRACK_ERRORS=true -ANALYTICS_TRACK_PERFORMANCE=true - -PHP_VERSION=8.4 - -UID=1000 -GID=1000 - -XDEBUG_MODE=debug,develop diff --git a/.env.production b/.env.production deleted file mode 100644 index a0edb779..00000000 --- a/.env.production +++ /dev/null @@ -1,116 +0,0 @@ -# Production Environment Configuration -# WICHTIG: Dieses File nach .env.production kopieren und anpassen! - -# Application Settings -APP_ENV=production -APP_DEBUG=false -APP_NAME="Michael Schiemer" -APP_KEY=base64:kJH8fsd89fs8df7sdf8sdf7sd8f7sdf -APP_TIMEZONE=Europe/Berlin -APP_LOCALE=de - -# Database Configuration (Production) -DB_DRIVER=pgsql -DB_HOST=db -DB_PORT=5432 -DB_DATABASE=michaelschiemer -DB_USERNAME=mdb_user -DB_PASSWORD=Qo2KNgGqeYksEhKr57pgugakxlothn8J -DB_CHARSET=utf8 - -# Security Configuration -SECURITY_ALLOWED_HOSTS=localhost,michaelschiemer.de,www.michaelschiemer.de -SECURITY_RATE_LIMIT_PER_MINUTE=30 -SECURITY_RATE_LIMIT_BURST=5 -SESSION_LIFETIME=1800 - -# Docker Production Configuration -RESTART_POLICY=always -VOLUME_MODE=ro -LOG_DRIVER=json-file -LOG_MAX_SIZE=10m -LOG_MAX_FILE=3 -LOG_LABELS=environment=production - -# PHP Production Settings -PHP_USER=www-data:www-data -PHP_IDE_CONFIG="" -XDEBUG_MODE=off -COMPOSER_INSTALL_FLAGS="--no-dev --optimize-autoloader --classmap-authoritative" - -# Resource Limits (Production) -WEB_MEMORY_LIMIT=256M -WEB_CPU_LIMIT=0.5 -WEB_MEMORY_RESERVATION=128M -WEB_CPU_RESERVATION=0.25 - -PHP_MEMORY_LIMIT=512M -PHP_CPU_LIMIT=1.0 -PHP_MEMORY_RESERVATION=256M -PHP_CPU_RESERVATION=0.5 - -DB_MEMORY_LIMIT=1G -DB_CPU_LIMIT=1.0 -DB_MEMORY_RESERVATION=512M -DB_CPU_RESERVATION=0.5 - -REDIS_MEMORY_LIMIT=256M -REDIS_CPU_LIMIT=0.5 -REDIS_MEMORY_RESERVATION=128M -REDIS_CPU_RESERVATION=0.25 - -# Network Security (Production) -NETWORK_BACKEND_INTERNAL=true -NETWORK_CACHE_INTERNAL=true - -# Production-specific configs -REDIS_CONFIG_PATH=./docker/redis/redis-secure.conf -# PostgreSQL doesn't need custom config path -HEALTHCHECK_START_PERIOD=30s - -# Production ports (only HTTPS) -APP_PORT= - -# External APIs (Production) -SHOPIFY_WEBHOOK_SECRET=SECURE_WEBHOOK_SECRET_HERE -RAPIDMAIL_USERNAME=production_username -RAPIDMAIL_PASSWORD=SECURE_API_PASSWORD_HERE -RAPIDMAIL_TEST_MODE=false - -# SSL/TLS Configuration -APP_SSL_PORT=443 -FORCE_HTTPS=true - -# Docker Production Settings -COMPOSE_PROJECT_NAME=framework-production -UID=1000 -GID=1000 - -# Performance Settings -OPCACHE_ENABLED=true -REDIS_HOST=production-redis-host -REDIS_PORT=6379 -REDIS_PASSWORD=SECURE_REDIS_PASSWORD_HERE - -# Analytics Configuration (Production) -ANALYTICS_ENABLED=true -ANALYTICS_TRACK_PAGE_VIEWS=true -ANALYTICS_TRACK_API_CALLS=true -ANALYTICS_TRACK_USER_ACTIONS=true -ANALYTICS_TRACK_ERRORS=true -# Disable debug performance tracking -ANALYTICS_TRACK_PERFORMANCE=false - -# Session Fingerprinting (Production - Stricter) -SESSION_FINGERPRINT_STRICT=true -SESSION_FINGERPRINT_USER_AGENT=true -SESSION_FINGERPRINT_ACCEPT_LANGUAGE=true -SESSION_FINGERPRINT_IP_PREFIX=true -SESSION_FINGERPRINT_THRESHOLD=0.8 - -# JavaScript Logger Configuration -VITE_LOG_LEVEL=error - -# Admin IP Whitelist (comma-separated) -# Add your office/home IP for production admin access -ADMIN_ALLOWED_IPS=127.0.0.1,::1 diff --git a/.env.production.example b/.env.production.example deleted file mode 100644 index ba6df3ed..00000000 --- a/.env.production.example +++ /dev/null @@ -1,49 +0,0 @@ -# Production Environment Configuration -# WICHTIG: Dieses File nach .env.production kopieren und anpassen! - -# Application Settings -APP_ENV=production -APP_DEBUG=false -APP_NAME="Framework Production" -APP_KEY=YOUR-SECURE-32-CHARACTER-KEY-HERE -APP_TIMEZONE=Europe/Berlin -APP_LOCALE=de - -# Database Configuration (Production) -DB_DRIVER=mysql -DB_HOST=production-db-host -DB_PORT=3306 -DB_DATABASE=production_database -DB_USERNAME=production_user -DB_PASSWORD=STRONG_DATABASE_PASSWORD_HERE -DB_CHARSET=utf8mb4 - -# Security Configuration -SECURITY_ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com -SECURITY_RATE_LIMIT_PER_MINUTE=30 -SECURITY_RATE_LIMIT_BURST=5 -SESSION_LIFETIME=1800 - -# External APIs (Production) -SHOPIFY_WEBHOOK_SECRET=SECURE_WEBHOOK_SECRET_HERE -RAPIDMAIL_USERNAME=production_username -RAPIDMAIL_PASSWORD=SECURE_API_PASSWORD_HERE -RAPIDMAIL_TEST_MODE=false - -# SSL/TLS Configuration -APP_SSL_PORT=443 -FORCE_HTTPS=true -DOMAIN_NAME=michaelschiemer.de -SSL_EMAIL=mail@michaelschiemer.de -LETSENCRYPT_ENABLED=true - -# Docker Production Settings -COMPOSE_PROJECT_NAME=framework-production -UID=1000 -GID=1000 - -# Performance Settings -OPCACHE_ENABLED=true -REDIS_HOST=production-redis-host -REDIS_PORT=6379 -REDIS_PASSWORD=SECURE_REDIS_PASSWORD_HERE \ No newline at end of file diff --git a/.env.secrets.example b/.env.secrets.example deleted file mode 100644 index e6020aaa..00000000 --- a/.env.secrets.example +++ /dev/null @@ -1,107 +0,0 @@ -# .env.secrets.example - Template for encrypted secrets -# Copy this file to .env.secrets and encrypt your sensitive values -# Generated for michaelschiemer.de framework - -# ============================================================================= -# ENCRYPTION SETUP -# ============================================================================= -# 1. Generate an encryption key: php console.php secrets:generate-key -# 2. Add ENCRYPTION_KEY to your .env file (never commit this!) -# 3. Encrypt secrets: php console.php secrets:encrypt "your-secret-value" -# 4. Store encrypted values below with ENC[...] format - -# ============================================================================= -# DATABASE SECRETS -# ============================================================================= -# Production database password (encrypted) -# SECRET_DB_PASSWORD=ENC[base64encodedencryptedvalue] - -# Database backup encryption key -# SECRET_DB_BACKUP_KEY=ENC[backupencryptionkey] - -# ============================================================================= -# API SECRETS -# ============================================================================= -# Shopify webhook secret -# SECRET_SHOPIFY_WEBHOOK_SECRET=ENC[shopifywebhooksecret] - -# RapidMail API credentials -# SECRET_RAPIDMAIL_USERNAME=ENC[rapidmailusername] -# SECRET_RAPIDMAIL_PASSWORD=ENC[rapidmailpassword] - -# External API keys -# SECRET_PAYMENT_API_KEY=ENC[paymentapikey] -# SECRET_ANALYTICS_API_KEY=ENC[analyticsapikey] - -# ============================================================================= -# AUTHENTICATION SECRETS -# ============================================================================= -# JWT signing secret -# SECRET_JWT_SECRET=ENC[jwtsigningsecret] - -# OAuth client secrets -# SECRET_OAUTH_GOOGLE_SECRET=ENC[googleoauthsecret] -# SECRET_OAUTH_GITHUB_SECRET=ENC[githuboauthsecret] - -# Session encryption key -# SECRET_SESSION_KEY=ENC[sessionencryptionkey] - -# ============================================================================= -# INFRASTRUCTURE SECRETS -# ============================================================================= -# Redis password -# SECRET_REDIS_PASSWORD=ENC[redispassword] - -# SMTP credentials -# SECRET_SMTP_USERNAME=ENC[smtpusername] -# SECRET_SMTP_PASSWORD=ENC[smtppassword] - -# SSL certificate passwords -# SECRET_SSL_CERT_PASSWORD=ENC[sslcertpassword] - -# ============================================================================= -# THIRD-PARTY INTEGRATIONS -# ============================================================================= -# CDN API secrets -# SECRET_CDN_API_KEY=ENC[cdnapikey] - -# Monitoring service tokens -# SECRET_MONITORING_TOKEN=ENC[monitoringtoken] - -# Backup service credentials -# SECRET_BACKUP_ACCESS_KEY=ENC[backupaccesskey] -# SECRET_BACKUP_SECRET_KEY=ENC[backupsecretkey] - -# ============================================================================= -# DEVELOPMENT NOTES -# ============================================================================= -# -# Commands for secret management: -# -# Generate encryption key: -# php console.php secrets:generate-key -# -# Encrypt a value: -# php console.php secrets:encrypt "my-secret-value" -# -# Decrypt a value (for debugging): -# php console.php secrets:decrypt "ENC[encrypted-value]" -# -# Rotate all secrets: -# php console.php secrets:rotate -# -# Validate secrets setup: -# php console.php secrets:validate -# -# ============================================================================= -# SECURITY NOTES -# ============================================================================= -# -# 1. Never commit .env.secrets to version control -# 2. Store ENCRYPTION_KEY securely (environment variable, secret manager) -# 3. Use different encryption keys for different environments -# 4. Regularly rotate secrets and encryption keys -# 5. Monitor secret access through audit logs -# 6. Use HTTPS in production for additional security -# 7. Consider using hardware security modules (HSM) for production -# \ No newline at end of file diff --git a/cookies.txt b/cookies.txt deleted file mode 100644 index 6b46dea9..00000000 --- a/cookies.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Netscape HTTP Cookie File -# https://curl.se/docs/http-cookies.html -# This file was generated by libcurl! Edit at your own risk. - -#HttpOnly_localhost FALSE / FALSE 0 ms_context 38ee2b7c042410ae1a2e8ef537a0e65b47aece9851768697b0128535f2e4470a -localhost FALSE /api/csrf/ FALSE 1759074843 analytics_session 46009b71fe9a786b82b0c81b0a796092 diff --git a/cookies_new.txt b/cookies_new.txt deleted file mode 100644 index a87894ec..00000000 --- a/cookies_new.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Netscape HTTP Cookie File -# https://curl.se/docs/http-cookies.html -# This file was generated by libcurl! Edit at your own risk. - -#HttpOnly_localhost FALSE / FALSE 0 ms_context 00b784d1f39e8e271637d1d7a72b2947c71419832320747d6da79a6a40a4382d -localhost FALSE /api/csrf/ FALSE 1759075715 analytics_session 11630ee766d182b2300f660a3065c58f diff --git a/deployment/applications/docker-compose.development.yml b/deployment/applications/docker-compose.development.yml deleted file mode 100644 index a73064af..00000000 --- a/deployment/applications/docker-compose.development.yml +++ /dev/null @@ -1,310 +0,0 @@ -# Development Environment Overrides -# Custom PHP Framework - Development Tools and Debugging -version: '3.8' - -services: - php: - build: - target: development - args: - - ENV=development - - XDEBUG_ENABLE=true - - COMPOSER_INSTALL_FLAGS=--dev --optimize-autoloader - environment: - APP_ENV: development - APP_DEBUG: true - XDEBUG_MODE: ${XDEBUG_MODE:-develop,debug} - XDEBUG_CONFIG: "client_host=host.docker.internal client_port=9003 start_with_request=yes" - XDEBUG_SESSION: 1 - PHP_MEMORY_LIMIT: 1G - PHP_MAX_EXECUTION_TIME: 0 - PHP_OPCACHE_ENABLE: 0 - PHP_OPCACHE_VALIDATE_TIMESTAMPS: 1 - PHP_ERROR_REPORTING: E_ALL - PHP_DISPLAY_ERRORS: 1 - PHP_LOG_ERRORS: 1 - volumes: - # Development bind mounts for live reload - - type: bind - source: ../../ - target: /var/www/html - consistency: cached - # Override vendor for faster access - - type: volume - source: composer_cache_dev - target: /root/.composer/cache - # Node modules volume to prevent conflicts - - type: volume - source: node_modules - target: /var/www/html/node_modules - ports: - # Expose Xdebug port - - "9003:9003" - read_only: false - deploy: - resources: - limits: - memory: 2G - cpus: '4.0' - reservations: - memory: 512M - cpus: '1.0' - logging: - driver: json-file - options: - max-size: "10m" - max-file: "3" - labels: "service=php,environment=development" - - nginx: - environment: - APP_ENV: development - NGINX_WORKER_PROCESSES: 1 - NGINX_WORKER_CONNECTIONS: 1024 - NGINX_ERROR_LOG_LEVEL: debug - NGINX_ACCESS_LOG_FORMAT: combined - volumes: - # Development Nginx config with Vite proxy - - type: bind - source: deployment/applications/configs/nginx/development.conf - target: /etc/nginx/conf.d/default.conf - read_only: true - # Local SSL certificates for development - - type: bind - source: ../../ssl - target: /etc/nginx/ssl - read_only: true - ports: - # Additional ports for development - - "${APP_PORT:-8080}:80" - - "${APP_SSL_PORT:-8443}:443" - - "8081:8081" # Alternative port - read_only: false - deploy: - resources: - limits: - memory: 256M - cpus: '1.0' - reservations: - memory: 64M - cpus: '0.25' - - mysql: - environment: - # Development database settings - MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-dev_root_password} - MYSQL_PASSWORD: ${DB_PASSWORD:-dev_password} - volumes: - # Development MySQL configuration - - type: bind - source: deployment/applications/configs/mysql/development.cnf - target: /etc/mysql/conf.d/development.cnf - read_only: true - # Development data volume - - type: volume - source: mysql_data_dev - target: /var/lib/mysql - ports: - # Expose MySQL for development tools - - "33060:3306" - read_only: false - command: - - mysqld - - --general-log=1 - - --general-log-file=/var/log/mysql/general.log - - --slow-query-log=1 - - --slow-query-log-file=/var/log/mysql/slow.log - - --long-query-time=1 - deploy: - resources: - limits: - memory: 1G - cpus: '2.0' - reservations: - memory: 256M - cpus: '0.5' - - redis: - environment: - REDIS_PASSWORD: ${REDIS_PASSWORD:-dev_redis_password} - REDIS_MAXMEMORY: 128m - REDIS_SAVE: "60 1000" # More frequent saves in development - volumes: - # Development Redis configuration - - type: bind - source: deployment/applications/configs/redis/development.conf - target: /usr/local/etc/redis/redis.conf - read_only: true - - type: volume - source: redis_data_dev - target: /data - ports: - # Expose Redis for development tools - - "63790:6379" - read_only: false - deploy: - resources: - limits: - memory: 256M - cpus: '0.5' - reservations: - memory: 64M - cpus: '0.25' - - queue-worker: - environment: - APP_ENV: development - APP_DEBUG: true - WORKER_QUEUE: development - WORKER_TIMEOUT: 60 - WORKER_MEMORY_LIMIT: 256 - WORKER_SLEEP: 5 - WORKER_TRIES: 1 - WORKER_DEBUG: true - read_only: false - deploy: - replicas: 1 - resources: - limits: - memory: 512M - cpus: '1.0' - reservations: - memory: 128M - cpus: '0.25' - - # Development-specific services - vite: - image: node:20-alpine - container_name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_vite - working_dir: /app - command: sh -c "npm install && npm run dev" - volumes: - - type: bind - source: ../../ - target: /app - consistency: cached - - type: volume - source: node_modules - target: /app/node_modules - ports: - - "5173:5173" - - "24678:24678" # HMR port - environment: - NODE_ENV: development - VITE_DEV_SERVER_HOST: 0.0.0.0 - VITE_DEV_SERVER_PORT: 5173 - CHOKIDAR_USEPOLLING: true - networks: - - frontend - user: "node:node" - deploy: - resources: - limits: - memory: 512M - cpus: '1.0' - reservations: - memory: 128M - cpus: '0.25' - - mailhog: - image: mailhog/mailhog:v1.0.1 - container_name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_mailhog - ports: - - "1025:1025" # SMTP - - "8025:8025" # Web interface - environment: - MH_STORAGE: maildir - MH_MAILDIR_PATH: /maildir - volumes: - - type: volume - source: mailhog_data - target: /maildir - networks: - - backend - - frontend - user: "mailhog:mailhog" - read_only: true - tmpfs: - - /tmp:noexec,nosuid,size=100m - security_opt: - - no-new-privileges:true - deploy: - resources: - limits: - memory: 128M - cpus: '0.25' - reservations: - memory: 64M - cpus: '0.1' - - phpmyadmin: - image: phpmyadmin:5.2-apache - container_name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_phpmyadmin - environment: - PMA_HOST: mysql - PMA_USER: ${DB_USERNAME:-dev_user} - PMA_PASSWORD: ${DB_PASSWORD:-dev_password} - PMA_ABSOLUTE_URI: http://localhost:8080/phpmyadmin/ - UPLOAD_LIMIT: 64M - MEMORY_LIMIT: 512M - MAX_EXECUTION_TIME: 600 - ports: - - "8080:80" - networks: - - backend - - frontend - depends_on: - mysql: - condition: service_healthy - read_only: false - deploy: - resources: - limits: - memory: 256M - cpus: '0.5' - reservations: - memory: 128M - cpus: '0.25' - - redis-commander: - image: rediscommander/redis-commander:latest - container_name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_redis_commander - environment: - REDIS_HOSTS: local:redis:6379:0:${REDIS_PASSWORD:-dev_redis_password} - HTTP_USER: admin - HTTP_PASSWORD: ${REDIS_COMMANDER_PASSWORD:-dev_admin_password} - ports: - - "8081:8081" - networks: - - cache - - frontend - depends_on: - redis: - condition: service_healthy - user: "node:node" - read_only: true - tmpfs: - - /tmp:noexec,nosuid,size=100m - security_opt: - - no-new-privileges:true - deploy: - resources: - limits: - memory: 128M - cpus: '0.25' - reservations: - memory: 64M - cpus: '0.1' - -volumes: - # Development volumes - composer_cache_dev: - name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_composer_cache_dev - node_modules: - name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_node_modules - mysql_data_dev: - name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_mysql_data_dev - redis_data_dev: - name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_redis_data_dev - mailhog_data: - name: ${COMPOSE_PROJECT_NAME:-michaelschiemer}_mailhog_data \ No newline at end of file diff --git a/deployment/applications/docker-compose.production.yml b/deployment/applications/docker-compose.production.yml deleted file mode 100644 index 10222c67..00000000 --- a/deployment/applications/docker-compose.production.yml +++ /dev/null @@ -1,211 +0,0 @@ -# Production overlay for Custom PHP Framework -# Extends base docker-compose.yml with production optimizations -version: '3.8' - -services: - web: - environment: - - APP_ENV=production - - PHP_IDE_CONFIG= # Remove IDE config in production - ports: - # Remove development ports, only expose HTTPS - - "${APP_SSL_PORT:-443}:443/tcp" - - "443:443/udp" - volumes: - # Read-only application code in production - - ./:/var/www/html:ro - - ./ssl:/var/www/ssl:ro - healthcheck: - test: ["CMD", "curl", "-f", "-k", "https://localhost/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 30s - restart: always - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - labels: "service=nginx,environment=production" - deploy: - resources: - limits: - memory: 256M - cpus: '0.5' - reservations: - memory: 128M - cpus: '0.25' - - php: - environment: - APP_ENV: production - APP_DEBUG: false - PHP_IDE_CONFIG: "" # Remove IDE config - XDEBUG_MODE: off # Disable Xdebug in production - build: - args: - - ENV=production - - COMPOSER_INSTALL_FLAGS=--no-dev --optimize-autoloader --classmap-authoritative - user: "www-data:www-data" # Use www-data in production - volumes: - # Read-only application code - - ./:/var/www/html:ro - # Writable storage volumes - - storage-data:/var/www/html/storage:rw - - var-data:/var/www/html/var:rw - # Composer cache (but less aggressive caching in prod) - - composer-cache:/var/www/.composer/cache - healthcheck: - test: ["CMD", "php", "/var/www/html/public/health.php"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - restart: always - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - labels: "service=php,environment=production" - deploy: - resources: - limits: - memory: 512M - cpus: '1.0' - reservations: - memory: 256M - cpus: '0.5' - - db: - environment: - - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - - MYSQL_DATABASE=${DB_DATABASE} - - MYSQL_USER=${DB_USERNAME} - - MYSQL_PASSWORD=${DB_PASSWORD} - ports: [] # No external ports in production - volumes: - - db_data:/var/lib/mysql - # Production MySQL configuration - - ./docker/mysql/conf.d/security.cnf:/etc/mysql/conf.d/security.cnf:ro - healthcheck: - test: ["CMD", "mariadb-admin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${DB_ROOT_PASSWORD}"] - interval: 30s - timeout: 10s - retries: 5 - start_period: 60s - restart: always - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - labels: "service=mariadb,environment=production" - deploy: - resources: - limits: - memory: 1G - cpus: '1.0' - reservations: - memory: 512M - cpus: '0.5' - - redis: - volumes: - # Use secure Redis configuration in production - - ./docker/redis/redis-secure.conf:/usr/local/etc/redis/redis.conf:ro - - redis_data:/data - command: ["redis-server", "/usr/local/etc/redis/redis.conf"] - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 30s - timeout: 5s - retries: 3 - start_period: 30s - restart: always - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - labels: "service=redis,environment=production" - deploy: - resources: - limits: - memory: 256M - cpus: '0.5' - reservations: - memory: 128M - cpus: '0.25' - - queue-worker: - environment: - - APP_ENV=production - - APP_DEBUG=false - - WORKER_DEBUG=false - - WORKER_SLEEP_TIME=${WORKER_SLEEP_TIME:-100000} - - WORKER_MAX_JOBS=${WORKER_MAX_JOBS:-1000} - - WORKER_MEMORY_LIMIT=${WORKER_MEMORY_LIMIT:-384M} - build: - args: - - ENV=production - - COMPOSER_INSTALL_FLAGS=--no-dev --optimize-autoloader - user: "www-data:www-data" - volumes: - # Read-only application code - - ./:/var/www/html:ro - # Writable logs and storage - - ./storage/logs:/var/www/html/storage/logs:rw - - ./src/Framework/CommandBus/storage:/var/www/html/src/Framework/CommandBus/storage:rw - restart: always - stop_grace_period: 60s # Longer grace period for production - logging: - driver: "json-file" - options: - max-size: "10m" - max-file: "3" - labels: "service=queue-worker,environment=production" - deploy: - resources: - limits: - memory: 512M - cpus: '0.5' - reservations: - memory: 256M - cpus: '0.25' - -# Security-focused network configuration -networks: - frontend: - driver: bridge - ipam: - driver: default - config: - - subnet: 172.24.0.0/24 - backend: - driver: bridge - internal: true # Backend network is internal-only - ipam: - driver: default - config: - - subnet: 172.25.0.0/24 - cache: - driver: bridge - internal: true # Cache network is internal-only - ipam: - driver: default - config: - - subnet: 172.26.0.0/24 - -volumes: - redis_data: - driver: local - composer-cache: - driver: local - storage-data: - driver: local - var-data: - driver: local - db_data: - driver: local \ No newline at end of file diff --git a/deployment/applications/docker-compose.staging.yml b/deployment/applications/docker-compose.staging.yml deleted file mode 100644 index bb9b0148..00000000 --- a/deployment/applications/docker-compose.staging.yml +++ /dev/null @@ -1,193 +0,0 @@ -# Staging overlay for Custom PHP Framework -# Extends base docker-compose.yml with staging-specific configurations -version: '3.8' - -services: - web: - environment: - - APP_ENV=staging - - PHP_IDE_CONFIG= # Remove IDE config in staging - ports: - # Expose both HTTP and HTTPS for staging testing - - "${APP_PORT:-8000}:80" - - "${APP_SSL_PORT:-443}:443/tcp" - - "443:443/udp" - volumes: - # Semi-readonly application code in staging - - ./:/var/www/html:cached - - ./ssl:/var/www/ssl:ro - healthcheck: - test: ["CMD", "curl", "-f", "-k", "https://localhost/health"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 20s - restart: unless-stopped - logging: - driver: "json-file" - options: - max-size: "50m" - max-file: "5" - labels: "service=nginx,environment=staging" - deploy: - resources: - limits: - memory: 512M - cpus: '1.0' - reservations: - memory: 256M - cpus: '0.5' - - php: - environment: - - APP_ENV=staging - - APP_DEBUG=true # Enable debug in staging - - PHP_IDE_CONFIG= # Remove IDE config - - XDEBUG_MODE=debug # Enable Xdebug in staging for debugging - build: - args: - - ENV=staging - - COMPOSER_INSTALL_FLAGS=--optimize-autoloader - user: "1000:1000" # Keep development user for staging - volumes: - # Cached application code for staging - - ./:/var/www/html:cached - - storage-data:/var/www/html/storage:rw - - var-data:/var/www/html/var:rw - - composer-cache:/root/.composer/cache - healthcheck: - test: ["CMD", "php", "/var/www/html/public/health.php"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - restart: unless-stopped - logging: - driver: "json-file" - options: - max-size: "50m" - max-file: "5" - labels: "service=php,environment=staging" - deploy: - resources: - limits: - memory: 1G - cpus: '2.0' - reservations: - memory: 512M - cpus: '1.0' - - db: - environment: - - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - - MYSQL_DATABASE=${DB_DATABASE} - - MYSQL_USER=${DB_USERNAME} - - MYSQL_PASSWORD=${DB_PASSWORD} - ports: - - "33060:3306" # Keep external port for staging database access - volumes: - - db_data:/var/lib/mysql - healthcheck: - test: ["CMD", "mariadb-admin", "ping", "-h", "127.0.0.1", "-u", "root", "-p${DB_ROOT_PASSWORD}"] - interval: 30s - timeout: 10s - retries: 5 - start_period: 60s - restart: unless-stopped - logging: - driver: "json-file" - options: - max-size: "50m" - max-file: "5" - labels: "service=mariadb,environment=staging" - deploy: - resources: - limits: - memory: 1G - cpus: '1.0' - reservations: - memory: 512M - cpus: '0.5' - - redis: - volumes: - # Use standard Redis configuration in staging - - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro - - redis_data:/data - command: ["redis-server", "/usr/local/etc/redis/redis.conf"] - healthcheck: - test: ["CMD", "redis-cli", "ping"] - interval: 30s - timeout: 5s - retries: 3 - start_period: 20s - restart: unless-stopped - logging: - driver: "json-file" - options: - max-size: "50m" - max-file: "5" - labels: "service=redis,environment=staging" - deploy: - resources: - limits: - memory: 512M - cpus: '1.0' - reservations: - memory: 256M - cpus: '0.5' - - queue-worker: - environment: - - APP_ENV=staging - - APP_DEBUG=true # Enable debug for staging - - WORKER_DEBUG=true - - WORKER_SLEEP_TIME=${WORKER_SLEEP_TIME:-100000} - - WORKER_MAX_JOBS=${WORKER_MAX_JOBS:-500} - - WORKER_MEMORY_LIMIT=${WORKER_MEMORY_LIMIT:-512M} - build: - args: - - ENV=staging - - COMPOSER_INSTALL_FLAGS=--optimize-autoloader - user: "1000:1000" - volumes: - - ./:/var/www/html:cached - - ./storage/logs:/var/www/html/storage/logs:rw - - ./src/Framework/CommandBus/storage:/var/www/html/src/Framework/CommandBus/storage:rw - restart: unless-stopped - stop_grace_period: 45s - logging: - driver: "json-file" - options: - max-size: "50m" - max-file: "5" - labels: "service=queue-worker,environment=staging" - deploy: - resources: - limits: - memory: 768M - cpus: '1.0' - reservations: - memory: 384M - cpus: '0.5' - -# Staging network configuration - more permissive than production -networks: - frontend: - driver: bridge - backend: - driver: bridge - cache: - driver: bridge - -volumes: - redis_data: - driver: local - composer-cache: - driver: local - storage-data: - driver: local - var-data: - driver: local - db_data: - driver: local \ No newline at end of file diff --git a/deployment/applications/environments/README.md b/deployment/applications/environments/README.md deleted file mode 100644 index 2bc39a85..00000000 --- a/deployment/applications/environments/README.md +++ /dev/null @@ -1,149 +0,0 @@ -# Environment Configuration Guide - -This directory contains environment templates for different deployment environments of the Custom PHP Framework. - -## Environment Templates - -### `.env.production.template` -Production environment template with security-focused configurations: -- APP_DEBUG=false -- Strict session fingerprinting -- Xdebug disabled -- Production logging levels -- Strong password requirements - -### `.env.staging.template` -Staging environment template for testing: -- APP_DEBUG=true -- Moderate security settings -- Xdebug enabled for debugging -- Verbose logging -- Test API configurations - -## Usage - -1. **Copy the appropriate template:** - ```bash - cp .env.production.template .env.production - # or - cp .env.staging.template .env.staging - ``` - -2. **Fill in required values:** - - Replace all `*** REQUIRED ***` placeholders with actual values - - Generate strong passwords for database credentials - - Configure API keys and service credentials - - Set proper domain names and SSL certificate paths - -3. **Security Considerations:** - - Never commit actual `.env.production` or `.env.staging` files to version control - - Use strong, unique passwords for each environment - - Rotate credentials regularly - - Enable appropriate session fingerprinting for security - -## Environment-Specific Settings - -### Development → Staging Changes -- Enable Xdebug but remove IDE configurations -- Use staging database and credentials -- Enable detailed logging for debugging -- Use test API endpoints where available - -### Staging → Production Changes -- Disable all debug features (APP_DEBUG=false, XDEBUG_MODE=off) -- Enable strict security settings -- Use production database with strong credentials -- Set warning-level logging only -- Configure production SSL certificates -- Use production API keys and webhooks - -## Required Values by Environment - -### Production Requirements -- **Database:** Strong passwords, production database name -- **APIs:** Production webhook secrets, SMTP credentials -- **SSL:** Valid SSL certificate paths -- **Monitoring:** Production-grade logging configuration - -### Staging Requirements -- **Database:** Separate staging database credentials -- **APIs:** Test/staging API keys where available -- **SSL:** Test certificates or self-signed certificates -- **Monitoring:** Verbose logging for debugging - -## Environment Variable Categories - -### Core Application -- `APP_ENV`, `APP_DEBUG`, `APP_URL`, `APP_DOMAIN` - -### Database Configuration -- `DB_HOST`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`, `DB_ROOT_PASSWORD` - -### Security & Session -- Session fingerprinting settings -- SSL certificate paths -- Authentication configurations - -### External Services -- SMTP configuration for emails -- Third-party API credentials -- Webhook secrets - -### Performance & Caching -- OPcache settings -- Redis configuration -- Worker process limits - -### Monitoring & Logging -- Log levels and channels -- Error reporting settings -- Analytics configuration - -## Deployment Integration - -These environment files are used by: -- Docker Compose overlays (`docker-compose.production.yml`, `docker-compose.staging.yml`) -- Ansible deployment playbooks -- Application deployment scripts - -## Security Best Practices - -1. **Credential Management:** - - Use strong, unique passwords for each environment - - Consider using a password manager or secrets management service - - Rotate credentials regularly - -2. **Environment Isolation:** - - Keep staging and production completely separate - - Use different database servers and API keys - - Monitor access to production credentials - -3. **File Permissions:** - - Set restrictive permissions on environment files (600) - - Ensure only necessary users can read the files - - Never include in version control - -4. **SSL/TLS Configuration:** - - Use valid SSL certificates in production - - Enable HTTPS everywhere - - Configure proper cipher suites - -## Troubleshooting - -### Common Issues -- **Missing required values:** Check for `*** REQUIRED ***` placeholders -- **Database connection failures:** Verify database credentials and host -- **SSL certificate errors:** Check certificate paths and permissions -- **API failures:** Verify API keys and endpoint configurations - -### Environment-Specific Debugging -- **Staging:** Enable verbose logging and Xdebug -- **Production:** Check application logs and monitoring systems -- **Both:** Verify environment variable loading in application - -## Integration with Deployment - -The environment templates integrate with: -1. **Docker Compose overlays** for environment-specific container configuration -2. **Ansible playbooks** for automated environment setup -3. **Application deployment scripts** for environment validation and deployment \ No newline at end of file diff --git a/deployment/applications/environments/production.env.template b/deployment/applications/environments/production.env.template deleted file mode 100644 index 2ac06912..00000000 --- a/deployment/applications/environments/production.env.template +++ /dev/null @@ -1,164 +0,0 @@ -# Production Environment Configuration Template -# Copy to .env.production and update with real values - -# Project Configuration -COMPOSE_PROJECT_NAME=michaelschiemer -DOMAIN_NAME=michaelschiemer.de - -# Environment -APP_ENV=production -APP_DEBUG=false -APP_TIMEZONE=Europe/Berlin -APP_LOCALE=de - -# SSL/HTTPS Configuration -APP_SSL_ENABLED=true -SSL_CERT_PATH=/etc/letsencrypt/live/michaelschiemer.de -FORCE_HTTPS=true - -# Database Configuration (Production) -DB_DRIVER=mysql -DB_HOST=db -DB_PORT=3306 -DB_DATABASE=*** REQUIRED *** -DB_USERNAME=*** REQUIRED *** -DB_PASSWORD=*** REQUIRED *** -DB_ROOT_PASSWORD=*** REQUIRED *** -DB_CHARSET=utf8mb4 -DB_COLLATION=utf8mb4_unicode_ci - -# Redis Configuration -REDIS_HOST=redis -REDIS_PORT=6379 -REDIS_PASSWORD=*** REQUIRED *** -REDIS_DATABASE=0 -REDIS_PREFIX=michaelschiemer_prod_ - -# Session Configuration (Production Security) -SESSION_DRIVER=redis -SESSION_LIFETIME=120 -SESSION_ENCRYPT=true -SESSION_SECURE_COOKIE=true -SESSION_HTTP_ONLY=true -SESSION_SAME_SITE=strict - -# Session Fingerprinting (Production Security) -SESSION_FINGERPRINT_STRICT=true -SESSION_FINGERPRINT_USER_AGENT=true -SESSION_FINGERPRINT_ACCEPT_LANGUAGE=true -SESSION_FINGERPRINT_IP_PREFIX=true -SESSION_FINGERPRINT_THRESHOLD=0.8 - -# Cache Configuration -CACHE_DRIVER=redis -CACHE_TTL=3600 -CACHE_PREFIX=michaelschiemer_cache_prod_ - -# Queue Configuration -QUEUE_DRIVER=redis -QUEUE_CONNECTION=redis -QUEUE_PREFIX=michaelschiemer_queue_prod_ -WORKER_QUEUE=production -WORKER_TIMEOUT=300 -WORKER_MEMORY_LIMIT=512 -WORKER_SLEEP=1 -WORKER_TRIES=5 -WORKER_BATCH_SIZE=10 - -# Mail Configuration (Production) -MAIL_DRIVER=*** REQUIRED *** -MAIL_HOST=*** REQUIRED *** -MAIL_PORT=*** REQUIRED *** -MAIL_USERNAME=*** REQUIRED *** -MAIL_PASSWORD=*** REQUIRED *** -MAIL_ENCRYPTION=tls -MAIL_FROM_ADDRESS=kontakt@michaelschiemer.de -MAIL_FROM_NAME="Michael Schiemer" - -# Logging Configuration (Production) -LOG_CHANNEL=stack -LOG_LEVEL=warning -LOG_STACK_CHANNELS=single,syslog -LOG_ROTATE_DAYS=30 -LOG_MAX_FILES=10 - -# External APIs (Production) -SHOPIFY_WEBHOOK_SECRET=*** REQUIRED *** -RAPIDMAIL_USERNAME=*** REQUIRED *** -RAPIDMAIL_PASSWORD=*** REQUIRED *** -RAPIDMAIL_TEST_MODE=false - -# Analytics Configuration (Production) -ANALYTICS_ENABLED=true -ANALYTICS_TRACK_PAGE_VIEWS=true -ANALYTICS_TRACK_API_CALLS=true -ANALYTICS_TRACK_USER_ACTIONS=true -ANALYTICS_TRACK_ERRORS=true -ANALYTICS_TRACK_PERFORMANCE=true - -# Monitoring & Health Checks -PROMETHEUS_ENABLED=true -PROMETHEUS_PORT=9090 -GRAFANA_ADMIN_PASSWORD=*** REQUIRED *** - -# Security Configuration -APP_KEY=*** REQUIRED - Generate with: openssl rand -base64 32 *** -CSRF_TOKEN_LIFETIME=7200 -RATE_LIMIT_PER_MINUTE=60 -MAX_LOGIN_ATTEMPTS=5 -LOGIN_LOCKOUT_DURATION=900 - -# Performance Configuration (Production) -PHP_MEMORY_LIMIT=512M -PHP_MAX_EXECUTION_TIME=30 -PHP_OPCACHE_ENABLE=1 -PHP_OPCACHE_MEMORY_CONSUMPTION=256 -PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 -PHP_OPCACHE_REVALIDATE_FREQ=0 -PHP_OPCACHE_VALIDATE_TIMESTAMPS=0 -PHP_REALPATH_CACHE_SIZE=4M -PHP_REALPATH_CACHE_TTL=3600 - -# Nginx Configuration (Production) -NGINX_WORKER_PROCESSES=4 -NGINX_WORKER_CONNECTIONS=2048 -NGINX_KEEPALIVE_TIMEOUT=65 -NGINX_CLIENT_MAX_BODY_SIZE=50m - -# Database Performance (Production) -MYSQL_INNODB_BUFFER_POOL_SIZE=1G -MYSQL_INNODB_LOG_FILE_SIZE=256M -MYSQL_MAX_CONNECTIONS=100 -MYSQL_QUERY_CACHE_SIZE=0 - -# Backup Configuration -BACKUP_ENABLED=true -BACKUP_SCHEDULE=0 2 * * * -BACKUP_RETENTION_DAYS=30 -BACKUP_S3_BUCKET=*** REQUIRED IF USING S3 *** -BACKUP_S3_ACCESS_KEY=*** REQUIRED IF USING S3 *** -BACKUP_S3_SECRET_KEY=*** REQUIRED IF USING S3 *** - -# SSL/TLS Configuration -SSL_PROTOCOLS=TLSv1.2 TLSv1.3 -SSL_CIPHERS=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 -SSL_PREFER_SERVER_CIPHERS=off -SSL_SESSION_CACHE_SIZE=10m -SSL_SESSION_TIMEOUT=10m - -# Container User IDs (Production) -UID=33 -GID=33 - -# Restart Policy -RESTART_POLICY=always - -# Resource Limits (Production) -PHP_MEMORY_LIMIT_DOCKER=2G -PHP_CPU_LIMIT=2.0 -NGINX_MEMORY_LIMIT_DOCKER=256M -NGINX_CPU_LIMIT=0.5 -DB_MEMORY_LIMIT_DOCKER=2G -DB_CPU_LIMIT=2.0 -REDIS_MEMORY_LIMIT_DOCKER=1G -REDIS_CPU_LIMIT=0.5 \ No newline at end of file diff --git a/deployment/applications/environments/staging.env.template b/deployment/applications/environments/staging.env.template deleted file mode 100644 index 0c012e1b..00000000 --- a/deployment/applications/environments/staging.env.template +++ /dev/null @@ -1,165 +0,0 @@ -# Staging Environment Configuration Template -# Copy to .env.staging and update with real values - -# Project Configuration -COMPOSE_PROJECT_NAME=michaelschiemer-staging -DOMAIN_NAME=staging.michaelschiemer.de - -# Environment -APP_ENV=staging -APP_DEBUG=false -APP_TIMEZONE=Europe/Berlin -APP_LOCALE=de - -# SSL/HTTPS Configuration (Staging with Let's Encrypt Staging CA) -APP_SSL_ENABLED=true -SSL_CERT_PATH=/etc/letsencrypt/live/staging.michaelschiemer.de -FORCE_HTTPS=true - -# Database Configuration (Staging) -DB_DRIVER=mysql -DB_HOST=db -DB_PORT=3306 -DB_DATABASE=*** REQUIRED *** -DB_USERNAME=*** REQUIRED *** -DB_PASSWORD=*** REQUIRED *** -DB_ROOT_PASSWORD=*** REQUIRED *** -DB_CHARSET=utf8mb4 -DB_COLLATION=utf8mb4_unicode_ci - -# Redis Configuration -REDIS_HOST=redis -REDIS_PORT=6379 -REDIS_PASSWORD=*** REQUIRED *** -REDIS_DATABASE=1 -REDIS_PREFIX=michaelschiemer_staging_ - -# Session Configuration (Staging) -SESSION_DRIVER=redis -SESSION_LIFETIME=240 -SESSION_ENCRYPT=true -SESSION_SECURE_COOKIE=true -SESSION_HTTP_ONLY=true -SESSION_SAME_SITE=strict - -# Session Fingerprinting (Staging - Less Strict) -SESSION_FINGERPRINT_STRICT=false -SESSION_FINGERPRINT_USER_AGENT=true -SESSION_FINGERPRINT_ACCEPT_LANGUAGE=true -SESSION_FINGERPRINT_IP_PREFIX=false -SESSION_FINGERPRINT_THRESHOLD=0.7 - -# Cache Configuration -CACHE_DRIVER=redis -CACHE_TTL=1800 -CACHE_PREFIX=michaelschiemer_cache_staging_ - -# Queue Configuration -QUEUE_DRIVER=redis -QUEUE_CONNECTION=redis -QUEUE_PREFIX=michaelschiemer_queue_staging_ -WORKER_QUEUE=staging -WORKER_TIMEOUT=120 -WORKER_MEMORY_LIMIT=384 -WORKER_SLEEP=3 -WORKER_TRIES=3 -WORKER_BATCH_SIZE=5 - -# Mail Configuration (Staging - Development SMTP or Mailtrap) -MAIL_DRIVER=smtp -MAIL_HOST=*** REQUIRED - Use Mailtrap or similar *** -MAIL_PORT=2525 -MAIL_USERNAME=*** REQUIRED *** -MAIL_PASSWORD=*** REQUIRED *** -MAIL_ENCRYPTION=tls -MAIL_FROM_ADDRESS=staging@michaelschiemer.de -MAIL_FROM_NAME="Michael Schiemer (Staging)" - -# Logging Configuration (Staging - More Verbose) -LOG_CHANNEL=stack -LOG_LEVEL=info -LOG_STACK_CHANNELS=single,daily -LOG_ROTATE_DAYS=7 -LOG_MAX_FILES=5 - -# External APIs (Staging - Test Mode) -SHOPIFY_WEBHOOK_SECRET=staging-webhook-secret -RAPIDMAIL_USERNAME=*** REQUIRED *** -RAPIDMAIL_PASSWORD=*** REQUIRED *** -RAPIDMAIL_TEST_MODE=true - -# Analytics Configuration (Staging) -ANALYTICS_ENABLED=true -ANALYTICS_TRACK_PAGE_VIEWS=true -ANALYTICS_TRACK_API_CALLS=true -ANALYTICS_TRACK_USER_ACTIONS=true -ANALYTICS_TRACK_ERRORS=true -ANALYTICS_TRACK_PERFORMANCE=true - -# Monitoring & Health Checks (Staging) -PROMETHEUS_ENABLED=true -PROMETHEUS_PORT=9091 -GRAFANA_ADMIN_PASSWORD=*** REQUIRED *** - -# Security Configuration (Staging - Slightly Relaxed) -APP_KEY=*** REQUIRED - Generate with: openssl rand -base64 32 *** -CSRF_TOKEN_LIFETIME=7200 -RATE_LIMIT_PER_MINUTE=120 -MAX_LOGIN_ATTEMPTS=10 -LOGIN_LOCKOUT_DURATION=300 - -# Performance Configuration (Staging) -PHP_MEMORY_LIMIT=512M -PHP_MAX_EXECUTION_TIME=60 -PHP_OPCACHE_ENABLE=1 -PHP_OPCACHE_MEMORY_CONSUMPTION=128 -PHP_OPCACHE_MAX_ACCELERATED_FILES=10000 -PHP_OPCACHE_REVALIDATE_FREQ=2 -PHP_OPCACHE_VALIDATE_TIMESTAMPS=1 -PHP_ERROR_REPORTING=E_ALL -PHP_DISPLAY_ERRORS=0 -PHP_LOG_ERRORS=1 - -# Nginx Configuration (Staging) -NGINX_WORKER_PROCESSES=2 -NGINX_WORKER_CONNECTIONS=1536 -NGINX_KEEPALIVE_TIMEOUT=60 -NGINX_CLIENT_MAX_BODY_SIZE=25m - -# Database Performance (Staging) -MYSQL_INNODB_BUFFER_POOL_SIZE=512M -MYSQL_INNODB_LOG_FILE_SIZE=128M -MYSQL_MAX_CONNECTIONS=50 - -# Testing & Load Testing Configuration -K6_ENABLED=true -JAEGER_ENABLED=true -JAEGER_HOST=jaeger -JAEGER_PORT=14268 - -# Backup Configuration (Staging - Reduced) -BACKUP_ENABLED=true -BACKUP_SCHEDULE=0 3 * * 0 -BACKUP_RETENTION_DAYS=7 - -# SSL/TLS Configuration (Staging) -SSL_PROTOCOLS=TLSv1.2 TLSv1.3 -SSL_CIPHERS=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 -SSL_PREFER_SERVER_CIPHERS=off - -# Container User IDs (Staging) -UID=33 -GID=33 - -# Restart Policy (Staging) -RESTART_POLICY=unless-stopped - -# Resource Limits (Staging - Reduced) -PHP_MEMORY_LIMIT_DOCKER=768M -PHP_CPU_LIMIT=1.5 -NGINX_MEMORY_LIMIT_DOCKER=192M -NGINX_CPU_LIMIT=0.4 -DB_MEMORY_LIMIT_DOCKER=1G -DB_CPU_LIMIT=1.0 -REDIS_MEMORY_LIMIT_DOCKER=640M -REDIS_CPU_LIMIT=0.4 \ No newline at end of file diff --git a/deployment/infrastructure/playbooks/deploy-rsync-based.yml b/deployment/infrastructure/playbooks/deploy-rsync-based.yml index 4c818018..b5a8b59a 100644 --- a/deployment/infrastructure/playbooks/deploy-rsync-based.yml +++ b/deployment/infrastructure/playbooks/deploy-rsync-based.yml @@ -349,13 +349,20 @@ register: current_release_before - name: Stop existing Docker containers (if any) - command: docker compose down + command: docker compose -f docker-compose.yml -f docker-compose.production.yml down args: chdir: "{{ current_path }}" become_user: "{{ app_user }}" when: current_release_before.stat.exists ignore_errors: yes + - name: Remove any remaining containers (force cleanup all) + shell: | + docker stop certbot db redis php web queue-worker 2>/dev/null || true + docker rm certbot db redis php web queue-worker 2>/dev/null || true + become_user: "{{ app_user }}" + ignore_errors: yes + # ========================================== # 8. Symlink Switch (Zero-Downtime) # ========================================== diff --git a/docker-compose.production.yml b/docker-compose.production.yml index 22416f06..03c5ed5f 100644 --- a/docker-compose.production.yml +++ b/docker-compose.production.yml @@ -66,6 +66,11 @@ services: certbot: condition: service_started + # Networks must be explicitly defined to avoid override issues + networks: + - frontend + - backend + php: # Production restart policy restart: always @@ -124,6 +129,11 @@ services: # Mount .env file from shared directory (production environment variables) - /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro + # Networks must be explicitly defined to avoid override issues + networks: + - backend + - cache + db: # Production restart policy restart: always @@ -161,6 +171,10 @@ services: compress: "true" labels: "service,environment" + # Networks must be explicitly defined to avoid override issues + networks: + - backend + redis: # Production restart policy restart: always @@ -192,6 +206,10 @@ services: compress: "true" labels: "service,environment" + # Networks must be explicitly defined to avoid override issues + networks: + - cache + queue-worker: # Use same image as php service (has application code copied) image: framework-production-php @@ -203,10 +221,8 @@ services: # The entrypoint script will use gosu to switch to appuser after setup user: "root" - # Override entrypoint - use php image's entrypoint for proper setup - entrypoint: ["/usr/local/bin/docker-entrypoint.sh"] - - # Worker command - executed after entrypoint setup + # No entrypoint override - queue-worker runs worker.php directly + # Worker command - direct PHP execution command: ["php", "/var/www/html/worker.php"] # Production volumes @@ -215,6 +231,8 @@ services: - /home/deploy/michaelschiemer/current:/var/www/html:ro # Mount storage directory as writable volume (overlays the read-only code mount) - storage:/var/www/html/storage:rw + # Mount var directory as writable volume for cache and logs (overlays read-only code mount) + - var-data:/var/www/html/var:rw # Mount .env file from shared directory (production environment variables) - /home/deploy/michaelschiemer/shared/.env.production:/var/www/html/.env:ro @@ -248,6 +266,20 @@ services: # Graceful shutdown for long-running jobs stop_grace_period: 60s + # Wait for dependencies to be healthy before starting + depends_on: + db: + condition: service_healthy + redis: + condition: service_healthy + php: + condition: service_healthy + + # Networks must be explicitly defined to avoid override issues + networks: + - backend + - cache + # Certbot Sidecar Container for Let's Encrypt certbot: image: certbot/certbot:latest @@ -282,7 +314,7 @@ networks: driver: bridge backend: driver: bridge - internal: true # Backend network is internal (no internet access) + # NOTE: backend must NOT be internal - PHP needs to communicate with DB! cache: driver: bridge internal: true # Cache network is internal diff --git a/docker/postgres/postgresql.production.conf b/docker/postgres/postgresql.production.conf index d0eafca6..16f071fd 100644 --- a/docker/postgres/postgresql.production.conf +++ b/docker/postgres/postgresql.production.conf @@ -6,6 +6,9 @@ # CONNECTIONS AND AUTHENTICATION # ============================================================================ +# Listen on all network interfaces for Docker networking +listen_addresses = '*' + # Maximum number of concurrent connections max_connections = 100 diff --git a/final-test.txt b/final-test.txt deleted file mode 100644 index 5bf944fa..00000000 --- a/final-test.txt +++ /dev/null @@ -1 +0,0 @@ -final network test diff --git a/ip-test.txt b/ip-test.txt deleted file mode 100644 index 8b615aed..00000000 --- a/ip-test.txt +++ /dev/null @@ -1 +0,0 @@ -IP test diff --git a/src/Framework/Core/ContainerBootstrapper.php b/src/Framework/Core/ContainerBootstrapper.php index 6e6be60d..b88983cf 100644 --- a/src/Framework/Core/ContainerBootstrapper.php +++ b/src/Framework/Core/ContainerBootstrapper.php @@ -159,6 +159,27 @@ final readonly class ContainerBootstrapper return $request; }); + // TEMPORARY FIX: Manual DatabasePlatform binding until Initializer Discovery issue is resolved + $container->singleton(\App\Framework\Database\Platform\DatabasePlatform::class, function ($container) { + error_log("ContainerBootstrapper: Creating DatabasePlatform singleton"); + + $env = $container->get(\App\Framework\Config\Environment::class); + $driver = $env->get('DB_DRIVER', 'pgsql'); + + error_log("ContainerBootstrapper: DB_DRIVER = {$driver}"); + + $platform = match($driver) { + 'mysql', 'mysqli' => new \App\Framework\Database\Platform\MySQLPlatform(), + 'pgsql', 'postgres', 'postgresql' => new \App\Framework\Database\Platform\PostgreSQLPlatform(), + 'sqlite' => throw new \RuntimeException('SQLite platform not yet implemented'), + default => throw new \RuntimeException("Unsupported database driver: {$driver}") + }; + + error_log("ContainerBootstrapper: DatabasePlatform created: " . get_class($platform)); + + return $platform; + }); + } /** diff --git a/src/Framework/RateLimit/RateLimiterInitializer.php b/src/Framework/RateLimit/RateLimiterInitializer.php index f8fb98d0..36ed840b 100644 --- a/src/Framework/RateLimit/RateLimiterInitializer.php +++ b/src/Framework/RateLimit/RateLimiterInitializer.php @@ -15,21 +15,13 @@ final readonly class RateLimiterInitializer { public function __construct( private Container $container - ) { - } - - #[Initializer] - public function createStorageInterface(): StorageInterface - { - $cache = $this->container->get(Cache::class); - - return new CacheStorage($cache); - } + ) {} #[Initializer] public function createRateLimiter(): RateLimiter { - $storage = $this->container->get(StorageInterface::class); + $cache = $this->container->get(Cache::class); + $storage = new CacheStorage($cache); return new RateLimiter($storage); } diff --git a/src/Framework/RateLimit/Storage/CacheStorage.php b/src/Framework/RateLimit/Storage/CacheStorage.php index a468a283..2c767557 100644 --- a/src/Framework/RateLimit/Storage/CacheStorage.php +++ b/src/Framework/RateLimit/Storage/CacheStorage.php @@ -7,8 +7,10 @@ namespace App\Framework\RateLimit\Storage; use App\Framework\Cache\Cache; use App\Framework\Cache\CacheKey; use App\Framework\Core\ValueObjects\Duration; +use App\Framework\DI\Attributes\DefaultImplementation; use App\Framework\RateLimit\TokenBucket; +#[DefaultImplementation] final readonly class CacheStorage implements StorageInterface { public function __construct(