Docker中Directus触发Flask Webhook时出现连接拒绝问题
问题描述
我在Docker容器中运行了一个Directus实例,对应的docker-compose.yml配置如下:
services: directus: image: directus/directus:9.22.1 ports: - 8055:8055 volumes: - ./database:/directus/database - ./extensions:/directus/extensions - ./uploads:/directus/uploads environment: KEY: "some-key" SECRET: "some-secret" DB_CLIENT: "sqlite3" DB_FILENAME: "/directus/database/data.db" ADMIN_EMAIL: "admin@example.com" ADMIN_PASSWORD: "d1r3ctu5" CORS_ENABLED: true
我在Directus中配置了Webhook,当新条目创建时触发,将条目数据发送到我的Flask应用(目标地址设为http://localhost:8080/webhook)。Flask应用本该监听localhost:8080/webhook并将数据打印到命令行,但触发Webhook时收到Connection refused错误。我曾以为是Docker端口问题,已暴露8080:8080端口,但问题未解决。
Flask应用代码如下:
import paho.mqtt.client as mqtt from flask import Flask, request, Response app = Flask(__name__) app.run(host='localhost', port=8080) @app.route('/webhook', methods=['POST']) def return_response(): print(request.json) message = "An new entry was created!" print(message)
Webhook配置截图:
错误日志如下:
directus-directus-1 | [11:52:22.159] WARN: connect ECONNREFUSED 127.0.0.1:8080 directus-directus-1 | err: { directus-directus-1 | "message": "connect ECONNREFUSED 127.0.0.1:8080: connect ECONNREFUSED 127.0.0.1:8080", directus-directus-1 | "name": "Error", directus-directus-1 | "stack": directus-directus-1 | Error: connect ECONNREFUSED 127.0.0.1:8080 directus-directus-1 | at AxiosError.from (file:///directus/node_modules/axios/lib/core/AxiosError.js:89:14) directus-directus-1 | at RedirectableRequest.handleRequestError (file:///directus/node_modules/axios/lib/adapters/http.js:516:25) directus-directus-1 | at RedirectableRequest.emit (node:events:513:28) directus-directus-1 | at eventHandlers.<computed> (/directus/node_modules/follow-redirects/index.js:14:24) directus-directus-1 | at ClientRequest.emit (node:events:513:28) directus-directus-1 | at Socket.socketErrorListener (node:_http_client:494:9) directus-directus-1 | at Socket.emit (node:events:513:28) directus-directus-1 | at emitErrorNT (node:internal/streams/destroy:151:8) directus-directus-1 | at emitErrorCloseNT (node:internal/streams/destroy:116:3) directus-directus-1 | at process.processTicksAndRejections (node:internal/process/task_queues:82:21) directus-directus-1 | caused by: Error: connect ECONNREFUSED 127.0.0.1:8080 directus-directus-1 | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1300:16) directus-directus-1 | "config": { directus-directus-1 | "transitional": { directus-directus-1 | "silentJSONParsing": true, directus-directus-1 | "forcedJSONParsing": true, directus-directus-1 | "clarifyTimeoutError": false directus-directus-1 | }, directus-directus-1 | "transformRequest": [ directus-directus-1 | null directus-directus-1 | ], directus-directus-1 | "transformResponse": [ directus-directus-1 | null directus-directus-1 | ], directus-directus-1 | "timeout": 0, directus-directus-1 | "xsrfCookieName": "XSRF-TOKEN", directus-directus-1 | "xsrfHeaderName": "X-XSRF-TOKEN", directus-directus-1 | "maxContentLength": -1, directus-directus-1 | "maxBodyLength": -1, directus-directus-1 | "env": {}, directus-directus-1 | "headers": { directus-directus-1 | "Accept": "application/json, text/plain, */*", directus-directus-1 | "Content-Type": "application/json", directus-directus-1 | "User-Agent": "axios/1.1.3", directus-directus-1 | "Content-Length": "324", directus-directus-1 | "Accept-Encoding": "gzip, deflate, br" directus-directus-1 | }, directus-directus-1 | "url": "http://localhost:8080/webhook", directus-directus-1 | "method": "post", directus-directus-1 | "data": "{\"event\":\"items.create\",\"accountability\":{\"user\":\"d7c59a91-b6a8-4f1f-bcd6-95fc9d34c160\",\"role\":\"1ca3337b-aeed-4e5d-8076-06b949d59572\"},\"payload\":{\"publish_date\":\"2023-05-18T13:52:00+02:00\",\"title\":\"test\",\"author\":\"d7c59a91-b6a8-4f1f-bcd6-95fc9d34c160\",\"excerpt\":\"test\",\"body\":\"<p>test</p>\"},\"key\":19,\"collection\":\"articles\"}" directus-directus-1 | },
解决方案
核心问题分析
- Docker网络隔离:Directus容器内的
localhost指向容器自身,而非宿主机的localhost。当Directus请求http://localhost:8080时,是在容器内部寻找服务,而Flask应用跑在宿主机上,自然连接失败。 - Flask绑定地址错误:Flask设置
host='localhost',仅监听宿主机的本地回环接口,容器无法通过宿主机IP访问到它。
修复步骤
步骤1:修改Flask应用配置
调整Flask的绑定地址为所有接口,并确保路由定义在启动服务之前,同时添加响应返回:
import paho.mqtt.client as mqtt from flask import Flask, request, Response app = Flask(__name__) @app.route('/webhook', methods=['POST']) def return_response(): print(request.json) message = "有新条目创建!" print(message) return Response(status=200) # 必须返回响应,否则Webhook会判定请求失败并重试 # 先定义路由再启动服务,避免路由未注册 if __name__ == '__main__': app.run(host='0.0.0.0', port=8080)
步骤2:修改Webhook目标地址
根据操作系统选择合适的地址:
- Linux/macOS/Windows:使用Docker内置的宿主机指向地址
http://host.docker.internal:8080/webhook - 跨平台通用方式:直接使用宿主机的局域网IP(例如
http://192.168.1.100:8080/webhook)
步骤3:检查防火墙设置
确保宿主机防火墙允许8080端口的入站请求:
- Linux:检查ufw/firewalld是否开放8080端口
- Windows/macOS:确认防火墙未阻止Flask应用的网络请求
额外场景处理(若Flask也在Docker中)
如果Flask应用同样运行在Docker容器中:
- 将Directus和Flask容器加入同一个Docker网络
- Webhook地址使用Flask容器的服务名(例如
http://flask-service:8080/webhook)而非localhost
内容的提问来源于stack exchange,提问作者BranAndSceolan
相关产品推荐
相关产品推荐

