# 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