Subscribers not running with Dockerised application #3430
-
Hi, I have an issue utilizing a subscriber when the Medusa backend is being run as a docker container. My issueI am working on a project with a Medusa JS backend & admin and my custom storefront created using NextJS. For my databases I am using PostgreSQL and Redis. I am using Solr for searching in my content. All services are supposed to be run as docker containers as part of deploying the project on a Linux server. My issue is that when running all my containers in Docker and the event is being raised it cannot find any subscribers. When starting the docker containers using I have subscribed to the event: product.updated When being run in docker this is the result of invoking the product.updated event. When I run all of my services using Docker, except for the Medusa backend which is started using This is the info output for medusa backend running locally: The difference between the two scenarios is that when Medusa backend is being run locally my env variables are set in an .env file and when running in docker variables are defined in the docker-compose file. If I go into the Medusa_backend container and open a terminal I can connect to the Redis instance and ping my redis server using the following command sequence:
Have anybody experienced anything similar with their subscribers and running the application in a Docker environment and if so how did you fix it? Any input is very welcome. Thanks in advance! Below is all my files and I am happy to share more if needed. My files.env
Where as when running via docker-compose my env variables are set as container names instead of localhost. Docker-compose.ymlversion: "3.8"
networks:
medusa_network:
services:
backend:
build:
context: ./medusa_backend
dockerfile: Dockerfile
image: dahlfrederik/medusa_backend
container_name: medusa_backend
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
DATABASE_URL: postgres://postgres:<my-password>@postgres:5432
REDIS_URL: redis://redis:6379
SOLR_URL: http://solr:8983/solr
NODE_ENV: development
JWT_SECRET: some_jwt_secret
COOKIE_SECRET: some_cookie_secret
PORT: 9000
ADMIN_CORS: http://medusa_admin:7000,http://localhost:7001,http://<my-server-ip>:7000,http://localhost:7000
STORE_CORS: http://localhost:3000,http://<my-server-ip>:8000,http://storefront:8000
volumes:
- ./medusa_backend/data:/var/lib/postgresql/data
ports:
- "9000:9000"
restart: always
networks:
- medusa_network
postgres:
image: postgres:10.4
container_name: postgres
ports:
- "5432:5432"
volumes:
- ./postgres/data:/var/lib/postgresql/data
restart: always
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=<my-password>
- POSTGRES_DB=postgres
- POSTGRES_INITDB_ARGS=--encoding=UTF-8
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres -h 127.0.0.1 -p 5432"]
interval: 10s
timeout: 5s
retries: 5
networks:
- medusa_network
redis:
image: redis
container_name: redis
expose:
- 6379
ports:
- "6379:6379"
restart: always
environment:
- ALLOW_EMPTY_PASSWORD=yes
- REDIS_BIND_ADDRESS=0.0.0.0
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- medusa_network
admin:
build:
context: ./medusa_admin
dockerfile: Dockerfile
image: dahlfrederik/medusa_admin
container_name: medusa_admin
depends_on:
- backend
environment:
HOST: 0.0.0.0
PORT: 7000
ports:
- "7000:7000"
restart: always
networks:
- medusa_network
storefront:
build:
context: ./nextjs_frontend
dockerfile: Dockerfile
image: dahlfrederik/medusa_storefront
container_name: storefront
depends_on:
- backend
environment:
PORT: 8000
ports:
- "8000:8000"
restart: always
networks:
- medusa_network
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
restart: always
networks:
- medusa_network
volumes:
data: SubscriberThis is the code for my subscriber import { EventBusService } from "@medusajs/medusa";
import SolrService from "../services/solr";
class ProductPublishedSubscriber {
private solrService: SolrService;
/**
* Initializes a new instance of the ProductPublishedSubscriber class.
* @param solrService - An instance of the SolrService class.
* @param eventBusService - An instance of the EventBusService class.
* Destructured according as described in Medusa JS docs
*/
constructor({
solrService,
eventBusService,
}: {
solrService: SolrService;
eventBusService: EventBusService;
}) {
this.solrService = solrService;
eventBusService.subscribe("product.updated", this.handleProductPublished);
}
/**
* Handles the "product.updated" event by adding the updated product to the Solr index.
* @param data - An object containing the ID of the updated product.
*/
handleProductPublished = async (data: { id: string }): Promise<void> => {
console.log("Found product with id: " + data.id);
this.solrService.updateProduct(data.id);
};
}
export default ProductPublishedSubscriber; Medusa-config.js
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
@dahlfrederik - can I get you to check if the events are stuck in the event outbox. You can do so by connecting to your Postgres db and running:
|
Beta Was this translation helpful? Give feedback.
-
UPDATEI tried to console.log my EventBusService inside my subscribers constructor. Are there any known way to ensure the EventBusService is initialized when starting the backend? |
Beta Was this translation helpful? Give feedback.
-
SOLUTIONI 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 typescript (medusajs/medusa-starter-default#9) I then decided to read through the changes and add the ones relevant for my project (for now). I updated my "scripts": {
"build": "tsc -p tsconfig.json",
"start": "npm run build && medusa develop"
}, I added the following to the my {
"compilerOptions": {
"experimentalDecorators": true,
},
"extends": "./tsconfig.base.json",
"include": ["src"],
"exclude": ["node_modules", "**/*.spec.ts"]
} I added a {
"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 medusa migrations run
npm run build
medusa develop Then I ran my docker commands
Boom. The Medusa_backend log showcased that the Subscriber was initialized and the subscriber worked as intended. |
Beta Was this translation helpful? Give feedback.
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 typescript (medusajs/medusa-starter-default#9)
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:I …