如何在docker compose中通过curl向FROST-Server插入JSON数据
问题描述
需要在docker compose部署环境中,通过CURL命令将file.json文件内的SensorThings数据写入FROST-Server对接的PostGIS数据库中。
你提供的file.json结构符合FROST-Server的深插入(Deep Insert)规范,单次POST请求即可完成Thing及其关联的Location、Datastream、Sensor、ObservedProperty、Observation全量实体创建,无需拆分多次请求。
已尝试方案
- 最初计划将本地file.json挂载到FROST-Server容器内部,在docker compose配置中直接执行CURL命令完成数据写入,初始测试命令如下:
curl -X POST -H "Content-Type: application/json" -d file.json http://localhost:8080/FROST-Server/v1.1/Things
- 基于上述思路编写的docker-compose.yaml配置如下:
version: '2' services: web: image: fraunhoferiosb/frost-server:latest environment: - serviceRootUrl=http://localhost:8080/FROST-Server - http_cors_enable=true - http_cors_allowed.origins=* - persistence_db_driver=org.postgresql.Driver - persistence_db_url=jdbc:postgresql://database:5432/sensorthings - persistence_db_username=sensorthings - persistence_db_password=ChangeMe - persistence_autoUpdateDatabase=true ports: - 8080:8080 - 1883:1883 volumes: - ./file.json:file.json depends_on: - database command: - curl - -X - POST - --data-binary - ./file.json - -H - "Content-Type: application/json" - -H - "Accept: application/json" - "http://localhost:8080/FROST-Server/v1.1/Things" database: image: postgis/postgis:14-3.2-alpine environment: - POSTGRES_DB=sensorthings - POSTGRES_USER=sensorthings - POSTGRES_PASSWORD=ChangeMe volumes: - postgis_volume:/var/lib/postgresql/data volumes: postgis_volume:
报错信息
执行docker-compose up命令后,容器启动失败,核心报错为连接被拒绝:
web_1 | curl: (7) Failed to connect to localhost port 8080: Connection refused frost_web_1 exited with code 7
问题根因
报错由三个配置错误共同导致:
- 直接覆盖FROST-Server容器的
command字段会替换容器默认的服务启动命令,配置中直接执行curl,根本没有启动FROST-Server本身的Web服务,8080端口无进程监听,curl请求必然被拒绝。 depends_on配置仅控制容器启动顺序,不会等待服务真正可用,就算正常启动FROST服务,也存在服务未完成初始化、端口未开放就执行curl的时序问题。- curl命令参数错误:
-d参数直接传文件名不会读取文件内容,只会把字符串"file.json"作为请求体发送,读取本地文件作为请求体需要加@前缀,即-d @file.json,使用--data-binary @file.json可保留JSON原始格式不做转义。
解决方案
提供两种可直接落地的方案,优先推荐第二种,无侵入、易维护。
方案一:修改FROST服务启动命令(不推荐)
在FROST服务容器内先启动服务进程,等待端口可用后再执行curl导入,最后保持前台进程运行避免容器退出。注意FROST官方镜像默认不带curl,需要先安装:
web: image: fraunhoferiosb/frost-server:latest environment: - serviceRootUrl=http://localhost:8080/FROST-Server - http_cors_enable=true - http_cors_allowed.origins=* - persistence_db_driver=org.postgresql.Driver - persistence_db_url=jdbc:postgresql://database:5432/sensorthings - persistence_db_username=sensorthings - persistence_db_password=ChangeMe - persistence_autoUpdateDatabase=true ports: - 8080:8080 - 1883:1883 volumes: - ./file.json:/tmp/file.json depends_on: - database command: > bash -c " apt-get update && apt-get install -y curl && catalina.sh run & until curl -s http://localhost:8080/FROST-Server/v1.1/Things > /dev/null; do sleep 2 done && curl -X POST -H 'Content-Type: application/json' --data-binary @/tmp/file.json http://localhost:8080/FROST-Server/v1.1/Things && wait "
该方案每次容器重建都会重复执行导入,需要额外加判断避免重复插入数据。
方案二:独立初始化容器执行导入(推荐)
不修改原有FROST和数据库服务的配置,单独新增一个一次性运行的初始化服务,等FROST服务完全启动后再执行数据导入,导入完成后自动退出,不影响原有服务生命周期。
完整配置如下:
version: '2' services: web: image: fraunhoferiosb/frost-server:latest environment: - serviceRootUrl=http://localhost:8080/FROST-Server - http_cors_enable=true - http_cors_allowed.origins=* - persistence_db_driver=org.postgresql.Driver - persistence_db_url=jdbc:postgresql://database:5432/sensorthings - persistence_db_username=sensorthings - persistence_db_password=ChangeMe - persistence_autoUpdateDatabase=true ports: - 8080:8080 - 1883:1883 depends_on: - database database: image: postgis/postgis:14-3.2-alpine environment: - POSTGRES_DB=sensorthings - POSTGRES_USER=sensorthings - POSTGRES_PASSWORD=ChangeMe volumes: - postgis_volume:/var/lib/postgresql/data frost-init: image: curlimages/curl:latest volumes: - ./file.json:/tmp/file.json depends_on: - web command: > sh -c " until curl -s http://web:8080/FROST-Server/v1.1/Things > /dev/null; do sleep 2 done && curl -X POST -H 'Content-Type: application/json' --data-binary @/tmp/file.json http://web:8080/FROST-Server/v1.1/Things " restart: "no" volumes: postgis_volume:
该方案优势:
- 完全不改动官方镜像默认启动逻辑,稳定性更高
- 使用轻量curl镜像执行导入,不需要在FROST容器内额外安装软件
- Docker Compose内部网络可直接通过服务名
web访问FROST接口,不需要走localhost端口映射 - 导入完成后init容器自动退出,不占用额外资源
- 需要重复导入时,单独启动frost-init容器即可,不需要重启整个服务栈
内容的提问来源于stack exchange,提问作者Abdelrahman Elayashy
相关产品推荐
相关产品推荐

