diff --git a/www/apps/book/.gitignore b/www/apps/book/.gitignore
index 25bbb4b9c1180..98297a172f7b0 100644
--- a/www/apps/book/.gitignore
+++ b/www/apps/book/.gitignore
@@ -15,6 +15,7 @@
# production
/build
+!/app/learn/build
# misc
.DS_Store
diff --git a/www/apps/book/app/learn/build/page.mdx b/www/apps/book/app/learn/build/page.mdx
new file mode 100644
index 0000000000000..d0cc43bee76e6
--- /dev/null
+++ b/www/apps/book/app/learn/build/page.mdx
@@ -0,0 +1,80 @@
+export const metadata = {
+ title: `${pageNumber} Build Medusa Application`,
+}
+
+# {metadata.title}
+
+In this chapter, you'll learn how to create a production build of your Medusa application to be deployed to a hosting provider.
+
+Next chapters explain how to deploy the Medusa application.
+
+## build Command
+
+The Medusa CLI tool has a [build](!resources!/medusa-cli/commands/build) command which creates a standalone build of the Medusa application that:
+
+- Doesn't rely on the source TypeScript files.
+- Can be copied to a production server reliably.
+
+So, to create the production build, run the following command in the root of your Medusa application:
+
+```bash
+npx medusa build
+```
+
+---
+
+## Build Output
+
+The `build` command outputs the production build in the `.medusa/server` directory, and the admin dashboard build in the `.medusa/server/public/admin`.
+
+### Separate Admin Build
+
+The `build` command accepts a `--admin-only` option that outputs the admin to the `.medusa/admin` directory. This is useful when deploying the admin dashboard separately, such as on Vercel:
+
+```bash
+npx medusa build --admin-only
+```
+
+---
+
+## Start Built Medusa Application
+
+To start the Medusa application after running the `build` command:
+
+- Change to the `.medusa/server` directory and install the dependencies:
+
+```bash npm2yarn
+cd .medusa/server && npm install
+```
+
+- When running the application locally, make sure to copy the `.env` file from the root project's directory. In production, use system environment variables instead.
+
+```bash title=".medusa/server"
+cp ../../.env .env.production
+```
+
+
+
+When `NODE_ENV=production`, the Medusa application loads the environment variables from `.env.production`. Learn more about environment variables in [this guide](../advanced-development/environment-variables/page.mdx).
+
+
+
+- In the system environment variables, set `NODE_ENV` to `production`:
+
+```bash
+NODE_ENV=production
+```
+
+- Use the `start` command in the `.medusa/server` directory to run the application:
+
+```bash npm2yarn title=".medusa/server"
+npm run start
+```
+
+---
+
+## Deploying Production Build
+
+The next chapter covers how you generally deploy the production build.
+
+You can also refer to the [deployment how-to guides](!resources!/deployment) for platform-specific how-to guides.
diff --git a/www/apps/book/app/learn/deployment/general/page.mdx b/www/apps/book/app/learn/deployment/general/page.mdx
new file mode 100644
index 0000000000000..b77d1d9548816
--- /dev/null
+++ b/www/apps/book/app/learn/deployment/general/page.mdx
@@ -0,0 +1,331 @@
+import { Prerequisites } from "docs-ui"
+
+export const metadata = {
+ title: `General Medusa Application Deployment Guide`,
+}
+
+# {metadata.title}
+
+In this document, you'll learn the general steps to deploy your Medusa application. How you apply these steps depend on your chosen hosting provider or platform.
+
+
+
+Find how-to guides for specific platforms in [this documentation](!resources!/deployment).
+
+
+
+
+
+## Hosting Provider Requirements
+
+When you deploy your Medusa application, make sure your chosen hosting provider supports deploying the following resources:
+
+1. PostgreSQL database: If your hosting provider doesn't support database hosting, you must find another hosting provider for the PostgreSQL database.
+2. Redis database: If your hosting provider doesn't support database hosting, you must find another hosting provider for the Redis database.
+3. Medusa application in server and worker mode. This means your hosting provider should support deploying two applications or instances from the same codebase.
+5. If you're also hosting the Medusa Admin with the server, the hosting provider and plan should offer at least 2GB of RAM.
+
+---
+
+## 1. Configure Medusa Application
+
+### Worker Mode
+
+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.
+
+Learn more about the `workerMode` configuration in [this document](!resources!/references/medusa-config#workermode).
+
+So, add the following configuration in `medusa-config.ts`:
+
+```ts title="medusa-config.ts"
+module.exports = defineConfig({
+ projectConfig: {
+ // ...
+ workerMode: process.env.MEDUSA_WORKER_MODE as "shared" | "worker" | "server",
+ },
+})
+```
+
+Later, you’ll set different values of the `MEDUSA_WORKER_MODE` environment variable for each Medusa application deployment or instance.
+
+### Configure Medusa Admin
+
+There are two cases where you may disable the Medusa Admin in your deployed Medusa application:
+
+1. If you choose to host it separately.
+2. In the Medusa application running in worker mode, as it doesn’t need to run the admin.
+
+
+
+To host the admin with the Medusa application, the hosting provider and plan should offer at least 2GB of RAM.
+
+
+
+So, add the following configuration in `medusa-config.ts`:
+
+```ts title="medusa-config.ts"
+module.exports = defineConfig({
+ // ...
+ admin: {
+ disable: process.env.DISABLE_MEDUSA_ADMIN === "true",
+ },
+})
+```
+
+Later, you’ll set different values of the `DISABLE_MEDUSA_ADMIN` environment variable.
+
+### Configure Redis URL
+
+The `redisUrl` configuration specifies the connection URL to Redis to store the Medusa server's session.
+
+
+
+Learn more in the [Medusa Configuration documentation](!resources!/references/medusa-config#redisurl).
+
+
+
+So, add the following configuration in `medusa-config.ts` :
+
+```ts title="medusa-config.ts"
+module.exports = defineConfig({
+ projectConfig: {
+ // ...
+ redisUrl: process.env.REDIS_URL,
+ },
+})
+```
+
+---
+
+## 2. Add predeploy Script
+
+Before you start the Medusa application in production, you should always run migrations and sync links.
+
+So, add the following script in `package.json`:
+
+```json
+"scripts": {
+ // ...
+ "predeploy": "medusa db:migrate"
+},
+```
+
+---
+
+## 3. Install Production Modules and Providers
+
+By default, your Medusa application uses modules and providers useful for development, such as the In-Memory Cache Module or the Local File Module Provider.
+
+It’s highly recommended to instead use modules and providers suitable for production, including:
+
+- [Redis Cache Module](!resources!/architectural-modules/cache/redis)
+- [Redis Event Bus Module](!resources!/architectural-modules/event/redis)
+- [Workflow Engine Redis Module](!resources!/architectural-modules/workflow-engine/redis)
+- [S3 File Module Provider](!resources!/architectural-modules/file/s3) (or other file module providers production-ready).
+- [SendGrid Notification Module Provider](!resources!/architectural-modules/notification/sendgrid) (or other notification module providers production-ready).
+
+Then, add these modules in `medusa-config.ts`:
+
+```ts title="medusa-config.ts"
+import { Modules } from "@medusajs/framework/utils"
+
+module.exports = defineConfig({
+ // ...
+ modules: [
+ {
+ resolve: "@medusajs/medusa/cache-redis",
+ options: {
+ redisUrl: process.env.REDIS_URL,
+ },
+ },
+ {
+ resolve: "@medusajs/medusa/event-bus-redis",
+ options: {
+ redisUrl: process.env.REDIS_URL,
+ },
+ },
+ {
+ resolve: "@medusajs/medusa/workflow-engine-redis",
+ options: {
+ redis: {
+ url: process.env.REDIS_URL,
+ },
+ },
+ },
+ ]
+})
+```
+
+
+
+Check out the [Integrations](!resources!/integrations) and [Architectural Modules](!resources!/architectural-modules) documentation for other modules and providers to use.
+
+
+
+---
+
+## 4. Create PostgreSQL and Redis Databases
+
+Your Medusa application must connect to PostgreSQL and Redis databases. So, before you deploy it, create production PostgreSQL and Redis databases.
+
+If your hosting provider doesn't support databases, you can use [Neon for PostgreSQL database hosting](https://neon.tech/), and [Redis Cloud for the Redis database hosting](https://redis.io/cloud/).
+
+After hosting both databases, keep their connection URLs for the next steps.
+
+---
+
+## 5. Deploy Medusa Application in Server Mode
+
+As mentioned earlier, you'll deploy two instances or create two deployments of your Medusa application: one in server mode, and the other in worker mode.
+
+The deployment steps depend on your hosting provider. This section provides the general steps to perform during the deployment.
+
+### Set Environment Variables
+
+When setting the environment variables of the Medusa application, set the following variables:
+
+```bash
+COOKIE_SECRET=supersecret # TODO GENERATE SECURE SECRET
+JWT_SECRET=supersecret # TODO GENERATE SECURE SECRET
+STORE_CORS= # STOREFRONT URL
+ADMIN_CORS= # ADMIN URL
+AUTH_CORS= # STOREFRONT AND ADMIN URLS, SEPARATED BY COMMAS
+# change to false if you're hosting the admin with the application
+DISABLE_MEDUSA_ADMIN=true
+MEDUSA_WORKER_MODE=server
+PORT=9000
+DATABASE_URL # POSTGRES DATABASE URL
+REDIS_URL= # REDIS DATABASE URL
+```
+
+Where:
+
+- The value of `COOKIE_SECRET` and `JWT_SECRET` must be a randomly generated secret.
+- `STORE_CORS`'s value is the URL of your storefront. If you don’t have it yet, you can skip adding it for now.
+- `ADMIN_CORS`'s value is the URL of the admin dashboard. If you don’t have it yet, or you’re deploying the admin with the Medusa application, you can skip adding it for now.
+- `AUTH_CORS`'s value is the URLs of any application authenticating users, customers, or other actor types, such as the storefront and admin URLs. The URLs are separated by commas. If you don’t have the URLs yet, you can set its value later.
+- Change `DISABLE_MEDUSA_ADMIN` to `false` if you’re hosting the admin with the Medusa application.
+- Set the PostgreSQL database's connection URL as the value of `DATABASE_URL`
+- Set the Redis database's connection URL as the value of `REDIS_URL`.
+
+Feel free to add any other relevant environment variables, such as for integrations and architectural modules.
+
+### Set Start Command
+
+The Medusa application's production build, which is created using the `build` command, outputs the Medusa application to `.medusa/server`.
+
+So, you must run the `start` command from the `.medusa/server` directory.
+
+If your hosting provider doesn't support setting a current-working directory, set the start command to the following:
+
+```bash npm2yarn
+cd .medusa/server && npm run predeploy && npm run start
+```
+
+### Additional Configuration if Deploying with Admin
+
+If you’re deploying the Medusa application in server mode with the admin, you have to make some changes after you’ve obtained the application’s URL.
+
+First, add the following configuration to `medusa-config.ts`:
+
+```ts title="medusa-config.ts"
+module.exports = defineConfig({
+ // ...
+ admin: {
+ // ...
+ backendUrl: process.env.MEDUSA_BACKEND_URL,
+ },
+})
+```
+
+Then, push the changes to the GitHub repository or deployed application.
+
+In your hosting provider, add or modify the following environment variables for the Medusa application in server mode:
+
+```bash
+ADMIN_CORS= # MEDUSA APPLICATION URL
+AUTH_CORS= # ADD MEDUSA APPLICATION URL
+MEDUSA_BACKEND_URL= # URL TO DEPLOYED MEDUSA APPLICATION
+```
+
+Where you set the value of `ADMIN_CORS` and `MEDUSA_BACKEND_URL` to the Medusa application’s URL, and you add the URL to `AUTH_CORS`.
+
+
+
+Remember to separate URLs in `AUTH_CORS` by commas.
+
+
+
+---
+
+## 6. Deploy Medusa Application in Worker Mode
+
+Next, you'll deploy the Medusa application in worker mode.
+
+As explained in the previous section, the deployment steps depend on your hosting provider. This section provides the general steps to perform during the deployment.
+
+### Set Environment Variables
+
+When setting the environment variables of the Medusa application, set the following variables:
+
+```bash
+COOKIE_SECRET=supersecret # TODO GENERATE SECURE SECRET
+JWT_SECRET=supersecret # TODO GENERATE SECURE SECRET
+DISABLE_MEDUSA_ADMIN=true
+MEDUSA_WORKER_MODE=worker
+PORT=9000
+DATABASE_URL # POSTGRES DATABASE URL
+REDIS_URL= # REDIS DATABASE URL
+```
+
+Where:
+
+- The value of `COOKIE_SECRET` and `JWT_SECRET` must be a randomly generated secret.
+- Keep `DISABLE_MEDUSA_ADMIN`'s value set to `true`, even if you’re hosting the admin with the Medusa application.
+- Set the PostgreSQL database's connection URL as the value of `DATABASE_URL`
+- Set the Redis database's connection URL as the value of `REDIS_URL`.
+
+Feel free to add any other relevant environment variables, such as for integrations and architectural modules.
+
+### Set Start Command
+
+The Medusa application's production build, which is created using the `build` command, outputs the Medusa application to `.medusa/server`.
+
+So, you must run the `start` command from the `.medusa/server` directory.
+
+If your hosting provider doesn't support setting a current-working directory, set the start command to the following:
+
+```bash npm2yarn
+cd .medusa/server && npm run predeploy && npm run start
+```
+
+---
+
+## 7. Test Deployed Application
+
+Once the application is deployed and live, go to `/health`, where `` is the URL of the Medusa application in server mode. If the deployment was successful, you’ll see the `OK` response.
+
+### Open Deployed Medusa Admin
+
+If you deployed the Medusa Admin with the application, it’ll be available at `/app`.
+
+---
+
+## Create Admin User
+
+If your hosting provider supports running commands in your Medusa application's directory, run the following command to create an admin user:
+
+```bash
+npx medusa user -e admin-medusa@test.com -p supersecret
+```
+
+Replace the email `admin-medusa@test.com` and password `supersecret` with the credentials you want.
+
+You can use these credentials to log into the Medusa Admin dashboard.
diff --git a/www/apps/book/app/learn/deployment/page.mdx b/www/apps/book/app/learn/deployment/page.mdx
index 4c91773771786..0e8f161f1ff0b 100644
--- a/www/apps/book/app/learn/deployment/page.mdx
+++ b/www/apps/book/app/learn/deployment/page.mdx
@@ -1,5 +1,5 @@
export const metadata = {
- title: `${pageNumber} Deployment Overview`,
+ title: `${pageNumber} Medusa Deployment Overview`,
}
# {metadata.title}
@@ -12,7 +12,7 @@ A standard Medusa project is made up of:
- Medusa application: The Medusa server and the Medusa Admin.
- One or more storefronts
-
+
![Diagram showcasing the connection between the three deployed components](https://res.cloudinary.com/dza7lstvk/image/upload/v1708600807/Medusa%20Book/deployment-options_ceuuvo.jpg)
You can either deploy the Medusa application fully (server with the admin), or deploy the Medusa Admin separately. The storefront is always deployed separately.
@@ -35,7 +35,11 @@ For optimal experience, make sure that the hosting provider and plan offer at le
Your server connects to a PostgreSQL database, Redis, and other services relevant for your setup. Most hosting providers support deploying and managing these databases along with your Medusa server (such as Railway and DigitalOcean).
-Refer to [this reference](!resources!/deployment) to find how-to deployment guides for specific hosting providers.
+### How to Deploy Medusa?
+
+The [next chapter](./general/page.mdx) explains the general steps to deploy your Medusa application.
+
+Refer to [this reference](!resources!/deployment) to find how-to deployment guides for general and specific hosting providers.
---
@@ -51,7 +55,7 @@ In this scenario, make sure the hosting provider and plan of your choice provide
-The server deployment guides mention details on how to deploy the admin with the Medusa server.
+The [server deployment guides](!resources!/deployment) mention details on how to deploy the admin with the Medusa server.
diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs
index 43b7205f0a6f1..cd4087bf6d662 100644
--- a/www/apps/book/generated/edit-dates.mjs
+++ b/www/apps/book/generated/edit-dates.mjs
@@ -1,7 +1,7 @@
export const generatedEditDates = {
"app/learn/basics/scheduled-jobs/page.mdx": "2024-09-30T08:43:53.132Z",
"app/learn/basics/workflows/page.mdx": "2024-09-30T08:43:53.132Z",
- "app/learn/deployment/page.mdx": "2024-08-05T07:24:05+00:00",
+ "app/learn/deployment/page.mdx": "2024-11-11T11:03:59.725Z",
"app/learn/page.mdx": "2024-09-03T07:09:09.034Z",
"app/learn/basics/commerce-modules/page.mdx": "2024-09-30T08:43:53.131Z",
"app/learn/advanced-development/workflows/retry-failed-steps/page.mdx": "2024-09-30T08:43:53.130Z",
@@ -113,5 +113,7 @@ export const generatedEditDates = {
"app/learn/advanced-development/data-models/infer-type/page.mdx": "2024-09-30T08:43:53.123Z",
"app/learn/advanced-development/custom-cli-scripts/seed-data/page.mdx": "2024-10-03T11:11:07.181Z",
"app/learn/basics/modules/page.mdx": "2024-10-16T08:49:39.997Z",
- "app/learn/advanced-development/environment-variables/page.mdx": "2024-10-25T14:59:07.831Z"
+ "app/learn/advanced-development/environment-variables/page.mdx": "2024-10-25T14:59:07.831Z",
+ "app/learn/build/page.mdx": "2024-11-11T11:08:41.832Z",
+ "app/learn/deployment/general/page.mdx": "2024-11-11T11:50:04.248Z"
}
\ No newline at end of file
diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs
index fe8c35acc7ac2..a183dd16e4f54 100644
--- a/www/apps/book/sidebar.mjs
+++ b/www/apps/book/sidebar.mjs
@@ -581,8 +581,21 @@ export const sidebar = numberSidebarItems(
},
{
type: "link",
- path: "/learn/deployment",
- title: "Deployment",
+ path: "/learn/build",
+ title: "Build",
+ chapterTitle: "Production",
+ children: [
+ {
+ type: "link",
+ path: "/learn/deployment",
+ title: "Deployment Overview",
+ },
+ {
+ type: "link",
+ path: "/learn/deployment/general",
+ title: "General Deployment",
+ }
+ ]
},
{
type: "link",
diff --git a/www/apps/resources/app/deployment/medusa-application/railway/page.mdx b/www/apps/resources/app/deployment/medusa-application/railway/page.mdx
index a2a08d0346a36..8640e35046bf3 100644
--- a/www/apps/resources/app/deployment/medusa-application/railway/page.mdx
+++ b/www/apps/resources/app/deployment/medusa-application/railway/page.mdx
@@ -2,7 +2,7 @@
sidebar_label: "Railway"
---
-import { Prerequisites, DetailsList } from "docs-ui"
+import { Prerequisites } from "docs-ui"
export const metadata = {
title: `Deploy Medusa Application to Railway`,
@@ -82,6 +82,14 @@ Later, you’ll set different values of the `DISABLE_MEDUSA_ADMIN` environment v
### Configure Redis URL
+The `redisUrl` configuration specifies the connection URL to Redis to store the Medusa server's session.
+
+
+
+Learn more in the [Medusa Configuration documentation](/references/medusa-config#redisurl).
+
+
+
Add the following configuration in `medusa-config.ts` :
```ts title="medusa-config.ts"
diff --git a/www/apps/resources/app/medusa-cli/commands/build/page.mdx b/www/apps/resources/app/medusa-cli/commands/build/page.mdx
index 14848f481d551..b82b60ad393e7 100644
--- a/www/apps/resources/app/medusa-cli/commands/build/page.mdx
+++ b/www/apps/resources/app/medusa-cli/commands/build/page.mdx
@@ -66,7 +66,13 @@ cd .medusa/server && npm install
- When running the application locally, make sure to copy the `.env` file from the root project's directory. In production, use system environment variables instead.
```bash npm2yarn
-cp .env .medusa/server
+cp .env .medusa/server/.env.production
+```
+
+- In the system environment variables, set `NODE_ENV` to `production`:
+
+```bash
+NODE_ENV=production
```
- Use the `start` command to run the application:
diff --git a/www/apps/resources/generated/edit-dates.mjs b/www/apps/resources/generated/edit-dates.mjs
index 9821f1bb6cdb9..6dcd348075f95 100644
--- a/www/apps/resources/generated/edit-dates.mjs
+++ b/www/apps/resources/generated/edit-dates.mjs
@@ -117,7 +117,7 @@ export const generatedEditDates = {
"app/contribution-guidelines/docs/page.mdx": "2024-10-16T15:48:04.071Z",
"app/create-medusa-app/page.mdx": "2024-08-05T11:10:55+03:00",
"app/deployment/admin/vercel/page.mdx": "2024-10-16T08:10:29.377Z",
- "app/deployment/medusa-application/railway/page.mdx": "2024-10-22T11:02:09.029Z",
+ "app/deployment/medusa-application/railway/page.mdx": "2024-11-11T11:50:10.517Z",
"app/deployment/storefront/vercel/page.mdx": "2024-07-26T07:21:31+00:00",
"app/deployment/page.mdx": "2024-07-25T09:55:22+03:00",
"app/integrations/page.mdx": "2024-10-15T12:26:39.839Z",
@@ -2276,7 +2276,7 @@ export const generatedEditDates = {
"app/commerce-modules/stock-location/links-to-other-modules/page.mdx": "2024-10-15T14:33:11.483Z",
"app/commerce-modules/store/links-to-other-modules/page.mdx": "2024-06-26T07:19:49.931Z",
"app/examples/page.mdx": "2024-10-16T15:47:38.345Z",
- "app/medusa-cli/commands/build/page.mdx": "2024-10-16T08:16:27.618Z",
+ "app/medusa-cli/commands/build/page.mdx": "2024-11-11T11:00:49.665Z",
"app/js-sdk/page.mdx": "2024-10-16T12:12:34.512Z",
"references/js_sdk/admin/Admin/properties/js_sdk.admin.Admin.apiKey/page.mdx": "2024-10-25T15:35:28.397Z",
"references/js_sdk/admin/Admin/properties/js_sdk.admin.Admin.campaign/page.mdx": "2024-10-25T15:35:28.465Z",
diff --git a/www/apps/resources/generated/sidebar.mjs b/www/apps/resources/generated/sidebar.mjs
index 14b1f29357705..3e9724284a900 100644
--- a/www/apps/resources/generated/sidebar.mjs
+++ b/www/apps/resources/generated/sidebar.mjs
@@ -9066,8 +9066,15 @@ export const generatedSidebar = [
"isPathHref": true,
"type": "category",
"title": "Medusa Application",
- "autogenerate_path": "/deployment/medusa-application",
"children": [
+ {
+ "loaded": true,
+ "isPathHref": true,
+ "type": "link",
+ "path": "https://docs.medusajs.com/learn/deployment/general",
+ "title": "General",
+ "children": []
+ },
{
"loaded": true,
"isPathHref": true,
diff --git a/www/apps/resources/sidebar.mjs b/www/apps/resources/sidebar.mjs
index 6b0fdac0e4385..f5b8ade77214d 100644
--- a/www/apps/resources/sidebar.mjs
+++ b/www/apps/resources/sidebar.mjs
@@ -2100,7 +2100,18 @@ export const sidebar = sidebarAttachHrefCommonOptions([
{
type: "category",
title: "Medusa Application",
- autogenerate_path: "/deployment/medusa-application",
+ children: [
+ {
+ type: "link",
+ path: "https://docs.medusajs.com/learn/deployment/general",
+ title: "General"
+ },
+ {
+ type: "link",
+ path: "/deployment/medusa-application/railway",
+ title: "Railway"
+ },
+ ],
},
{
type: "category",