services: postgres: image: postgis/postgis:17-3.5 environment: POSTGRES_DB: ulhub POSTGRES_USER: ulhub POSTGRES_PASSWORD: development volumes: - postgres-data:/var/lib/postgresql/data mosquitto: image: eclipse-mosquitto:2 ports: - "1883:1883" - "8883:8883" - "8884:8884" volumes: - ./mosquitto:/mosquitto backend: build: context: ./backend dockerfile: Dockerfile ports: - "3001:3001" depends_on: - postgres - mosquitto # Development mounts: mount source for hot-reload and keep container node_modules volumes: - ./backend:/usr/src/app:delegated - /usr/src/app/node_modules - ./mosquitto/certs:/mosquitto-certs environment: DATABASE_URL: postgresql://ulhub:development@postgres:5432/ulhub JWT_SECRET: ${JWT_SECRET:-dev-only-insecure-secret} MQTT_HOST: mosquitto MQTT_PORT: 1883 MQTT_USERNAME: ${MQTT_BACKEND_USERNAME:-backend} MQTT_PASSWORD: ${MQTT_BACKEND_PASSWORD:?set MQTT_BACKEND_PASSWORD} MQTT_CERTS_DIR: /mosquitto-certs MQTT_TLS_PORT: 8883 # Must match the CN the broker's server cert was provisioned for # (Settings → MQTT Certs), not this container's docker-network hostname — # used by the simulator's MQTTS transport to verify the broker's identity. MQTT_TLS_SERVERNAME: ${MQTT_TLS_SERVERNAME:-localhost} # BLE challenge-response session certs (backend/src/device-mqtt-auth): # how long a nonce is redeemable for, and how long the short-lived # session cert it produces is valid before a phone must re-challenge. MQTT_CHALLENGE_TTL_SECONDS: ${MQTT_CHALLENGE_TTL_SECONDS:-120} MQTT_SESSION_CERT_HOURS: ${MQTT_SESSION_CERT_HOURS:-24} NODE_ENV: development command: sh -c "npx prisma migrate deploy && npm run start:dev" web: build: context: ./web dockerfile: Dockerfile ports: - "3000:3000" depends_on: - backend # Development mount: mount web code into container for Next.js dev server volumes: - ./web:/usr/src/app:delegated - /usr/src/app/node_modules environment: BACKEND_HOST: http://backend:3001 NEXT_PUBLIC_ARCGIS_API_KEY: ${NEXT_PUBLIC_ARCGIS_API_KEY:-} NODE_ENV: development command: npm run dev pgadmin: image: dpage/pgadmin4:8 environment: PGADMIN_DEFAULT_EMAIL: admin@example.com PGADMIN_DEFAULT_PASSWORD: admin ports: - "5050:80" depends_on: - postgres volumes: postgres-data: