Docker容器间连接被拒绝问题:Python容器无法连接本地GeoServer容器获取WMS信息
咱们先从最扎眼的问题说起:你在Python配置里用错了容器内部的服务端口!
你的GeoServer容器里,Tomcat是跑在8080端口的——从docker-compose里的ports: - ${GS_HTTP_PORT}:8080就能看出来,主机端口是映射到容器的8080端口。但你给Python的配置写的是http://geoserver,默认会访问80端口,可GeoServer容器根本没在80端口提供服务,这肯定连不上啊!
第一步:修正WMS服务URL
把你的JSON配置改成下面这样,补上正确的端口和GeoServer上下文路径:
{ "url": "http://geoserver:8080/geoserver", "workspace": "tiger", "service_version": "1.3.0", "layer_name": "poi", "layer_type": "vector" }
这里要注意两个关键点:
- 加上容器内部的服务端口
:8080 - URL末尾补上
/geoserver(GeoServer的默认上下文路径,不加的话请求会找不到服务)
第二步:处理容器启动就绪问题
就算改对了端口,你可能还是会遇到连接失败——因为depends_on只是保证GeoServer容器先启动,但GeoServer(加Tomcat)启动需要好几分钟,Python容器启动时GeoServer可能还没完全就绪,导致第一次请求直接被拒绝。
你可以给docker-compose里的geoserver服务加上健康检查,让Python容器等GeoServer真正可用后再启动:
geoserver: image: maxdragonheart/geoserver environment: GS_VERSION: ${GS_VERSION} GS_DEMO_DATA: ${GS_DEMO_DATA} GS_HTTP_PORT: ${GS_HTTP_PORT} GS_INITIAL_MEMORY: ${GS_INITIAL_MEMORY} GS_MAXIMUM_MEMORY: ${GS_MAXIMUM_MEMORY} container_name: dev_geoserver restart: always ports: - ${GS_HTTP_PORT}:8080 volumes: - geoserver:/opt/tomcat/webapps/geoserver networks: - test healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/geoserver/web/"] interval: 30s timeout: 10s retries: 10 start_period: 120s
然后给python-api服务的depends_on加上健康检查依赖:
python-api: image: maxdragonheart/${PROJECT_NAME} build: context: ./pythonapi dockerfile: Dockerfile environment: PROJECT_NAME: ${PROJECT_NAME} container_name: dev_pythonapi restart: always ports: - ${PYTHON_API_PORT}:5000 depends_on: geoserver: condition: service_healthy networks: - test
这样Python容器会等到GeoServer的健康检查通过(也就是服务真正能响应请求)之后才启动,避免启动时的连接失败。
第三步:手动验证连通性(可选排查)
如果改完还是有问题,你可以进入Python容器内部,手动测试连通性:
# 进入Python容器 docker exec -it dev_pythonapi bash # 如果容器里没有curl,先安装(基于Debian/Ubuntu镜像的话) apt update && apt install -y curl # 测试GeoServer的WMS服务 curl "http://geoserver:8080/geoserver/tiger/wms?service=WMS&request=GetCapabilities&version=1.3.0"
如果这个命令能返回XML格式的GetCapabilities响应,说明网络和服务都没问题,问题可能出在你的Python代码里;如果还是连接拒绝,再检查网络配置——不过看你的docker-compose,两个容器都在test桥接网络里,服务名解析应该是正常的。
总结一下,最核心的问题是用错了容器内部的服务端口,其次是启动顺序导致的服务未就绪问题,按上面的步骤改应该就能解决啦!
内容的提问来源于stack exchange,提问作者MaxDragonheart

