# frost — FROST-Server (OGC SensorThings API) (cloud only) # Public hostname: frost.wbd-rd.nl (reverse-proxied via nginx-proxy) # /FROST-Server → frost-http:8080 (REST + UI) # /mqtt → frost-mqtt:9876 (WebSocket MQTT for STA clients) # # Networks: # frost-internal : private bus (db ↔ frost-* ↔ mosquitto). No outside reach. # app : where frost-http / frost-mqtt expose ports to nginx. # # Dedicated postgis DB + dedicated mosquitto bus — maximum segregation from the # shared sql / rabbitmq stacks. Public MQTT for SCADA clients goes via rabbitmq. services: # --- DB: dedicated postgis instance for FROST --------------------------------- frost-db: image: postgis/postgis:16-3.4-alpine restart: unless-stopped networks: [frost-internal] environment: POSTGRES_DB: sensorthings POSTGRES_USER: sensorthings POSTGRES_PASSWORD: ${FROST_DB_PASSWORD} TZ: ${TZ:-Europe/Amsterdam} volumes: - frost-db-data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -d sensorthings -U sensorthings"] interval: 5s timeout: 5s retries: 12 start_period: 30s # --- Internal message bus ------------------------------------------------------ # Used solely for frost-http ↔ frost-mqtt synchronisation. Not for external clients. frost-mosquitto: image: eclipse-mosquitto:2.0 restart: unless-stopped networks: [frost-internal] volumes: - ./config/mosquitto.conf:/mosquitto/config/mosquitto.conf:ro - frost-mosquitto-data:/mosquitto/data - frost-mosquitto-log:/mosquitto/log # --- HTTP (REST + admin UI) --------------------------------------------------- frost-http: image: fraunhoferiosb/frost-server-http:latest restart: unless-stopped networks: [frost-internal, app] depends_on: frost-db: condition: service_healthy frost-mosquitto: condition: service_started environment: serviceRootUrl: ${FROST_SERVICE_ROOT_URL:-https://frost.wbd-rd.nl/FROST-Server} queueLoggingInterval: "1000" plugins_multiDatastream_enable: "false" http_cors_enable: "true" http_cors_allowed_origins: "*" bus_busImplementationClass: de.fraunhofer.iosb.ilt.frostserver.messagebus.MqttMessageBus bus_mqttBroker: tcp://frost-mosquitto:1883 bus_sendQueueSize: "2000" bus_sendWorkerPoolSize: "10" bus_maxInFlight: "2000" persistence_db_driver: org.postgresql.Driver persistence_db_url: jdbc:postgresql://frost-db:5432/sensorthings persistence_db_username: sensorthings persistence_db_password: ${FROST_DB_PASSWORD} persistence_autoUpdateDatabase: "true" # BasicAuth against USERS table in postgis. Swap to Keycloak OIDC later. auth_provider: de.fraunhofer.iosb.ilt.frostserver.auth.basic.BasicAuthProvider auth_db_driver: org.postgresql.Driver auth_db_url: jdbc:postgresql://frost-db:5432/sensorthings auth_db_username: sensorthings auth_db_password: ${FROST_DB_PASSWORD} auth_plainTextPassword: "false" auth_autoUpdateDatabase: "true" TZ: ${TZ:-Europe/Amsterdam} # --- MQTT (SensorThings MQTT endpoint, with WebSocket on 9876) ----------------- frost-mqtt: image: fraunhoferiosb/frost-server-mqtt:latest restart: unless-stopped networks: [frost-internal, app] depends_on: frost-db: condition: service_healthy frost-mosquitto: condition: service_started environment: serviceRootUrl: ${FROST_SERVICE_ROOT_URL:-https://frost.wbd-rd.nl/FROST-Server} queueLoggingInterval: "1000" plugins_multiDatastream_enable: "false" bus_busImplementationClass: de.fraunhofer.iosb.ilt.frostserver.messagebus.MqttMessageBus bus_mqttBroker: tcp://frost-mosquitto:1883 mqtt_CreateThreadPoolSize: "10" mqtt_CreateMessageQueueSize: "10000" mqtt_SubscribeThreadPoolSize: "20" mqtt_SubscribeMessageQueueSize: "10000" persistence_persistenceManagerImplementationClass: de.fraunhofer.iosb.ilt.sta.persistence.postgres.PostgresPersistenceManager persistence_db_driver: org.postgresql.Driver persistence_db_url: jdbc:postgresql://frost-db:5432/sensorthings persistence_db_username: sensorthings persistence_db_password: ${FROST_DB_PASSWORD} auth_provider: de.fraunhofer.iosb.ilt.frostserver.auth.basic.BasicAuthProvider auth_db_driver: org.postgresql.Driver auth_db_url: jdbc:postgresql://frost-db:5432/sensorthings auth_db_username: sensorthings auth_db_password: ${FROST_DB_PASSWORD} auth_plainTextPassword: "false" auth_autoUpdateDatabase: "true" TZ: ${TZ:-Europe/Amsterdam} networks: app: frost-internal: driver: bridge internal: true volumes: frost-db-data: frost-mosquitto-data: frost-mosquitto-log: