services: caddy: image: caddy:2-alpine container_name: px360_caddy restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./Caddyfile.prod:/etc/caddy/Caddyfile:ro - caddy_data:/data - caddy_config:/config - static_volume:/srv/static - media_volume:/srv/media depends_on: web: condition: service_healthy networks: - px360_net logging: driver: json-file options: max-size: "10m" max-file: "3" web: image: ${PX360_IMAGE:-gitea.tenhal.sa/marwan/hh:latest} container_name: px360_web restart: unless-stopped volumes: - static_volume:/app/staticfiles - media_volume:/app/media env_file: - .env.production depends_on: redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health/"] interval: 30s timeout: 10s retries: 3 start_period: 60s networks: - px360_net logging: driver: json-file options: max-size: "10m" max-file: "3" celery: image: ${PX360_IMAGE:-gitea.tenhal.sa/marwan/hh:latest} container_name: px360_celery restart: unless-stopped command: celery -A config worker -l info --concurrency=4 env_file: - .env.production depends_on: web: condition: service_healthy networks: - px360_net logging: driver: json-file options: max-size: "10m" max-file: "3" celery-beat: image: ${PX360_IMAGE:-gitea.tenhal.sa/marwan/hh:latest} container_name: px360_celery_beat restart: unless-stopped command: celery -A config beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler env_file: - .env.production depends_on: web: condition: service_healthy networks: - px360_net logging: driver: json-file options: max-size: "10m" max-file: "3" redis: image: redis:7-alpine container_name: px360_redis restart: unless-stopped volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 networks: - px360_net volumes: redis_data: static_volume: media_volume: caddy_data: caddy_config: networks: px360_net: driver: bridge