在Docker中使用Redis和MedusaJs的订阅者

huangapple go评论51阅读模式
英文:

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: &quot;3.8&quot;
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:&lt;my_password&gt;@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://&lt;my_server_ip&gt;:7000,http://localhost:7000
STORE_CORS: http://localhost:3000,http:///&lt;my_server_ip&gt;:8000,http://localhost:8000
volumes:
- ./medusa_backend/data:/var/lib/postgresql/data
ports:
- &quot;9000:9000&quot;
networks:
- alpha_solutions_docker_network
restart: always
postgres:
image: postgres:10.4
container_name: postgres
ports:
- &quot;5432:5432&quot;
volumes:
- ./postgres/data:/var/lib/postgresql/data
networks:
- alpha_solutions_docker_network
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=&lt;my_password&gt;
- POSTGRES_DB=postgres
- POSTGRES_INITDB_ARGS=--encoding=UTF-8
redis:
image: redis
container_name: redis
ports:
- &quot;6379:6379&quot;
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:
- &quot;7000:7000&quot;
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:
- &quot;8000:8000&quot;
networks:
- alpha_solutions_docker_network
restart: always
solr:
image: solr
container_name: solr
depends_on:
- postgres
ports:
- &quot;8983:8983&quot;
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 &quot;product.updated&quot; 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:

&quot;scripts&quot;: {
&quot;build&quot;: &quot;tsc -p tsconfig.json&quot;,
&quot;start&quot;: &quot;npm run build &amp;&amp; medusa develop&quot;
},

I added the following to the my tsconfig.json

{
  &quot;compilerOptions&quot;: {
    &quot;experimentalDecorators&quot;: true,
  },
  &quot;extends&quot;: &quot;./tsconfig.base.json&quot;,
  &quot;include&quot;: [&quot;src&quot;],
  &quot;exclude&quot;: [&quot;node_modules&quot;, &quot;**/*.spec.ts&quot;]
}

I added a tsconfig.base.json file

{
    &quot;compilerOptions&quot;: {
      &quot;lib&quot;: [&quot;es5&quot;, &quot;es6&quot;],
      &quot;target&quot;: &quot;esnext&quot;,
      &quot;allowJs&quot;: true,
      &quot;esModuleInterop&quot;: false,
      &quot;module&quot;: &quot;commonjs&quot;,
      &quot;moduleResolution&quot;: &quot;node&quot;,
      &quot;emitDecoratorMetadata&quot;: true,
      &quot;experimentalDecorators&quot;: true,
      &quot;skipLibCheck&quot;: true,
      &quot;skipDefaultLibCheck&quot;: true,
      &quot;declaration&quot;: false,
      &quot;sourceMap&quot;: false,
      &quot;outDir&quot;: &quot;./dist&quot;,
      &quot;rootDir&quot;: &quot;src&quot;,
      &quot;baseUrl&quot;: &quot;src&quot;
    },
    &quot;exclude&quot;: [&quot;node_modules&quot;]
  }

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.

huangapple
  • 本文由 发表于 2023年3月7日 21:43:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定