Spaces:
Sleeping
Sleeping
| # docker-compose.yml (repo root) | |
| # ---------------------------------------------------------------------- | |
| # Local DEV environment for arac-hasar-v2. | |
| # | |
| # What it brings up: | |
| # - backend (FastAPI, hot-reload, mounts ./services/backend:/app) | |
| # - worker (Celery, same image) | |
| # - postgres 16 | |
| # - redis 7 | |
| # - minio + minio-init (S3-mock, bucket auto-created) | |
| # | |
| # What it does NOT bring up (run with pnpm dev): | |
| # - apps/web -> cd apps/web && pnpm dev (port 3000) | |
| # - apps/mobile -> cd apps/mobile && pnpm start | |
| # - apps/desktop -> cd apps/desktop && pnpm tauri dev | |
| # | |
| # Quick start: | |
| # docker compose up -d postgres redis minio minio-init | |
| # docker compose up backend worker # foreground, see logs | |
| # | |
| # For the full GPU/CUDA compose with bundled web container, | |
| # see services/backend/docker-compose.yml. | |
| # ---------------------------------------------------------------------- | |
| name: arac-hasar-v2-dev | |
| services: | |
| backend: | |
| build: | |
| context: ./services/backend | |
| dockerfile: Dockerfile | |
| image: hasarui-api:dev | |
| container_name: hasarui-backend | |
| # NOTE: --reload-exclude tames watchfiles churn from ML shim copies, | |
| # __pycache__ writes, training log spew, and visualization PNGs that | |
| # otherwise trigger a uvicorn restart loop in dev. | |
| command: ["sh", "-c", "uvicorn main:app --host 0.0.0.0 --port 8000 --reload --reload-dir /app --reload-exclude '*.log' --reload-exclude '*.png' --reload-exclude '*.jpg' --reload-exclude '__pycache__/*' --reload-exclude 'tests/*' --reload-exclude 'migrations/versions/*'"] | |
| ports: | |
| - "8000:8000" | |
| env_file: | |
| - ./services/backend/.env | |
| environment: | |
| # Override URLs to point to compose service names | |
| DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/arac_hasar" | |
| REDIS_URL: "redis://redis:6379/0" | |
| S3_ENDPOINT: "http://minio:9000" | |
| S3_ACCESS_KEY: "minioadmin" | |
| S3_SECRET_KEY: "minioadmin" | |
| S3_BUCKET: "inspections" | |
| S3_REGION: "us-east-1" | |
| ML_DEVICE: "cpu" | |
| # Entrypoint skips S3 model fetch — we mount weights as a volume. | |
| SKIP_MODEL_FETCH: "1" | |
| RUN_MIGRATIONS: "1" | |
| ENVIRONMENT: "development" | |
| # Web (3000), Tauri desktop dev (1420) + prod webview origins, Expo mobile (8081) | |
| CORS_ORIGINS: "http://localhost:3000,http://localhost:1420,http://tauri.localhost,tauri://localhost,http://localhost:8081" | |
| # Single-source ML modules: services/ml/ mounted read-only at /app/ml. | |
| # PYTHONPATH includes /app/ml so `from pipeline import DamagePipeline` | |
| # resolves to services/ml/pipeline.py without scripts/prepare-ml-shim.* | |
| # having to copy files into services/backend/. /app still takes | |
| # priority — backend-local override remains possible during a cutover. | |
| PYTHONPATH: "/app:/app/ml" | |
| volumes: | |
| # Hot-reload: source mounted on top of image | |
| - ./services/backend:/app | |
| # ML single-source mount: services/ml/ read-only at /app/ml. | |
| # Eliminates services/backend/pipeline.py drift vs services/ml/pipeline.py. | |
| # prepare-ml-shim.{sh,ps1} is now only needed for the PRODUCTION docker | |
| # build (CI bakes files in); dev runs straight off this mount. | |
| # NOT: pretrained/ alt klasoru runtime'da yazilabilir (model_manager | |
| # download bir kez .pt indirir, sonraki boot'larda cache hit). Kalan | |
| # services/ml/ icerigi kod ve egitim verisi — dev'de read-write OK. | |
| - ./services/ml:/app/ml | |
| # Local model weights for dev (point at your snapshot dir or symlink). | |
| # If this path is missing, run: | |
| # $env:MODEL_SNAPSHOT_DIR = "<absolute path to latest snapshot>" | |
| # or edit the path below to the latest run under services/ml/runs/bundles/. | |
| - ${MODEL_SNAPSHOT_DIR:-./services/ml/runs/bundles/full_20260515_044630/_SNAPSHOT_FOR_BUILD}:/app/models:ro | |
| networks: | |
| - hasarui-net | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| minio-init: | |
| condition: service_completed_successfully | |
| logging: | |
| driver: json-file | |
| options: | |
| max-size: "10m" | |
| max-file: "3" | |
| # Dev guardrail. Observed peak ~1.7 GiB (uvicorn 2 workers + YOLO ensemble | |
| # + cv2/numpy + torch CPU). Render starter (512 MB) is undersized — we | |
| # have to deploy on standard (2 GB) or trim to a single uvicorn worker | |
| # + lazy model load. NOT mirrored to render.yaml in this change. | |
| deploy: | |
| resources: | |
| limits: | |
| memory: 3G | |
| cpus: "4.0" | |
| reservations: | |
| memory: 1G | |
| restart: unless-stopped | |
| worker: | |
| build: | |
| context: ./services/backend | |
| dockerfile: Dockerfile | |
| image: hasarui-api:dev | |
| container_name: hasarui-worker | |
| command: ["sh", "-c", "celery -A worker.celery_app worker --loglevel=info --concurrency=1"] | |
| env_file: | |
| - ./services/backend/.env | |
| environment: | |
| DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/arac_hasar" | |
| REDIS_URL: "redis://redis:6379/0" | |
| S3_ENDPOINT: "http://minio:9000" | |
| S3_ACCESS_KEY: "minioadmin" | |
| S3_SECRET_KEY: "minioadmin" | |
| S3_BUCKET: "inspections" | |
| S3_REGION: "us-east-1" | |
| ML_DEVICE: "cpu" | |
| SKIP_MODEL_FETCH: "1" | |
| RUN_MIGRATIONS: "0" | |
| ENVIRONMENT: "development" | |
| CORS_ORIGINS: "http://localhost:3000,http://localhost:1420,http://tauri.localhost,tauri://localhost,http://localhost:8081" | |
| # Celery prefork spawn temizler sys.path '' entry'sini; explicit PYTHONPATH | |
| # zorunlu — yoksa worker `from pipeline import DamagePipeline` başarısız. | |
| # /app/ml eklendi: services/ml/ tek-kaynak modülleri (pipeline.py vb.) | |
| PYTHONPATH: "/app:/app/ml" | |
| volumes: | |
| - ./services/backend:/app | |
| # Worker da ML modüllerini aynı tek-kaynak mount'tan okur. | |
| # NOT: pretrained/ alt klasoru runtime'da yazilabilir (model_manager | |
| # download bir kez .pt indirir, sonraki boot'larda cache hit). Kalan | |
| # services/ml/ icerigi kod ve egitim verisi — dev'de read-write OK. | |
| - ./services/ml:/app/ml | |
| - ${MODEL_SNAPSHOT_DIR:-./services/ml/runs/bundles/full_20260515_044630/_SNAPSHOT_FOR_BUILD}:/app/models:ro | |
| networks: | |
| - hasarui-net | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| redis: | |
| condition: service_healthy | |
| minio-init: | |
| condition: service_completed_successfully | |
| backend: | |
| condition: service_started | |
| # Override Dockerfile's HTTP /health check — worker has no HTTP server. | |
| # Use Celery's own broker ping (returns "pong" from each running worker). | |
| healthcheck: | |
| test: ["CMD-SHELL", "celery -A worker.celery_app inspect ping -d celery@$$HOSTNAME -t 5 || exit 1"] | |
| interval: 30s | |
| timeout: 10s | |
| retries: 3 | |
| start_period: 30s | |
| logging: | |
| driver: json-file | |
| options: | |
| max-size: "10m" | |
| max-file: "3" | |
| # Worker ensemble inference 12 foto için peak ~2 GiB gözlemlendi. | |
| # Concurrency=1 ile zaten serialize ediyoruz; 3 GiB tampon yeterli. | |
| deploy: | |
| resources: | |
| limits: | |
| memory: 3G | |
| cpus: "4.0" | |
| reservations: | |
| memory: 1G | |
| restart: unless-stopped | |
| postgres: | |
| image: postgres:16-alpine | |
| container_name: hasarui-postgres | |
| environment: | |
| POSTGRES_USER: postgres | |
| POSTGRES_PASSWORD: postgres | |
| POSTGRES_DB: arac_hasar | |
| ports: | |
| - "5432:5432" | |
| volumes: | |
| - pg_data:/var/lib/postgresql/data | |
| healthcheck: | |
| test: ["CMD-SHELL", "pg_isready -U postgres -d arac_hasar"] | |
| interval: 5s | |
| timeout: 5s | |
| retries: 10 | |
| start_period: 10s | |
| networks: | |
| - hasarui-net | |
| logging: | |
| driver: json-file | |
| options: | |
| max-size: "10m" | |
| max-file: "3" | |
| restart: unless-stopped | |
| redis: | |
| image: redis:7-alpine | |
| container_name: hasarui-redis | |
| command: ["redis-server", "--appendonly", "yes", "--save", "60", "1"] | |
| ports: | |
| - "6379:6379" | |
| volumes: | |
| - redis_data:/data | |
| healthcheck: | |
| test: ["CMD", "redis-cli", "ping"] | |
| interval: 5s | |
| timeout: 3s | |
| retries: 5 | |
| networks: | |
| - hasarui-net | |
| logging: | |
| driver: json-file | |
| options: | |
| max-size: "10m" | |
| max-file: "3" | |
| restart: unless-stopped | |
| minio: | |
| image: minio/minio:latest | |
| container_name: hasarui-minio | |
| command: ["server", "/data", "--console-address", ":9001"] | |
| environment: | |
| MINIO_ROOT_USER: minioadmin | |
| MINIO_ROOT_PASSWORD: minioadmin | |
| ports: | |
| - "9000:9000" # S3 API | |
| - "9001:9001" # Web console -> http://localhost:9001 | |
| volumes: | |
| - minio_data:/data | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] | |
| interval: 10s | |
| timeout: 5s | |
| retries: 5 | |
| start_period: 10s | |
| networks: | |
| - hasarui-net | |
| logging: | |
| driver: json-file | |
| options: | |
| max-size: "10m" | |
| max-file: "3" | |
| restart: unless-stopped | |
| minio-init: | |
| image: minio/mc:latest | |
| container_name: hasarui-minio-init | |
| depends_on: | |
| minio: | |
| condition: service_healthy | |
| networks: | |
| - hasarui-net | |
| # Idempotent: --ignore-existing makes mb / anonymous safe to re-run. | |
| entrypoint: | |
| - /bin/sh | |
| - -c | |
| - | | |
| set -e | |
| until mc alias set local http://minio:9000 minioadmin minioadmin >/dev/null 2>&1; do | |
| echo "minio-init: waiting for minio..." | |
| sleep 1 | |
| done | |
| mc mb --ignore-existing local/inspections | |
| mc mb --ignore-existing local/models | |
| mc anonymous set download local/inspections || true | |
| echo "MinIO buckets ready: inspections, models" | |
| restart: "no" | |
| networks: | |
| hasarui-net: | |
| driver: bridge | |
| volumes: | |
| pg_data: | |
| redis_data: | |
| minio_data: | |