Skip to main content

Using docker

Docker is a technology which allows you to run your Vendure application inside a container. The default installation with @vendure/create includes a sample Dockerfile:

Dockerfile
FROM node:22WORKDIR /usr/src/appCOPY package.json ./COPY package-lock.json ./ RUN npm install --productionCOPY . .RUN npm run build

This Dockerfile can then be built into an "image" using:

Bash
docker build -t vendure .

This same image can be used to run both the Vendure server and the worker:

Bash
# Run the serverdocker run -dp 3000:3000 --name vendure-server vendure npm run start:server# Run the workerdocker run -dp 3000:3000 --name vendure-worker vendure npm run start:worker

Here is a breakdown of the command used above:

  • docker run - run the image we created with docker build
  • -dp 3000:3000 - the -d flag means to run in "detached" mode, so it runs in the background and does not take control of your terminal. -p 3000:3000 means to expose port 3000 of the container (which is what Vendure listens on by default) as port 3000 on your host machine.
  • --name vendure-server - we give the container a human-readable name.
  • vendure - we are referencing the tag we set up during the build.
  • npm run start:server - this last part is the actual command that should be run inside the container.

Docker Compose

Managing multiple docker containers can be made easier using Docker Compose. In the below example, we use the same Dockerfile defined above, and we also define a Postgres database to connect to:

Yaml
version: "3"services:  server:    build:      context: .      dockerfile: Dockerfile    ports:      - 3000:3000    command: ["npm", "run", "start:server"]    volumes:      - /usr/src/app    environment:      DB_HOST: database      DB_PORT: 5432      DB_NAME: vendure      DB_USERNAME: postgres      DB_PASSWORD: password  worker:    build:      context: .      dockerfile: Dockerfile    command: ["npm", "run", "start:worker"]    volumes:      - /usr/src/app    environment:      DB_HOST: database      DB_PORT: 5432      DB_NAME: vendure      DB_USERNAME: postgres      DB_PASSWORD: password  database:    image: postgres    volumes:      - /var/lib/postgresql/data    ports:      - 5432:5432    environment:      POSTGRES_PASSWORD: password      POSTGRES_DB: vendure

Kubernetes

Kubernetes is used to manage multiple containerized applications. This deployment starts the shop container we created above as both worker and server.

Yaml
apiVersion: apps/v1kind: Deploymentmetadata:  name: vendure-shopspec:  selector:    matchLabels:      app: vendure-shop  replicas: 1  template:    metadata:      labels:        app: vendure-shop    spec:      containers:        - name: server          image: vendure-shop:latest          command:            - node          args:            - "dist/index.js"          env:          # your env config here          ports:            - containerPort: 3000        - name: worker          image: vendure-shop:latest          imagePullPolicy: Always          command:            - node          args:            - "dist/index-worker.js"          env:          # your env config here          ports:            - containerPort: 3000

Health/Readiness Checks

If you wish to deploy with Kubernetes or some similar system, you can make use of the health check endpoints.

Server

This is a regular REST route (note: not GraphQL), available at /health.

Text
REQUEST: GET http://localhost:3000/health
Json
{  "status": "ok",  "info": {    "database": {      "status": "up"    }  },  "error": {},  "details": {    "database": {      "status": "up"    }  }}

Health checks are built on the Nestjs Terminus module. You can also add your own health checks by creating plugins that make use of the HealthCheckRegistryService.

Worker

Although the worker is not designed as an HTTP server, it contains a minimal HTTP server specifically to support HTTP health checks. To enable this, you need to call the startHealthCheckServer() method after bootstrapping the worker:

Ts
bootstrapWorker(config)    .then(worker => worker.startJobQueue())    .then(worker => worker.startHealthCheckServer({ port: 3020 }))    .catch(err => {        console.log(err);    });

This will make the /health endpoint available. When the worker instance is running, it will return the following:

Text
REQUEST: GET http://localhost:3020/health
Json
{  "status": "ok"}
Was this chapter helpful?
Report Issue
Edited Feb 2, 2026·Edit this page