# Clusev — PROD stack. Plain Docker Compose, no Portainer. # Image from GHCR (set GHCR_OWNER + IMAGE_TAG in .env), or build on the VM: # docker compose -f docker-compose.prod.yml build # Deploy: # docker compose -f docker-compose.prod.yml pull # docker compose -f docker-compose.prod.yml up -d # docker compose -f docker-compose.prod.yml exec app php artisan migrate --force name: clusev x-image: &image image: "ghcr.io/${GHCR_OWNER:-OWNER}/clusev:${IMAGE_TAG:-latest}" restart: unless-stopped env_file: - .env networks: - clusev services: app: <<: *image build: context: . dockerfile: Dockerfile target: prod ports: - "${APP_PORT:-80}:80" depends_on: mariadb: condition: service_healthy redis: condition: service_started reverb: <<: *image command: php artisan reverb:start --host=0.0.0.0 --port=8080 ports: - "${REVERB_HOST_PORT:-8080}:8080" depends_on: redis: condition: service_started queue: <<: *image command: php artisan queue:work --tries=3 --timeout=90 --sleep=1 depends_on: mariadb: condition: service_healthy redis: condition: service_started mariadb: image: mariadb:11 restart: unless-stopped environment: MARIADB_DATABASE: "${DB_DATABASE:-clusev}" MARIADB_USER: "${DB_USERNAME:-clusev}" MARIADB_PASSWORD: "${DB_PASSWORD:?set DB_PASSWORD in .env}" MARIADB_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:?set DB_ROOT_PASSWORD in .env}" volumes: - mariadb-data:/var/lib/mysql healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s timeout: 5s retries: 30 networks: - clusev redis: image: redis:7-alpine restart: unless-stopped command: redis-server --appendonly yes volumes: - redis-data:/data networks: - clusev volumes: mariadb-data: redis-data: networks: clusev: driver: bridge