docs: add worker mode documentation + improvements (#11812)

This commit is contained in:
Shahed Nasser
2025-03-11 19:12:32 +02:00
committed by GitHub
parent ef66ff8f99
commit 267af9f3f6
10 changed files with 8414 additions and 8168 deletions

View File

@@ -762,24 +762,13 @@ module.exports = defineConfig({
### workerMode
The `projectConfig.workerMode` configuration specifies the worker mode of the Medusa application.
The `projectConfig.workerMode` configuration specifies the worker mode of the Medusa application. You can learn more about it in the [Worker Mode chapter](../../production/worker-mode/page.mdx).
Workers are processes running separately from the main application. They're useful for executing long-running or resource-heavy tasks in the background, such as importing products.
The value for this configuration can be one of the following:
With a worker, these tasks are offloaded to a separate process. So, they won't affect the performance of the main application.
![Diagram showcasing how the server and worker work together](https://res.cloudinary.com/dza7lstvk/image/upload/fl_lossy/f_auto/r_16/ar_16:9,c_pad/v1/Medusa%20Book/medusa-worker_klkbch.jpg?_a=BATFJtAA0)
Medusa has three runtime modes:
- Use `shared` to run the application in a single process, meaning the worker and server run in the same process.
- Use `worker` to run the a worker process only.
- Use `server` to run the application server only.
In production, it's recommended to deploy two instances of your Medusa application:
1. One having the `workerMode` configuration set to `server`. This is the main application server that handles incoming requests.
2. Another having the `workerMode` configuration set to `worker`. This is the worker that handles background tasks.
- `shared`: run the application in a single process, meaning the worker and server run in the same process.
- `worker`: run the a worker process only.
- `server`: run the application server only.
#### Example

View File

@@ -47,11 +47,9 @@ When you deploy your Medusa application, make sure your chosen hosting provider
### Worker Mode
The `workerMode` configuration determines which mode the Medusa application runs in.
The `workerMode` configuration determines which mode the Medusa application runs in. When you deploy the Medusa application, you deploy two instances: one in server mode, and one in worker mode.
When you deploy the Medusa application, you deploy two instances: one in server mode, and one in worker mode.
Learn more about the `workerMode` configuration in [this document](../../configurations/medusa-config/page.mdx#workermode).
Learn more about worker mode in the [Worker Module chapter](../../production/worker-mode/page.mdx).
So, add the following configuration in `medusa-config.ts`:

View File

@@ -31,6 +31,19 @@ Your server connects to a PostgreSQL database, Redis, and other services relevan
When you deploy your Medusa application, you also deploy the Medusa Admin. For optimal experience, your hosting provider and plan must offer at least 2GB of RAM.
### Deploy Server and Worker Instances
By default, Medusa runs all processes in a single instance. This includes the server that handles incoming requests and the worker that processes background tasks. While this works for development, its not optimal for production environments as many background tasks can be long-running or resource-heavy.
Instead, you should deploy two instances:
- A server instance, which handles incoming requests to the applications API routes.
- A worker instance, which processes background tasks, including scheduled jobs and subscribers.
You dont need to set up different projects for each instance. Instead, you can configure the Medusa application to run in different modes based on environment variables.
Learn more about worker modes and how to configure them in the [Worker Mode chapter](../production/worker-mode/page.mdx).
### How to Deploy Medusa?
Medusa Cloud is our managed services offering that makes deploying and operating Medusa applications possible without having to worry about configuring, scaling, and maintaining infrastructure. Medusa Cloud hosts your server, Admin dashboard, database, and Redis instance.

View File

@@ -12,7 +12,7 @@ In this chapter, youll learn about Query and how to use it to fetch data from
Query fetches data across modules. Its a set of methods registered in the Medusa container under the `query` key.
In your resources, such as API routes or workflows, you can resolve Query to fetch data across custom modules and Medusas commerce modules.
In all resources that can access the [Medusa Container](../../medusa-container/page.mdx), such as API routes or workflows, you can resolve Query to fetch data across custom modules and Medusas commerce modules.
---

View File

@@ -6,13 +6,19 @@ export const metadata = {
In this chapter, you'll learn about the architectural layers in Medusa.
<Note title="Tip">
Find the full architectural diagram at the [end of this chapter](#full-diagram-of-medusas-architecture).
</Note>
## HTTP, Workflow, and Module Layers
Medusa is a headless commerce platform. So, storefronts, admin dashboards, and other clients consume Medusa's functionalities through its API routes.
In a common Medusa application, requests go through four layers in the stack. In order of entry, those are:
1. API Routes (HTTP): Our API Routes are the typical entry point.
1. API Routes (HTTP): Our API Routes are the typical entry point. The Medusa server is based on Express.js, which handles incoming requests. It can also connect to a Redis database that stores the server session data.
2. Workflows: API Routes consume workflows that hold the opinionated business logic of your application.
3. Modules: Workflows use domain-specific modules for resource management.
3. Data store: Modules query the underlying datastore, which is a PostgreSQL database in common cases.
@@ -23,13 +29,13 @@ These layers of stack can be implemented within [plugins](../../fundamentals/plu
</Note>
![Diagram illustrating the HTTP layer](https://res.cloudinary.com/dza7lstvk/image/upload/v1727175296/Medusa%20Book/http-layer_sroafr.jpg)
![This diagram illustrates the entry point of requests into the Medusa application through API routes. It shows a storefront and an admin that can send a request to the HTTP layer. The HTTP layer then uses workflows to handle the business logic. Finally, the workflows use modules to query and manipulate data in the data stores.](https://res.cloudinary.com/dza7lstvk/image/upload/v1727175296/Medusa%20Book/http-layer_sroafr.jpg)
---
## Database Layer
The Medusa application injects into each module a connection to the configured PostgreSQL database. Modules use that connection to read and write data to the database.
The Medusa application injects into each module, including your [custom modules](../../fundamentals/modules/page.mdx), a connection to the configured PostgreSQL database. Modules use that connection to read and write data to the database.
<Note>
@@ -37,13 +43,13 @@ Modules can be implemented within [plugins](../../fundamentals/plugins/page.mdx)
</Note>
![Diagram illustrating the database layer](https://res.cloudinary.com/dza7lstvk/image/upload/v1727175379/Medusa%20Book/db-layer_pi7tix.jpg)
![This diagram illustrates how modules connect to the database.](https://res.cloudinary.com/dza7lstvk/image/upload/v1727175379/Medusa%20Book/db-layer_pi7tix.jpg)
---
## Service Integrations
## Third-Party Integrations Layer
Third-party services are integrated through commerce and architectural modules. You also create custom third-party integrations through a custom module.
Third-party services and systems are integrated through Medusa's Commerce and Architectural modules. You also create custom third-party integrations through a [custom module](../../fundamentals/modules/page.mdx).
<Note>
@@ -53,13 +59,25 @@ Modules can be implemented within [plugins](../../fundamentals/plugins/page.mdx)
### Commerce Modules
[Commerce modules](!resources!/commerce-modules) integrate third-party services relevant for commerce or user-facing features. For example, you integrate Stripe through a payment module provider.
[Commerce modules](!resources!/commerce-modules) integrate third-party services relevant for commerce or user-facing features. For example, you can integrate [Stripe](!resources!/commerce-modules/payment/payment-provider/stripe) through a Payment Module Provider, or [ShipStation](!resources!/integrations/guides/shipstation) through a Fulfillment Module Provider.
You can also integrate third-party services for custom functionalities. For example, you can integrate [Sanity](!resources!/integrations/guides/sanity) for rich CMS capabilities, or [Odoo](!resources!/recipes/erp/odoo) to sync your Medusa application with your ERP system.
You can replace any of the third-party services mentioned above to build your preferred commerce ecosystem.
![Diagram illustrating the commerce modules integration to third-party services](https://res.cloudinary.com/dza7lstvk/image/upload/v1727175357/Medusa%20Book/service-commerce_qcbdsl.jpg)
### Architectural Modules
[Architectural modules](!resources!/architectural-modules) integrate third-party services and systems for architectural features. For example, you integrate Redis as a pub/sub service to send events, or SendGrid to send notifications.
[Architectural modules](!resources!/architectural-modules) integrate third-party services and systems for architectural features. Medusa has the following Architectural modules:
- [Workflow Engine Module](!resources!/architectural-modules/workflow-engine): Orchestrates workflows that hold the business logic of your application. You can integrate [Redis](!resources!/architectural-modules/workflow-engine/redis) to orchestrate workflows.
- [Cache Module](!resources!/architectural-modules/cache): Caches data that require heavy computation. You can integrate a custom module to handle the caching with services like Memcached, or use the existing [Redis Cache Module](!resources!/architectural-modules/cache/redis).
- [Event Module](!resources!/architectural-modules/event): A pub/sub system that allows you to subscribe to events and trigger them. You can integrate [Redis](!resources!/architectural-modules/event/redis) as the pub/sub system.
- [File Module](!resources!/architectural-modules/file): Manages file uploads and storage, such as upload of product images. You can integrate [AWS S3](!resources!/architectural-modules/file/s3) for file storage.
- [Notification Module](!resources!/architectural-modules/notification): Sends notifications to customers and users, such as for order updates or newsletters. You can integrate [SendGrid](!resources!/architectural-modules/notification/sendgrid) for sending emails.
All of the third-party services mentioned above can be replaced to help you build your preferred architecture and ecosystem.
![Diagram illustrating the architectural modules integration to third-party services and systems](https://res.cloudinary.com/dza7lstvk/image/upload/v1727175342/Medusa%20Book/service-arch_ozvryw.jpg)
@@ -67,6 +85,6 @@ Modules can be implemented within [plugins](../../fundamentals/plugins/page.mdx)
## Full Diagram of Medusa's Architecture
The following diagram illustrates Medusa's architecture over the three layers.
The following diagram illustrates Medusa's architecture including all its layers.
![Full diagram illustrating Medusa's architecture](https://res.cloudinary.com/dza7lstvk/image/upload/v1727174897/Medusa%20Book/architectural-diagram-full.jpg)
![Full diagram illustrating Medusa's architecture combining all the different layers.](https://res.cloudinary.com/dza7lstvk/image/upload/v1727174897/Medusa%20Book/architectural-diagram-full.jpg)

View File

@@ -0,0 +1,106 @@
import { CodeTabs, CodeTab } from "docs-ui"
export const metadata = {
title: `${pageNumber} Worker Mode of Medusa Instance`,
}
# {metadata.title}
In this chapter, you'll learn about the different modes of running a Medusa instance and how to configure the mode.
## What is Worker Mode?
By default, the Medusa application runs both the server, which handles all incoming requests, and the worker, which processes background tasks, in a single process. While this setup is suitable for development, it is not optimal for production environments where background tasks can be long-running or resource-intensive.
In a production environment, you should deploy two separate instances of your Medusa application:
1. A server instance that handles incoming requests to the application's API routes.
2. A worker instance that processes background tasks. This includes scheduled jobs and subscribers.
You don't need to set up different projects for each instance. Instead, you can configure the Medusa application to run in different modes based on environment variables, as you'll see later in this chapter.
This separation ensures that the server instance remains responsive to incoming requests, while the worker instance processes tasks in the background.
![Diagram showcasing how the server and worker work together](https://res.cloudinary.com/dza7lstvk/image/upload/fl_lossy/f_auto/r_16/ar_16:9,c_pad/v1/Medusa%20Book/medusa-worker_klkbch.jpg?_a=BATFJtAA0)
---
## How to Set Worker Mode
You can set the worker mode of your application using the `projectConfig.workerMode` configuration in the `medusa-config.ts`. The `workerMode` configuration accepts the following values:
- `shared`: (default) run the application in a single process, meaning the worker and server run in the same process.
- `worker`: run a worker process only.
- `server`: run the application server only.
Instead of creating different projects with different worker mode configurations, you can set the worker mode using an environment variable. Then, the worker mode configuration will change based on the environment variable.
For example, set the worker mode in `medusa-config.ts` to the following:
```ts title="medusa-config.ts"
module.exports = defineConfig({
projectConfig: {
workerMode: process.env.WORKER_MODE || "shared",
// ...
},
// ...
})
```
You set the worker mode configuration to the `process.env.WORKER_MODE` environment variable and set a default value of `shared`.
Then, in the deployed server Medusa instance, set `WORKER_MODE` to `server`, and in the worker Medusa instance, set `WORKER_MODE` to `worker`:
<CodeTabs group="worker-mode-env">
<CodeTab label="Server Medusa Instance" value="server">
```bash
WORKER_MODE=server
```
</CodeTab>
<CodeTab label="Worker Medusa Instance" value="worker">
```bash
WORKER_MODE=worker
```
</CodeTab>
</CodeTabs>
### Disable Admin in Worker Mode
Since the worker instance only processes background tasks, you should disable the admin interface in it. That will save resources in the worker instance.
To disable the admin interface, set the `admin.disable` configuration in the `medusa-config.ts` file:
```ts title="medusa-config.ts"
module.exports = defineConfig({
admin: {
disable: process.env.ADMIN_DISABLED === "true" ||
false,
},
// ...
})
```
Similar to before, you set the value in an environment variable, allowing you to enable or disable the admin interface based on the environment.
Then, in the deployed server Medusa instance, set `ADMIN_DISABLED` to `false`, and in the worker Medusa instance, set `ADMIN_DISABLED` to `true`:
<CodeTabs group="worker-mode-env">
<CodeTab label="Server Medusa Instance" value="server">
```bash
ADMIN_DISABLED=false
```
</CodeTab>
<CodeTab label="Worker Medusa Instance" value="worker">
```bash
ADMIN_DISABLED=true
```
</CodeTab>
</CodeTabs>

View File

@@ -1,7 +1,7 @@
export const generatedEditDates = {
"app/learn/fundamentals/scheduled-jobs/page.mdx": "2024-12-09T10:51:40.570Z",
"app/learn/fundamentals/workflows/page.mdx": "2024-12-09T14:45:17.837Z",
"app/learn/deployment/page.mdx": "2025-03-06T09:15:39.707Z",
"app/learn/deployment/page.mdx": "2025-03-11T14:53:25.540Z",
"app/learn/page.mdx": "2025-03-11T10:17:39.318Z",
"app/learn/fundamentals/modules/commerce-modules/page.mdx": "2024-12-09T10:46:29.339Z",
"app/learn/fundamentals/workflows/retry-failed-steps/page.mdx": "2024-12-04T07:37:59.823Z",
@@ -73,7 +73,7 @@ export const generatedEditDates = {
"app/learn/fundamentals/module-links/custom-columns/page.mdx": "2025-03-11T13:29:54.752Z",
"app/learn/fundamentals/module-links/directions/page.mdx": "2024-12-12T15:31:31.555Z",
"app/learn/fundamentals/module-links/page.mdx": "2025-03-11T13:39:14.345Z",
"app/learn/fundamentals/module-links/query/page.mdx": "2025-02-04T07:35:31.633Z",
"app/learn/fundamentals/module-links/query/page.mdx": "2025-03-11T15:35:10.605Z",
"app/learn/fundamentals/modules/db-operations/page.mdx": "2024-12-09T14:40:50.581Z",
"app/learn/fundamentals/modules/multiple-services/page.mdx": "2024-10-21T13:30:21.370Z",
"app/learn/fundamentals/modules/page.mdx": "2025-03-11T13:00:37.391Z",
@@ -97,12 +97,12 @@ export const generatedEditDates = {
"app/learn/customization/integrate-systems/service/page.mdx": "2024-12-09T11:02:39.594Z",
"app/learn/customization/next-steps/page.mdx": "2024-12-06T14:34:53.356Z",
"app/learn/fundamentals/modules/architectural-modules/page.mdx": "2024-10-21T13:30:21.367Z",
"app/learn/introduction/architecture/page.mdx": "2025-01-16T10:25:10.780Z",
"app/learn/introduction/architecture/page.mdx": "2025-03-11T15:28:01.187Z",
"app/learn/fundamentals/data-models/infer-type/page.mdx": "2024-12-09T15:54:08.713Z",
"app/learn/fundamentals/custom-cli-scripts/seed-data/page.mdx": "2024-12-09T14:38:06.385Z",
"app/learn/fundamentals/environment-variables/page.mdx": "2025-03-11T08:55:03.343Z",
"app/learn/build/page.mdx": "2024-12-09T11:05:17.383Z",
"app/learn/deployment/general/page.mdx": "2025-03-11T08:53:37.292Z",
"app/learn/deployment/general/page.mdx": "2025-03-11T15:30:23.949Z",
"app/learn/fundamentals/workflows/multiple-step-usage/page.mdx": "2024-11-25T16:19:32.169Z",
"app/learn/installation/page.mdx": "2025-03-11T08:55:12.967Z",
"app/learn/fundamentals/data-models/check-constraints/page.mdx": "2024-12-06T14:34:50.384Z",
@@ -119,6 +119,7 @@ export const generatedEditDates = {
"app/learn/resources/contribution-guidelines/admin-translations/page.mdx": "2025-02-11T16:57:46.726Z",
"app/learn/resources/contribution-guidelines/docs/page.mdx": "2025-03-06T09:32:26.010Z",
"app/learn/resources/usage/page.mdx": "2025-02-26T13:35:34.824Z",
"app/learn/configurations/medusa-config/page.mdx": "2025-03-11T08:50:04.239Z",
"app/learn/configurations/ts-aliases/page.mdx": "2025-02-11T16:57:46.683Z"
"app/learn/configurations/medusa-config/page.mdx": "2025-03-11T14:27:04.528Z",
"app/learn/configurations/ts-aliases/page.mdx": "2025-02-11T16:57:46.683Z",
"app/learn/production/worker-mode/page.mdx": "2025-03-11T15:21:50.906Z"
}

View File

@@ -1152,6 +1152,16 @@ export const generatedSidebars = [
"chapterTitle": "8.1. Build",
"number": "8.1."
},
{
"loaded": true,
"isPathHref": true,
"type": "link",
"path": "/learn/production/worker-mode",
"title": "Worker Mode",
"children": [],
"chapterTitle": "8.2. Worker Mode",
"number": "8.2."
},
{
"loaded": true,
"isPathHref": true,
@@ -1166,12 +1176,12 @@ export const generatedSidebars = [
"path": "/learn/deployment/general",
"title": "General Deployment",
"children": [],
"chapterTitle": "8.2.1. General Deployment",
"number": "8.2.1."
"chapterTitle": "8.3.1. General Deployment",
"number": "8.3.1."
}
],
"chapterTitle": "8.2. Deployment Overview",
"number": "8.2."
"chapterTitle": "8.3. Deployment Overview",
"number": "8.3."
}
],
"chapterTitle": "8. Production",

File diff suppressed because it is too large Load Diff

View File

@@ -605,6 +605,11 @@ export const sidebars = [
path: "/learn/build",
title: "Build",
},
{
type: "link",
path: "/learn/production/worker-mode",
title: "Worker Mode",
},
{
type: "link",
path: "/learn/deployment",