JS
Medusa
What is Medusa?
Medusa is an ecommerce platform with a built-in framework for customization that allows you to build custom commerce applications without reinventing core commerce logic.
Installation
Run the following command and replace <NAME>
and <DATABASE_URL>
with your store name:
$ npx create-medusa-app@latest <NAME> --with-nextjs-starter --db-url "<DATABASE_URL>" --no-migrations
Medusa CLI
$ npx medusa user -e admin@medusajs.com -p supersecret
Deployment
Railway
- Click on Create on right top corner
- Choose GitHub Repo
- Select or authorize the
Medusa Backend
repository from your own GitHub account - Open the Variables tab by clicking on the newly created service
- Deploy the new service
NODE_ENV="production"
PORT="9000"
ADMIN_CORS=https://${{RAILWAY_PUBLIC_DOMAIN}},https://${{RAILWAY_PRIVATE_DOMAIN}}
AUTH_CORS=https://${{RAILWAY_PUBLIC_DOMAIN}},https://${{RAILWAY_PRIVATE_DOMAIN}}
STORE_CORS=${{Storefront.NEXT_PUBLIC_BASE_URL}}
COOKIE_SECRET=supersecret
JWT_SECRET=supersecret
DATABASE_URL=${{Postgres.DATABASE_URL}}
REDIS_URL=${{Redis.REDIS_URL}}?family=0
S3_ACCESS_KEY_ID=<IAM_USER_ACCESS_KEY_ID>
S3_SECRET_ACCESS_KEY=<IAM_USER_SECRET_ACCESS_KEY>
S3_BUCKET=<bucket_name>
S3_ENDPOINT=https://s3.<region>.amazonaws.com
S3_FILE_URL=https://<bucket_name>.s3.<region>.amazonaws.com
S3_REGION=<region>
Storefront
- Click on Create on right top corner
- Choose GitHub Repo
- Select or authorize the
Medusa Storefront
repository from your own GitHub account - Open the Variables tab by clicking on the newly created service
- Deploy the new service
PORT=8000
MEDUSA_BACKEND_URL=https://${{Backend.RAILWAY_PUBLIC_DOMAIN}}
NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY=pk_*****************
NEXT_PUBLIC_BASE_URL=https://${{RAILWAY_PUBLIC_DOMAIN}}
NEXT_PUBLIC_DEFAULT_REGION=us
NEXT_PUBLIC_STRIPE_KEY=
REVALIDATE_SECRET=supersecret
S3_FILE_URL=<bucket_name>.s3.<region>.amazonaws.com
- Open the Settings tab by clicking on the newly created service
- Click on **Custom Domain ** under Public Networking, select the port in the dropdown menu or type
8000
which was defined in the Variables.
Modules
Redis
import { Modules } from "@medusajs/framework/utils"
// ...
module.exports = defineConfig({
// ...
modules: [
{
resolve: "@medusajs/medusa/cache-redis",
options: {
redisUrl: process.env.CACHE_REDIS_URL,
},
},
],
})
AWS S3 Storage
- Create AWS user with
AmazonS3FullAccess
permissions. - Create AWS IAM user access key ID and secret access key.
- Create S3 bucket with the "Public Access setting" enabled:
- On your bucket's dashboard, click on the Permissions tab.
- Click on the Edit button of the Block public access (bucket settings) section.
- In the form that opens, don't toggle any checkboxes and click the "Save changes" button.
- Confirm saving the changes by entering
confirm
in the pop-up that shows. - Back on the Permissions page, scroll to the Object Ownership section and click the Edit button.
- In the form that opens:
- Choose the "ACLs enabled" card.
- Click on the "Save changes" button.
- Back on the Permissions page, scroll to the "Access Control List (ACL)" section and click on the Edit button.
- In the form that opens, enable the Read permission for "Everyone (public access)".
- Check the "I understand the effects of these changes on my objects and buckets." checkbox.
- Click on the "Save changes" button.
Essential Modules Config
import { loadEnv, defineConfig, Modules } from '@medusajs/framework/utils'
loadEnv(process.env.NODE_ENV || 'development', process.cwd())
module.exports = defineConfig({
projectConfig: {
databaseUrl: process.env.DATABASE_URL,
redisUrl: process.env.REDIS_URL,
databaseLogging: false,
http: {
storeCors: process.env.STORE_CORS!,
adminCors: process.env.ADMIN_CORS!,
authCors: process.env.AUTH_CORS!,
jwtSecret: process.env.JWT_SECRET || "supersecret",
cookieSecret: process.env.COOKIE_SECRET || "supersecret",
}
},
modules: [
{
key: Modules.CACHE,
resolve: "@medusajs/cache-redis",
options: {
redisUrl: process.env.REDIS_URL,
ttl: 30, // Time to live in seconds
},
},
{
key: Modules.EVENT_BUS,
resolve: "@medusajs/event-bus-redis",
options: {
redisUrl: process.env.REDIS_URL,
},
},
{
key: Modules.WORKFLOW_ENGINE,
resolve: '@medusajs/workflow-engine-redis',
options: {
redis: {
url: process.env.REDIS_URL,
},
},
},
{
key: Modules.FILE,
resolve: "@medusajs/medusa/file",
options: {
providers: [
{
resolve: "@medusajs/medusa/file-s3",
id: "s3",
options: {
file_url: process.env.S3_FILE_URL,
access_key_id: process.env.S3_ACCESS_KEY_ID,
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
region: process.env.S3_REGION,
bucket: process.env.S3_BUCKET,
endpoint: process.env.S3_ENDPOINT,
},
},
],
},
...(process.env.SENDGRID_API_KEY && process.env.SENDGRID_FROM_EMAIL ? [{
key: Modules.NOTIFICATION,
resolve: '@medusajs/notification',
options: {
providers: [
...(process.env.SENDGRID_API_KEY && process.env.SENDGRID_FROM_EMAIL ? [{
resolve: '@medusajs/notification-sendgrid',
id: 'sendgrid',
options: {
channels: ['email'],
api_key: process.env.SENDGRID_API_KEY,
from: process.env.SENDGRID_FROM_EMAIL,
}
}] : []),
]
}
}] : []),
...(process.env.STRIPE_API_KEY && process.env.STRIPE_WEBHOOK_SECRET ? [{
key: Modules.PAYMENT,
resolve: '@medusajs/payment',
options: {
providers: [
{
resolve: '@medusajs/payment-stripe',
id: 'stripe',
options: {
apiKey: process.env.STRIPE_API_KEY,
webhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
},
},
],
},
}] : [])
},
],
})
Troubleshooting
Module @medusajs/cache-redis doesn't have a serviceName. Please provide a 'key' for the module or check the service joiner config.
- Open the
medsua-config.ts
file in Medusa backend repository
import { Modules } from "@medusajs/framework/utils"
//...
modules: [
{
key: Modules.CACHE,
resolve: "@medusajs/cache-redis",
options: {
redisUrl: process.env.REDIS_URL,
ttl: 30, // Time to live in seconds
},
},
//...
Make sure the modules used have the key