# Общая часть. Сверху накладывается: # локально — docker-compose.override.yml (подхватывается сам): сети паспорта и Kafka, порт WEB_PORT; # на сервере — docker-compose.prod.yml (COMPOSE_FILE в .env): HTTPS через Caddy. # Фронт, /api и /tiles открываются на одном адресе. services: # PostGIS под amd64 и arm64 (официальный postgis/postgis — только amd64, на Apple Silicon не запускается) db: image: imresamu/postgis:17-3.5-alpine3.21 container_name: patrol_db restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} ports: # Только с этой машины (psql, TablePlus через localhost). Снаружи база недоступна. - "${DB_BIND:-127.0.0.1}:${DB_PORT}:5432" volumes: - patrol_pgdata:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 20 # Хранилище фото и видео: SeaweedFS с S3 API (образы MinIO с Docker Hub удалены в сентябре 2026) s3: image: chrislusf/seaweedfs:4.47 container_name: patrol_s3 restart: unless-stopped entrypoint: ["weed"] command: ["server", "-dir=/data", "-s3", "-s3.port=8333"] environment: AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY} AWS_SECRET_ACCESS_KEY: ${S3_SECRET_KEY} volumes: - patrol_s3:/data # Подложка карты из ./tiles/kazakhstan.mbtiles (собирается scripts/build-tiles.sh) tiles: image: maptiler/tileserver-gl:latest container_name: patrol_tiles restart: on-failure:3 command: ["--file", "/data/kazakhstan.mbtiles", "--public_url", "/tiles/"] volumes: - ./tiles:/data api: build: context: . dockerfile: docker/api.Dockerfile container_name: patrol_api restart: unless-stopped depends_on: db: condition: service_healthy s3: condition: service_started environment: PORT: 3000 DB_HOST: db DB_PORT: 5432 POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} JWT_SECRET: ${JWT_SECRET} S3_ENDPOINT: http://s3:8333 S3_ACCESS_KEY: ${S3_ACCESS_KEY} S3_SECRET_KEY: ${S3_SECRET_KEY} S3_BUCKET: ${S3_BUCKET} # Паспорт Aspans и SSO Aspans ID (как PASSPORT_URL / PLATFORM_CODE / ASPANS_ID_* в symfony) PASSPORT_URL: ${PASSPORT_URL} PLATFORM_CODE: ${PLATFORM_CODE:-patrol} PASSPORT_PLATFORM_TOKEN: ${PASSPORT_PLATFORM_TOKEN} ASPANS_ID_BASE_URL: ${ASPANS_ID_BASE_URL:-} ASPANS_ID_CLIENT_SECRET: ${ASPANS_ID_CLIENT_SECRET:-} WEBSITE_URL: ${WEBSITE_URL:-} PLATFORM_ADMIN_USERNAMES: ${PLATFORM_ADMIN_USERNAMES:-admin} UCHET_KZ_TOKEN: ${UCHET_KZ_TOKEN:-} UCHET_KZ_DISABLED: ${UCHET_KZ_DISABLED:-false} NOMINATIM_URL: ${NOMINATIM_URL:-} NOMINATIM_EMAIL: ${NOMINATIM_EMAIL:-} GEOCODE_DISABLED: ${GEOCODE_DISABLED:-false} COOKIE_SECURE: ${COOKIE_SECURE:-false} # Синхронизация людей с паспортом через Kafka (aspans.users.changed): отправка правок и приём событий. # Профиль kafka, как у symfony: docker compose --profile kafka up -d users_sync users_sync: build: context: . dockerfile: docker/api.Dockerfile container_name: patrol_users_sync profiles: ['kafka'] restart: unless-stopped command: ['node', 'apps/api/dist/sync.js'] depends_on: db: condition: service_healthy api: condition: service_started environment: DB_HOST: db DB_PORT: 5432 POSTGRES_DB: ${POSTGRES_DB} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} JWT_SECRET: ${JWT_SECRET} PLATFORM_CODE: ${PLATFORM_CODE:-patrol} KAFKA_BROKERS: ${KAFKA_BROKERS:-} KAFKA_USERNAME: ${KAFKA_USERNAME:-} KAFKA_PASSWORD: ${KAFKA_PASSWORD:-} USERS_SYNC_TOPIC: ${USERS_SYNC_TOPIC:-aspans.users.changed} USERS_SYNC_SOURCE: ${USERS_SYNC_SOURCE:-platform-patrol} web: build: context: . dockerfile: docker/web.Dockerfile args: VITE_TILE_URL: ${VITE_TILE_URL} container_name: patrol_web restart: unless-stopped depends_on: - api volumes: patrol_pgdata: patrol_s3: