英文:
Subscribers in Docker using Redis and MedusaJs
问题
我在运行Docker中的应用程序时,在Medusa后端中设置订阅者遇到了问题。我已经创建了一个docker-compose.yml文件,这使得可以部署和使用medusa_admin、自己的商店以及docker中的medusa_backend。我还创建了我的数据库作为Docker容器(redis、postgres和Solr用于搜索优化)。
以下是我的docker-compose.yml文件:
version: "3.8"
services:
backend:
build:
context: ./medusa_backend
dockerfile: Dockerfile
image: my_username/medusa_backend
container_name: medusa_backend
depends_on:
- postgres
- redis
environment:
DATABASE_URL: postgres://postgres:<my_password>@postgres:5432
REDIS_URL: redis://redis:6379
NODE_ENV: development
JWT_SECRET: some_jwt_secret
COOKIE_SECRET: some_cookie_secret
PORT: 9000
ADMIN_CORS: http://localhost:7000,http://localhost:7001,http://<my_server_ip>:7000,http://localhost:7000
STORE_CORS: http://localhost:3000,http://<my_server_ip>:8000,http://localhost:8000
volumes:
- ./medusa_backend/data:/var/lib/postgresql/data
ports:
- "9000:9000"
networks:
- alpha_solutions_docker_network
restart: always
postgres:
image: postgres:10.4
container_name: postgres
ports:
- "5432:5432"
volumes:
- ./postgres/data:/var/lib/postgresql/data
networks:
- alpha_solutions_docker_network
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=<my_password>
- POSTGRES_DB=postgres
- POSTGRES_INITDB_ARGS=--encoding=UTF-8
redis:
image: redis
container_name: redis
ports:
- "6379:6379"
networks:
- alpha_solutions_docker_network
restart: always
admin:
build:
context: ./medusa_admin
dockerfile: Dockerfile
image: my_username/medusa_admin
container_name: medusa_admin
depends_on:
- backend
environment:
HOST: 0.0.0.0
PORT: 7000
ports:
- "7000:7000"
networks:
- alpha_solutions_docker_network
restart: always
storefront:
build:
context: ./nextjs_frontend
dockerfile: Dockerfile
image: my_username/medusa_storefront
container_name: storefront
depends_on:
- backend
environment:
PORT: 8000
ports:
- "8000:8000"
networks:
- alpha_solutions_docker_network
restart: always
solr:
image: solr
container_name: solr
depends_on:
- postgres
ports:
- "8983:8983"
volumes:
- data:/var/solr
- ./solr:/opt/solr/server/solr/configsets/product_index
entrypoint:
- docker-entrypoint.sh
- solr-precreate
- product_index
networks:
- alpha_solutions_docker_network
restart: always
volumes:
data:
networks:
alpha_solutions_docker_network:
当我通过npm run start
在开发模式下运行我的medusa_backend时,我可以使用我的订阅者,并且它按预期调用函数。请注意:应用程序的其余部分(管理界面、数据库)都在Docker中运行。
我正在监听事件"product.updated",并在以开发模式运行后端时得到以下响应:
info: Processing product.updated which has 1 subscribers
当我通过"docker-compose up --build -d"运行我的Medusa后端(以及应用程序的其余部分)并尝试调用事件时,我得到以下响应:
info: Processing product.updated which has 0 subscribers
起初,我认为我的Docker容器无法相互连接,但从我的后端Docker容器的命令行中,我可以通过"redis-cli -u $REDIS_URL"前往Redis服务器并执行"ping"命令。这意味着Medusa_backend容器可以成功使用我在我的docker-compose.yml中定义的$REDIS_URL环境变量进行连接。
在以开发模式运行和在Docker中运行之间的主要区别是,我的Postgres、Redis和Solr的URL已更改为它们的容器名称,而不是localhost,以便Docker可以重定向到正确的IP。
更新
当在Docker中运行相同的Redis映像,但不作为网络的一部分时,我的后端可以通过localhost:6379连接到它。
更新2
结果,只要我将medusa_backend作为容器运行,我就无法使用我的订阅者。尽管当使用在Docker网络之外的Redis服务器的镜像(通过localhost)运行时,它似乎可以正常工作。在medusa_backend日志中,我可以看到:
info: Processing product.updated which has 0 subscribers
我对此感到非常困惑,但将继续研究。我认为这必须与连接到Redis数据库有关。此外,我已经在我的docker-compose文件中添加了一个检查,以验证在启动Medusa_backend服务器之前Redis是否正在运行。
更新3
我尝试在我的订阅者构造函数中使用console.log输出我的EventBusService。在本地运行Medusa_backend(通过npm start)时,它记录了一个包含连接参数到我的redis实例的完整eventbus对象。在Docker环境中执行时,没有记录任何eventbus,这让我怀疑是否在启动时初始化eventbus。
是否有已知的方法可以确保在启动后端时初始化EventBusService?
英文:
I have an issue setting up a subscriber in Medusa backend when running my application in Docker.
I have created a docker-compose.yml which makes it possible to deploy and use both medusa_admin, my own storefront and the medusa_backend from docker.
Also I have created my databases as docker containers (redis, postgres and a Solr for search optimization).
Below is my docker-compose.yml file:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
version: "3.8"
services:
backend:
build:
context: ./medusa_backend
dockerfile: Dockerfile
image: my_username/medusa_backend
container_name: medusa_backend
depends_on:
- postgres
- redis
environment:
DATABASE_URL: postgres://postgres:<my_password>@postgres:5432
REDIS_URL: redis://redis:6379
NODE_ENV: development
JWT_SECRET: some_jwt_secret
COOKIE_SECRET: some_cookie_secret
PORT: 9000
ADMIN_CORS: http://localhost:7000,http://localhost:7001,http://<my_server_ip>:7000,http://localhost:7000
STORE_CORS: http://localhost:3000,http:///<my_server_ip>:8000,http://localhost:8000
volumes:
- ./medusa_backend/data:/var/lib/postgresql/data
ports:
- "9000:9000"
networks:
- alpha_solutions_docker_network
restart: always
postgres:
image: postgres:10.4
container_name: postgres
ports:
- "5432:5432"
volumes:
- ./postgres/data:/var/lib/postgresql/data
networks:
- alpha_solutions_docker_network
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=<my_password>
- POSTGRES_DB=postgres
- POSTGRES_INITDB_ARGS=--encoding=UTF-8
redis:
image: redis
container_name: redis
ports:
- "6379:6379"
networks:
- alpha_solutions_docker_network
restart: always
admin:
build:
context: ./medusa_admin
dockerfile: Dockerfile
image: my_username/medusa_admin
container_name: medusa_admin
depends_on:
- backend
environment:
HOST: 0.0.0.0
PORT: 7000
ports:
- "7000:7000"
networks:
- alpha_solutions_docker_network
restart: always
storefront:
build:
context: ./nextjs_frontend
dockerfile: Dockerfile
image: my_username/medusa_storefront
container_name: storefront
depends_on:
- backend
environment:
PORT: 8000
ports:
- "8000:8000"
networks:
- alpha_solutions_docker_network
restart: always
solr:
image: solr
container_name: solr
depends_on:
- postgres
ports:
- "8983:8983"
volumes:
- data:/var/solr
- ./solr:/opt/solr/server/solr/configsets/product_index
entrypoint:
- docker-entrypoint.sh
- solr-precreate
- product_index
networks:
- alpha_solutions_docker_network
restart: always
volumes:
data:
networks:
alpha_solutions_docker_network:
<!-- end snippet -->
When running my medusa_backend in development mode via npm run start
I can use my subscriber and it calls the function as intended.
Note: the rest of the application (admin GUI, databases) is running in docker.
I am listening to the event "product.updated"
and it gives the following response when running the backend in develop mode:
> info: Processing product.updated which has 1 subscribers
When my Medusa backend (and rest of the application) is run via my docker-compose.yml file via "docker-compose up --build -d" and try to invoke the event I get the following response:
> info: Processing product.updated which has 0 subscribers
At first I thought my docker containers were unable to connect to each other, but from the command line in my backend docker container I can go to the Redis server via "redis-cli -u $REDIS_URL" and execute the "ping" command.
Which means that the Medusa_backend container can successfully connect using the $REDIS_URL
env variable defined in my docker-compose.yml
.
The big difference between running in development mode (npm start) and in docker is that the URL's for my Postgres, Redis and Solr is changed to their container names instead of localhost so that Docker can redirect to the proper IP.
Update
When running the same Redis image in docker, but not as a part of the network, my backend can connect to it via localhost:6379.
Update 2
Turns out that as soon as I run the medusa_backend as a container in my I cannot use my subscriber. Thought it worked when running the image with a Redis server outside the docker network (via localhost).
It did not.
In the medusa_backend logs i can see:
info: Processing product.updated which has 0 subscribers
I am truly confused as to why - but will keep looking into it.
I assume it must be something with the connection the Redis database.
Also I have added a check to my docker-compose file that verifies that my Redis is running before starting my Medusa_backend server.
Update 3
I tried to console.log my EventBusService inside my subscribers constructor.
Running the Medusa_backend locally (via npm start) it logs a full eventbus object with connection parameters to my redis instance.
When executed in the docker environment no eventbus is logged - which makes me wonder if the eventbus gets initialized at all.
Are there any known way to ensure the EventBusService is initialized when starting the backend?
答案1
得分: 1
解决方案
我找到了解决我的问题的方法。
当我意识到订阅者(以及eventBusService等)从未被初始化时,让我思考的是,我的项目没有正确处理我的TypeScript文件。
事实证明,尽管我的订阅者和服务是用TypeScript编写的,但它们并没有像预期那样被转译/编译。
然后我研究了MedusaJS和TypeScript,并找到了一个添加了对TypeScript支持的PR。
然后我决定阅读这些更改,并添加对我的项目有关的部分(暂时)。
我在我的package.json
文件中添加了一个构建脚本:
"scripts": {
"build": "tsc -p tsconfig.json",
"start": "npm run build && medusa develop"
},
我在我的tsconfig.json
中添加了以下内容
{
"compilerOptions": {
"experimentalDecorators": true,
},
"extends": "./tsconfig.base.json",
"include": ["src"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
我添加了一个tsconfig.base.json
文件
{
"compilerOptions": {
"lib": ["es5", "es6"],
"target": "esnext",
"allowJs": true,
"esModuleInterop": false,
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"declaration": false,
"sourceMap": false,
"outDir": "./dist",
"rootDir": "src",
"baseUrl": "src"
},
"exclude": ["node_modules"]
}
我更新了我的develop.sh
脚本,使其运行与npm start
脚本相同的命令
medusa migrations run
npm run build
medusa develop
然后我运行了我的Docker命令
docker-compose up --build -d
Boom。 Medusa_backend日志显示订阅者已初始化,并且订阅者按预期工作。
英文:
SOLUTION
I figured out a solution to my problem.
When I realized that the Subscriber (and the eventBusService etc) was never initialized let me into the thought process that my project did not handle my TS files correctly.
It turns out that my subscriber and service while written in TS was not transpiled/compiled as expected.
Then I looked into MedusaJS and TypeScript and found a PR that added support for TS.
I then decided to read through the changes and add the ones relevant for my project (for now).
I updated my package.json
file with a build script:
"scripts": {
"build": "tsc -p tsconfig.json",
"start": "npm run build && medusa develop"
},
I added the following to the my tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
},
"extends": "./tsconfig.base.json",
"include": ["src"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
I added a tsconfig.base.json
file
{
"compilerOptions": {
"lib": ["es5", "es6"],
"target": "esnext",
"allowJs": true,
"esModuleInterop": false,
"module": "commonjs",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"skipDefaultLibCheck": true,
"declaration": false,
"sourceMap": false,
"outDir": "./dist",
"rootDir": "src",
"baseUrl": "src"
},
"exclude": ["node_modules"]
}
I updated my [develop.sh](http://develop.sh)
script to run the same commandos as the npm start script
medusa migrations run
npm run build
medusa develop
Then I ran my docker commands
docker-compose up --build -d
Boom. The Medusa_backend log showcased that the Subscriber was initialized and the subscriber worked as intended.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论