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

View File

@@ -0,0 +1,213 @@
# Base Docker Compose Configuration
# This file contains shared service definitions, networks, and volumes.
# Use with environment-specific override files:
# - docker-compose.local.yml (local development)
# - docker-compose.staging.yml (staging environment)
# - docker-compose.production.yml (production environment)
#
# Usage:
# Local: docker-compose -f docker-compose.base.yml -f docker-compose.local.yml up
# Staging: docker-compose -f docker-compose.base.yml -f docker-compose.staging.yml up
# Production: docker-compose -f docker-compose.base.yml -f docker-compose.production.yml up
services:
web:
build:
context: docker/nginx
dockerfile: Dockerfile
healthcheck:
test: ["CMD", "nc", "-z", "127.0.0.1", "443"]
interval: 30s
timeout: 10s
retries: 3
depends_on:
php:
condition: service_started
networks:
- frontend
- backend
php:
build:
context: .
dockerfile: docker/php/Dockerfile
args:
- ENV=${APP_ENV:-dev}
- COMPOSER_INSTALL_FLAGS=${COMPOSER_INSTALL_FLAGS:---no-scripts --no-autoloader}
healthcheck:
test: [ "CMD", "php", "-v" ]
interval: 30s
timeout: 10s
retries: 3
networks:
- backend
- cache
volumes:
# Shared Volume für Composer-Cache über Container-Neustarts hinweg
- composer-cache:/root/.composer/cache
# Docker-Volumes für Performance (keine Host-Sync nötig)
- storage-cache:/var/www/html/storage/cache:rw
- storage-queue:/var/www/html/storage/queue:rw
- storage-discovery:/var/www/html/storage/discovery:rw
- var-data:/var/www/html/var:rw
php-test:
build:
context: .
dockerfile: docker/php/Dockerfile.test
user: "1000:1000"
profiles:
- test
volumes:
- composer-cache:/home/appuser/.composer/cache
- storage-cache:/var/www/html/storage/cache:rw
- storage-queue:/var/www/html/storage/queue:rw
- storage-discovery:/var/www/html/storage/discovery:rw
- var-data:/var/www/html/var:rw
environment:
APP_ENV: testing
APP_DEBUG: true
DB_HOST: db
REDIS_HOST: redis
networks:
- backend
- cache
entrypoint: []
command: ["php", "-v"]
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: ${DB_DATABASE:-michaelschiemer}
POSTGRES_USER: ${DB_USERNAME:-postgres}
# SECURITY: POSTGRES_PASSWORD must be set explicitly (no hardcoded fallback)
# Set DB_PASSWORD in .env.local for local development
# Use Docker Secrets in production/staging via DB_PASSWORD_FILE
POSTGRES_PASSWORD: ${DB_PASSWORD}
# Performance & Connection Settings
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- db_data:/var/lib/postgresql/data
- "${DB_CONFIG_PATH:-./docker/postgres/postgresql.conf}:/etc/postgresql/postgresql.conf:ro"
- "${DB_INIT_PATH:-./docker/postgres/init}:/docker-entrypoint-initdb.d:ro"
command:
- "postgres"
- "-c"
- "config_file=/etc/postgresql/postgresql.conf"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-postgres} -d ${DB_DATABASE:-michaelschiemer}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- backend
redis:
image: redis:7-alpine
volumes:
- "${REDIS_CONFIG_PATH:-./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: 30s
networks:
- cache
queue-worker:
build:
context: .
dockerfile: docker/worker/Dockerfile
entrypoint: "" # Override any entrypoint
command: ["php", "/var/www/html/worker.php"] # Direct command execution
depends_on:
php:
condition: service_healthy
redis:
condition: service_healthy
db:
condition: service_healthy
volumes:
# Use same storage volumes as PHP container for consistency
- storage-cache:/var/www/html/storage/cache:rw
- storage-queue:/var/www/html/storage/queue:rw
- storage-discovery:/var/www/html/storage/discovery:rw
- var-data:/var/www/html/var:rw
networks:
- backend
- cache
# Graceful shutdown timeout
stop_grace_period: 30s
minio:
image: minio/minio:latest
environment:
- TZ=Europe/Berlin
# SECURITY: MINIO credentials must be set explicitly (no hardcoded fallback)
# Set MINIO_ROOT_USER and MINIO_ROOT_PASSWORD in .env.local for local development
# Use Docker Secrets in production/staging for production deployments
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
command: server /data --console-address ":9001"
volumes:
- minio_data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
cache:
driver: bridge
volumes:
redis_data:
composer-cache:
storage-cache: # Cache-Verzeichnis (Performance-kritisch)
storage-queue: # Queue-Verzeichnis (Performance-kritisch)
storage-discovery: # Discovery-Cache (Framework-intern)
var-data:
db_data:
project-data:
worker-logs:
worker-queue:
worker-storage: # Complete separate storage for worker with correct permissions
minio_data: # MinIO object storage data
# Docker Secrets Configuration
# Secrets are defined here but activated in environment-specific override files
secrets:
db_root_password:
file: ./secrets/db_root_password.txt
external: false
db_user_password:
file: ./secrets/db_user_password.txt
external: false
redis_password:
file: ./secrets/redis_password.txt
external: false
app_key:
file: ./secrets/app_key.txt
external: false
vault_encryption_key:
file: ./secrets/vault_encryption_key.txt
external: false
git_token:
file: ./secrets/git_token.txt
external: false

View File

@@ -25,11 +25,16 @@ services:
- DB_PORT=${DB_PORT:-5432}
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
- DB_PASSWORD_FILE=/run/secrets/db_user_password
# Redis
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD}
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
- REDIS_PASSWORD_FILE=/run/secrets/redis_password
secrets:
- db_user_password
- redis_password
# Cache
- CACHE_DRIVER=redis
- CACHE_PREFIX=${CACHE_PREFIX:-app}
@@ -181,22 +186,24 @@ services:
- app-internal
environment:
- TZ=Europe/Berlin
secrets:
- redis_password
command: >
redis-server
--requirepass ${REDIS_PASSWORD}
sh -c "redis-server
--requirepass $$(cat /run/secrets/redis_password)
--maxmemory 512mb
--maxmemory-policy allkeys-lru
--save 900 1
--save 300 10
--save 60 10000
--appendonly yes
--appendfsync everysec
--appendfsync everysec"
volumes:
- redis-data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
test: ["CMD", "sh", "-c", "redis-cli --no-auth-warning -a $$(cat /run/secrets/redis_password) ping"]
interval: 30s
timeout: 10s
retries: 3
@@ -218,11 +225,16 @@ services:
- DB_PORT=${DB_PORT:-5432}
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
- DB_PASSWORD_FILE=/run/secrets/db_user_password
# Redis
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD}
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
- REDIS_PASSWORD_FILE=/run/secrets/redis_password
secrets:
- db_user_password
- redis_password
# Queue
- QUEUE_DRIVER=redis
- QUEUE_CONNECTION=default
@@ -234,6 +246,9 @@ services:
- app-logs:/var/www/html/storage/logs
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
secrets:
- db_user_password
- redis_password
command: php console.php queue:work --queue=default --timeout=${QUEUE_WORKER_TIMEOUT:-60}
healthcheck:
test: ["CMD-SHELL", "php -r 'exit(0);' && test -f /var/www/html/console.php || exit 1"]
@@ -263,11 +278,16 @@ services:
- DB_PORT=${DB_PORT:-5432}
- DB_DATABASE=${DB_DATABASE}
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
- DB_PASSWORD_FILE=/run/secrets/db_user_password
# Redis
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=${REDIS_PASSWORD}
# Use Docker Secrets via *_FILE pattern (Framework supports this automatically)
- REDIS_PASSWORD_FILE=/run/secrets/redis_password
secrets:
- db_user_password
- redis_password
volumes:
- app-storage:/var/www/html/storage
- app-logs:/var/www/html/storage/logs
@@ -300,6 +320,12 @@ volumes:
name: redis-data
external: true
secrets:
db_user_password:
file: ./secrets/db_user_password.txt
redis_password:
file: ./secrets/redis_password.txt
networks:
traefik-public:
external: true