Installing Medusa and Related Services
Last Updated: May 23, 2023
This guide gives step-by-step instructions on how to get Medusa and all of its related services up and running on a fresh Ubuntu 22.04 server. This is the second part in a series of guides that will cover how to deploy Medusa. After Part 1, you should have a server up and running on AWS. If you haven’t done that yet, go back and do it now. This guide will pick up where that one left off.
Contents
- Set Up the Environment
- Postgres
- Redis
- Meilisearch
- Medusa
- Medusa Admin
- Notifications Provider
- Payment Provider
- File Service
- Search
Set Up the Environment
Update Ubuntu
Before anything else, let’s make sure the server is up to date.
sudo apt update && sudo apt upgrade -y
Timezone
Setting your timezone is useful so that customer order date/times (and any other created_at values in your database) make sense and don’t have to be translated form GMT. Set your timezone and then reboot to make sure the change takes effect.
This example is for New York. Change it to your timezone. You can find the full list of available options here.
sudo timedatectl set-timezone America/New_York
sudo reboot
Install Node.js v18.x
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
node -v
If you don’t see v18.x, something went wrong. Avoid using Node v20. Many apps and libraries are not yet compatible with it.
Install Yarn
sudo npm install --global yarn
yarn -v
Configure Yarn
These changes will make it easier to run the Medusa CLI from the command line.
yarn config set prefix ~/.yarn
nano ~/.bashrc
Use the down arrow key to go to the bottom of the file and add the following line:
export PATH="$PATH:`yarn global bin`"
Press CTRL
+X
to exit, then Y
to save, then ENTER
to confirm.
Reload your bash profile:
source ~/.bashrc
Postgres
Install Postgres
sudo apt -y install postgresql
sudo systemctl enable postgresql
Generate a password for the postgres user
An easy way to generate good keys is by using the openssl
command. The maximum length of a Postgres password is 63 characters. The command below will generate a 60 character password. You can generate a longer password if you want, but it will be truncated to 63 characters.
openssl rand -hex 30
Update the password and create a database for Medusa
First, we open the postgres client.
sudo -u postgres psql
Then, we update the password for the postgres user and create a database for Medusa.
ALTER USER postgres PASSWORD 'the-password-you-generated-above';
create database medusa;
\q
Redis
Install Redis
curl -fsSL https://packages.redis.io/gpg |
sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main"
| sudo tee /etc/apt/sources.list.d/redis.list
sudo apt update
sudo apt install redis
sudo systemctl enable redis-server
sudo service redis-server start
redis-cli ping
You should see PONG
as the response. Otherwise, something went wrong.
Meilisearch
Install Meilisearch
curl -OL "https://github.com/meilisearch/meilisearch/releases/download/v1.1.1/meilisearch.deb"
sudo apt install ./meilisearch.deb
meilisearch --version
Meilisearch is now installed, but we still need to set it up as a proper systemd service, which is not done for us out of the box. We also need to generate a ‘master key,’ which you can think of as the meilisearch password.
Generate a Key
An easy way to generate good keys is by using the openssl
command.
openssl rand -hex 32
Configuring as a Service
There are a lot of benefits to running meilisearch as a service in this sort of all-in-one Medusa setup. This way, if the server goes down for any reason, the meilisearch service will automatically restart. You also don’t have to keep the master key handy to cut and paste every time you want to start meilisearch.
Create a working directory and then create a systemd service file:
sudo mkdir /var/meilisearch
sudo nano /etc/systemd/system/meilisearch.service
Copy and paste the following into the file:
[Unit]
Description=Meilisearch
After=systemd-user-sessions.service
[Service]
Type=simple
WorkingDirectory=/var/meilisearch
ExecStart=/usr/bin/meilisearch --env "production" --master-key "the-key-you-generated-above"
Restart=always
[Install]
WantedBy=multi-user.target
Press CTRL
+X
to exit, then Y
to save, then ENTER
to confirm.
Now, enable the service and start it:
sudo systemctl enable meilisearch
sudo service meilisearch start
Medusa
If any step below fails, check the Backend Setup guide in the Medusa Docs in case something has been changed.
Install Medusa CLI and Create a New Project
yarn global add @medusajs/medusa-cli
medusa new medusa-backend
cd medusa-backend
yarn install
Update the Environment Variables
Create two more strings using openssl rand -hex 32. One will be used for the session secret and the other for the cookie secret.
openssl rand -hex 32
openssl rand -hex 32
nano .env
Add the two strings to the .env file and update the database credentials and your CORS settings.
JWT_SECRET="string1-generated-above"
COOKIE_SECRET="string2-generated-above"
ADMIN_CORS="http://localhost:7000,http://localhost:7001"
STORE_CORS="http://localhost:8000,http://localhost:5173"
DATABASE_TYPE="postgres"
DATABASE_URL="postgresql://postgres:the-password-you-generated-earlier@localhost:5432/medusa?schema=public"
REDIS_URL=redis://localhost:6379
A full discussion of CORS is outside the scope of this guide. For now, just add the urls you will be using to access the admin and store.
Press CTRL
+X
to exit, then Y
to save, then ENTER
to confirm.
Run the Migrations and Seed the Database
This will create the tables in the database.
npx @medusajs/medusa migrations run
If you want to seed the database with some sample data, you can run the following command:
npx @medusajs/medusa seed -f data/seed.json
If you don’t want to seed the database, you should add a user so that you can log into the the admin app.
npx @medusajs/medusa user -e '[email protected]' -p 'some-password'
Enable Redis for Caching and the Event Bus
Before starting our server, let’s also make sure we enable Redis.
nano medusa-config.js
Uncomment the Redis-related lines in modules
and projectConfig
:
const modules = {
eventBus: {
resolve: "@medusajs/event-bus-redis",
options: {
redisUrl: REDIS_URL
}
},
cacheService: {
resolve: "@medusajs/cache-redis",
options: {
redisUrl: REDIS_URL
}
},
}
const projectConfig = {
...
redis_url: REDIS_URL
}
Calm Your Mind and Think Happy Thoughts
Now, the moment of truth. Start the server:
yarn dev
If everything went well, you should see some startup messages, and then the following message:
Server is ready on port: 9000
Install the Admin
Install the Admin Package
yarn add @medusajs/admin
Configure the Admin
Uncomment the following lines in the plugins
array in medusa-config.js
:
{
resolve: "@medusajs/admin",
/** @type {import('@medusajs/admin').PluginOptions} */
options: {
autoRebuild: true,
},
},
Notifications Provider
You will want to install a notification provider to send email notifications to your customers. The most popular option is medusa-plugin-sendgrid. We will use AWS SES in this guide because I am most familiar with it
Install the Plugin
The following instructions are for AWS SES. If you are using a different provider, you will need to adjust the instructions accordingly.
yarn add medusa-plugin-ses
Update Your Environment Variables
Open your .env
file and add the following:
SES_REGION=""
SES_ACCESS_KEY_ID=""
SES_SECRET_ACCESS_KEY=""
SES_FROM="[email protected] <[email protected]>"
SES_TEMPLATE_PATH="data/templates"
SES_REGION will be for example “us-east-1”
Obtain the access key id and secret access key by creating an IAM user with SES send permissions.
The SES_FROM email address must be a verified sender in your AWS account.
The template path is where the Handlebars email templates will be stored.
Update Your Config File
Open your medusa-config.js
file and add the following:
{
resolve: `medusa-plugin-ses`,
options: {
access_key_id: process.env.SES_ACCESS_KEY_ID,
secret_access_key: process.env.SES_SECRET_ACCESS_KEY,
region: process.env.SES_REGION,
from: process.env.SES_FROM,
enable_endpoint: process.env.SES_ENABLE_ENDPOINT,
template_path: process.env.SES_TEMPLATE_PATH,
order_placed_template: 'order_placed',
order_shipped_template: 'order_shipped',
customer_password_reset_template: 'customer_password_reset',
gift_card_created_template: 'gift_card_created',
//order_canceled_template: 'order_canceled',
//order_refund_created_template: 'order_refund_created',
//order_return_requested_template: 'order_return_requested',
//order_items_returned_template: 'order_items_returned',
//swap_created_template: 'swap_created',
//swap_shipment_created_template: 'swap_shipment_created',
//swap_received_template: 'swap_received',
//claim_shipment_created_template: 'claim_shipment_created',
//user_password_reset_template: 'user_password_reset',
//medusa_restock_template: 'medusa_restock',
}
},
You only need to uncomment the templates you want to use. If there is no template for a type of event, then no notifications will be sent for events of that type.
Templates
Create a ‘data/templates’ folder if you used the default SES_TEMPLATE_PATH variable above. You can specify a full or absolute path.
medusa-server // root directory
|-data
|-templates
|-order_placed // or whatever you name your templates and specify in the config file
|-subject.hbs
|-html.hbs
|-text.hbs
|-gift_card_created
|-subject.hbs
|-html.hbs
|-text.hbs
|- etc
Payment Provider
There are several payment providers to choose from, and not all are available in all regions. My personal preference is Stripe.
Refer to this guide to set up Stripe
File Service Provider
You will need to choose a file service provider to store your product images. The most popular options are AWS S3 and MinIO.
Refer to this guide to set up AWS S3
Install Search Plugin
We’re already most of the way there since we installed meilisearch along with our other services earlier. We just need to install the plugin and configure it.
Install medusa-plugin-meilisearch
yarn add medusa-plugin-meilisearch
Update Your Environment Variables
Open your .env
file and add the following:
MEILISEARCH_HOST="http://localhost:7700"
MEILISEARCH_API_KEY="the-master-key-you-generated-earlier"
Open medusa-config.js
and add the following to the plugins
array:
const plugins = [
...
{
resolve: `medusa-plugin-meilisearch`,
options: {
config: {
host: process.env.MEILISEARCH_HOST,
apiKey: process.env.MEILISEARCH_API_KEY,
},
settings: {
products: {
indexSettings: {
searchableAttributes: [
"title",
"description",
"variant_sku",
],
displayedAttributes: [
"title",
"description",
"variant_sku",
"thumbnail",
"handle",
],
},
primaryKey: "id",
transform: (product) => ({
id: product.id,
// other attributes...
}),
},
},
},
},
]