# Coolify Docker Compose deployment for fleet-platform. # # Three services from one image, selected by APP_ROLE: # gateway — HTTP: push receivers + dashboard read API + JWT issuance (exposes 8000) # worker — LISTEN parser → projectors # cron — APScheduler: polled ingest, SLO measurement, contract checker # # Coolify-specific notes: # - Domain for `gateway` (api.rahamafresh.com) is configured via the # Coolify UI → Application → Settings → Domains. Coolify generates the # Traefik labels automatically; don't add them here. # - All env values live in Coolify's Environment Variables panel. # Compose only references them with ${VAR_NAME}. # - Coolify will clone this repo, build the image once, and re-use it # across all three services (saves disk + build time). # - `coolify` network is created by Coolify; we attach so containers can # reach the TimescaleDB by service name. # The TimescaleDB this app talks to lives in another Coolify project # (its compose network is `bo3nov2ija7g8wn9b1g2paxs`). The DB container # has the alias `timescale_db` ONLY on that network, so we attach all # three services to it as an external network — that's what makes the # DATABASE_URL `postgresql://...@timescale_db:5432/fleet_platform` work. # # If/when the DB project is re-created with a different network UUID, # update the name here OR migrate the DB onto the shared `coolify` net. networks: db_project: name: bo3nov2ija7g8wn9b1g2paxs external: true services: gateway: build: . image: fleet-platform:${COOLIFY_RESOURCE_UUID:-latest} restart: unless-stopped networks: - default - db_project environment: APP_ROLE: gateway APP_MODE: prod APP_LOG_LEVEL: INFO APP_GIT_SHA: ${SOURCE_COMMIT:-unknown} DATABASE_URL: ${DATABASE_URL} JWT_SECRET: ${JWT_SECRET} JWT_ACCESS_TTL_MIN: ${JWT_ACCESS_TTL_MIN:-15} JWT_REFRESH_TTL_DAYS: ${JWT_REFRESH_TTL_DAYS:-30} TRACKSOLID_API_BASE_URL: ${TRACKSOLID_API_BASE_URL} TRACKSOLID_PUSH_TOKEN: ${TRACKSOLID_PUSH_TOKEN} NOMINATIM_BASE_URL: ${NOMINATIM_BASE_URL:-} MAPBOX_TOKEN: ${MAPBOX_TOKEN:-} expose: - "8000" healthcheck: test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/health/gateway"] interval: 15s timeout: 3s retries: 3 start_period: 10s worker: image: fleet-platform:${COOLIFY_RESOURCE_UUID:-latest} restart: unless-stopped depends_on: gateway: condition: service_started networks: - default - db_project environment: APP_ROLE: worker APP_MODE: prod APP_LOG_LEVEL: INFO APP_GIT_SHA: ${SOURCE_COMMIT:-unknown} DATABASE_URL: ${DATABASE_URL} JWT_SECRET: ${JWT_SECRET} TRACKSOLID_API_BASE_URL: ${TRACKSOLID_API_BASE_URL} TRACKSOLID_PUSH_TOKEN: ${TRACKSOLID_PUSH_TOKEN} NOMINATIM_BASE_URL: ${NOMINATIM_BASE_URL:-} healthcheck: test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/health/worker"] interval: 15s timeout: 3s retries: 3 start_period: 10s cron: image: fleet-platform:${COOLIFY_RESOURCE_UUID:-latest} restart: unless-stopped depends_on: gateway: condition: service_started networks: - default - db_project environment: APP_ROLE: cron APP_MODE: prod APP_LOG_LEVEL: INFO APP_GIT_SHA: ${SOURCE_COMMIT:-unknown} DATABASE_URL: ${DATABASE_URL} JWT_SECRET: ${JWT_SECRET} TRACKSOLID_API_BASE_URL: ${TRACKSOLID_API_BASE_URL} TRACKSOLID_PUSH_TOKEN: ${TRACKSOLID_PUSH_TOKEN} TRACKSOLID_APP_KEY: ${TRACKSOLID_APP_KEY} TRACKSOLID_APP_SECRET: ${TRACKSOLID_APP_SECRET} TRACKSOLID_USER_ID: ${TRACKSOLID_USER_ID} TRACKSOLID_PWD_MD5: ${TRACKSOLID_PWD_MD5} TRACKSOLID_TARGETS: ${TRACKSOLID_TARGETS} TRACKSOLID_POLL_INTERVAL_SEC: ${TRACKSOLID_POLL_INTERVAL_SEC:-60} TRACKSOLID_STALE_POLL_INTERVAL_SEC: ${TRACKSOLID_STALE_POLL_INTERVAL_SEC:-600} TRACKSOLID_STALE_AFTER_SEC: ${TRACKSOLID_STALE_AFTER_SEC:-1800} NOMINATIM_BASE_URL: ${NOMINATIM_BASE_URL:-} GEOCODER_TICK_SEC: ${GEOCODER_TICK_SEC:-30} healthcheck: test: ["CMD", "curl", "-fsS", "http://127.0.0.1:8000/health/cron"] interval: 15s timeout: 3s retries: 3 start_period: 10s