I have a directus instance running in a docker container.
The docker-compose.yml looks like this:
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
In the directus instance there is a webhook that gets triggered on new entries and sends the entry data to my flask app (or is supposed to do so). I use the url http://localhost:8080/webhook for this purpose.
The Flask app is supposed to listen on localhost:8080/webhook and print the data to the command line.
But when I trigger the webhook I recieve a "Connection refused" error message. I thought it was about the ports of the docker container, so I exposed 8080:8080 but that did not help.
The flask app:
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)
The Error message:
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 | },
My problem was that I did not use the correct url while sending the webhook. Due to my directus instance running in a docker container, I only send the message to the localhost of the docker container. I fixed this by moving the flask app into the docker network.
I created a new directory called app on the same level as the directus directory. Into the app directory I put a requirements.txt, the app script and a Dockerfile. The Dockerfile looks like this:
# syntax=docker/dockerfile:1
FROM python:3.10-alpine
WORKDIR /code
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["python3", "app.py"]
The Docker Compose file (which is placed in the parent directory of the directus and the app directory, looks like this:
version: "3"
services:
directus:
image: directus/directus:9.22.1
ports:
- "8055:8055"
volumes:
- ./directus/database:/directus/database
- ./directus/extensions:/directus/extensions
- ./directus/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
app:
build: ./app
ports:
- "8080:8080"
Now I can address each container using the name of the container. So I changed the webhook to
http://app:8080/webhook
I also changed the position and argument of the flask.run() call.
from flask import Flask
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
return "Works", 200
app.run(host='app', port=8080, debug=True) # called last, using the new host name.