x-app-env: &app-env APP_NAME: ${APP_NAME:-Fotospiel} APP_ENV: ${APP_ENV:-production} APP_DEBUG: ${APP_DEBUG:-false} APP_URL: ${APP_URL} APP_KEY: ${APP_KEY} LOG_CHANNEL: stack LOG_LEVEL: ${LOG_LEVEL:-info} DB_CONNECTION: mysql DB_HOST: mysql DB_PORT: 3306 DB_DATABASE: ${DB_DATABASE} DB_USERNAME: ${DB_USERNAME} DB_PASSWORD: ${DB_PASSWORD} DB_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} REDIS_HOST: redis REDIS_PASSWORD: ${REDIS_PASSWORD} REDIS_PORT: 6379 QUEUE_CONNECTION: ${QUEUE_CONNECTION:-redis} CACHE_DRIVER: ${CACHE_DRIVER:-redis} SESSION_DRIVER: ${SESSION_DRIVER:-redis} BROADCAST_DRIVER: log FILESYSTEM_DISK: ${FILESYSTEM_DISK:-local-ssd} STORAGE_ALERT_EMAIL: ${STORAGE_ALERT_EMAIL:-} x-app-build: &app-build context: . dockerfile: Dockerfile target: app args: PHP_VERSION: ${PHP_VERSION:-8.3} NODE_VERSION: ${NODE_VERSION:-20} cache_from: - type=registry,ref=${APP_IMAGE_CACHE:-fotospiel-app:buildcache} cache_to: - type=registry,ref=${APP_IMAGE_CACHE:-fotospiel-app:buildcache},mode=max services: app: build: *app-build image: registry.internal:5443/${APP_IMAGE:-fotospiel-app:latest} env_file: - path: .env environment: <<: *app-env APP_SOURCE: /opt/app APP_TARGET: /var/www/html APP_USER: www-data APP_GROUP: www-data volumes: - app-code:/var/www/html - app-storage:/var/www/html/storage - app-bootstrap-cache:/var/www/html/bootstrap/cache - photobooth-import:/var/www/html/storage/app/photobooth depends_on: mysql: condition: service_healthy redis: condition: service_started healthcheck: test: - CMD - php - -r - "exit(file_exists('/var/www/html/vendor/autoload.php') ? 0 : 1);" interval: 15s timeout: 5s retries: 5 start_period: 30s restart: unless-stopped docs-build: image: node:20 working_dir: /var/www/html/docs/site command: - bash - -lc - npm ci && npm run build volumes: - app-code:/var/www/html env_file: - path: .env depends_on: app: condition: service_healthy restart: "no" web: image: nginx:1.27-alpine depends_on: docs-build: condition: service_completed_successfully app: condition: service_healthy labels: - traefik.enable=true - traefik.http.middlewares.fotospiel-https-redirect.redirectscheme.scheme=https - traefik.http.routers.fotospiel-http.rule=Host(`test-y0k0.fotospiel.app`) - traefik.http.routers.fotospiel-http.entrypoints=web - traefik.http.routers.fotospiel-http.middlewares=fotospiel-https-redirect - traefik.http.routers.fotospiel-https.rule=Host(`test-y0k0.fotospiel.app`) - traefik.http.routers.fotospiel-https.entrypoints=websecure - traefik.http.routers.fotospiel-https.tls=true - traefik.http.routers.fotospiel-https.service=fotospiel-web - traefik.http.services.fotospiel-web.loadbalancer.server.port=80 - traefik.docker.network=dokploy-network volumes: - app-code:/var/www/html:ro - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro - ./docs/site/build:/var/www/docs-site:ro - ./docker/nginx/.htpasswd-docs:/etc/nginx/.htpasswd-docs:ro env_file: - path: .env networks: - default - dokploy-network restart: unless-stopped photobooth-ftp: image: delfer/alpine-ftp-server:latest env_file: - path: .env environment: USERS: ${PHOTOBOOTH_FTP_USERS:-seed|changeme|/home/ftpusers/photobooth} ADDRESS: ${PHOTOBOOTH_FTP_ADDRESS:-test-y0k0.fotospiel.app} MIN_PORT: ${PHOTOBOOTH_FTP_PASV_MIN_PORT:-30000} MAX_PORT: ${PHOTOBOOTH_FTP_PASV_MAX_PORT:-30009} volumes: - photobooth-import:/home/ftpusers/photobooth ports: - "${PHOTOBOOTH_FTP_PORT:-2121}:21" - "${PHOTOBOOTH_FTP_PASV_MIN_PORT:-30000}-${PHOTOBOOTH_FTP_PASV_MAX_PORT:-30009}:${PHOTOBOOTH_FTP_PASV_MIN_PORT:-30000}-${PHOTOBOOTH_FTP_PASV_MAX_PORT:-30009}" networks: - dokploy-network healthcheck: test: ["CMD", "nc", "-z", "localhost", "21"] interval: 30s timeout: 10s retries: 5 restart: unless-stopped queue: image: registry.internal:5443/${APP_IMAGE:-fotospiel-app:latest} env_file: - path: .env command: /var/www/html/scripts/queue-worker.sh default environment: <<: *app-env SKIP_CODE_SYNC: "1" volumes: - app-code:/var/www/html - app-storage:/var/www/html/storage - app-bootstrap-cache:/var/www/html/bootstrap/cache depends_on: app: condition: service_healthy redis: condition: service_started restart: unless-stopped media-storage-worker: image: registry.internal:5443/${APP_IMAGE:-fotospiel-app:latest} env_file: - path: .env command: /var/www/html/scripts/queue-worker.sh media-storage environment: <<: *app-env QUEUE_TRIES: 5 QUEUE_SLEEP: 5 SKIP_CODE_SYNC: "1" volumes: - app-code:/var/www/html - app-storage:/var/www/html/storage - app-bootstrap-cache:/var/www/html/bootstrap/cache depends_on: app: condition: service_healthy redis: condition: service_started restart: unless-stopped scheduler: image: registry.internal:5443/${APP_IMAGE:-fotospiel-app:latest} env_file: - path: .env command: php artisan schedule:work environment: <<: *app-env SKIP_CODE_SYNC: "1" volumes: - app-code:/var/www/html - app-storage:/var/www/html/storage - app-bootstrap-cache:/var/www/html/bootstrap/cache - photobooth-import:/var/www/html/storage/app/photobooth depends_on: app: condition: service_healthy restart: unless-stopped horizon: image: registry.internal:5443/${APP_IMAGE:-fotospiel-app:latest} env_file: - path: .env command: /var/www/html/scripts/horizon.sh environment: <<: *app-env SKIP_CODE_SYNC: "1" volumes: - app-code:/var/www/html - app-storage:/var/www/html/storage - app-bootstrap-cache:/var/www/html/bootstrap/cache depends_on: app: condition: service_healthy redis: condition: service_started restart: unless-stopped redis: image: redis:7.4-alpine command: - redis-server - "--save" - "" - "--appendonly" - "no" - "--requirepass" - "${REDIS_PASSWORD}" volumes: - redis-data:/data restart: unless-stopped mysql: image: mysql:8.4 environment: MYSQL_DATABASE: ${DB_DATABASE} MYSQL_USER: ${DB_USERNAME} MYSQL_PASSWORD: ${DB_PASSWORD} MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} volumes: - mysql-data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "-p${DB_PASSWORD}"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped volumes: app-code: app-storage: app-bootstrap-cache: photobooth-import: mysql-data: redis-data: networks: dokploy-network: external: true