DEV Community

Cover image for Deploying a Medusa + Minio + MeiliSearch stack with Docker and Traefik
Turbo Plebeian
Turbo Plebeian

Posted on

Deploying a Medusa + Minio + MeiliSearch stack with Docker and Traefik

Deploying a production-ready Medusa stack with a proper search engine and a cloud storage can be quite challenging, especially for beginners. However, with a few simple steps, you can deploy your own stack and have it up and running in no time. In this blog post, I will guide you through the process and provide you with some tips for troubleshooting.

Table of contents

Components of the stack

Requirements

  • A VPS with at least 1GB of RAM.
  • Docker and Docker Compose.
  • A custom domain pointing to CloudFlare.
  • A CloudFlare account.

Setup your hosting and (sub)domains

After getting access to your VPS you need to install and configure Docker and Docker compose.

Once you configure your server we are going to setup our domain. We will use CloudFlare to manage our domain's DNS records and handle the validation of a free SSL LetsEncrypt certificate in a easy way.

  1. Follow the instructions to add your site to your CloudFlare's account.
  2. Setup each A record to point your VPS IP address. DNS A Records
  3. Set your SSL/TLS encryption mode to "Full (strict)". SSL/TLS encryption mode
  4. Obtain your CloudFlare's API tokens.

CloudFlare API tokens

Write down those codes, we are going to use them in following steps.

NOTE: Free TLDs like .ga, .ml or .tk won't work with the automatic DNS validation.

Setup Medusa stack

Once you installed Docker and secure your VPS, is time to set up the Medusa stack:

 Step 1: Clone the Github repository.

You can clone the Github repository using the following command:

git clone https://github.com/beakman/medusa-stack-dockerized.git
Enter fullscreen mode Exit fullscreen mode

Step 2: Edit the .env file.

In the root directory of the cloned repository, you will find a file named .env.example. You should copy this file and rename it to .env. Open the .env file and edit the values to suit your environment.

CloudFlare configuration

# LetsEncrypt CloudFlare verification
EMAIL=user@example.com
CERT_RESOLVER=letsencrypt
CLOUDFLARE_EMAIL=
CLOUDFLARE_API_KEY=
CLOUDFLARE_DNS_API_TOKEN=
Enter fullscreen mode Exit fullscreen mode

Here you should provide the previously generated API token and your CloudFlare's email.

Medusa server

MEDUSA_DOMAIN=example.com
MEDUSA_CERT_RESOLVER=letsencrypt
ADMIN_CORS=https://admin.example.com
STORE_CORS=https://store.example.com
JWT_SECRET=
COOKIE_SECRET=
Enter fullscreen mode Exit fullscreen mode

The admin and the store urls are not available yet. We are going to deploy them in another platform as it would be explained in another post.

The MEDUSA_DOMAIN will be the address of our backend. We could use something like api.example.com.

Traefik and dashboard

TRAEFIK_DOMAIN=traefik.example.com
TRAEFIK_CERT_RESOLVER=letsencrypt
TRAEFIK_USER=admin
TRAEFIK_PASSWORD_HASH= # echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g% 
Enter fullscreen mode Exit fullscreen mode

Traefik Dashboard

We will configure the rest of the variables in a second phase, since we will need to generate the api keys of some of the services.

Step 3: Start the containers.

The stack is composed of different docker-compose files to deploy each part of the stack. To start the containers, simply run:

sh start.sh
Enter fullscreen mode Exit fullscreen mode

or more explicitly:

docker compose \
-f docker-compose.medusa.yml \
-f docker-compose.minio.yml \
-f docker-compose.search.yml \
-f docker-compose.traefik.yml \
up -d
Enter fullscreen mode Exit fullscreen mode

Step 4: Access the Medusa stack.

If everything goes well, you could access the different components of your stack:

You can check also the health of the containers by running:

turbo@test-medusa:~$ cd medusa-stack-dockerized/
turbo@test-medusa:~/medusa-stack-dockerized$ docker compose ps
NAME                                    COMMAND                  SERVICE             STATUS              PORTS
medusa-server-default                   "./develop.sh"           backend             running (healthy)   0.0.0.0:9000->9000/tcp, :::9000->9000/tcp
medusa-stack-dockerized-meilisearch-1   "tini -- /bin/sh -c …"   meilisearch         running             0.0.0.0:7700->7700/tcp, :::7700->7700/tcp
medusa-stack-dockerized-postgres-1      "docker-entrypoint.s…"   postgres            running (healthy)   
medusa-stack-dockerized-redis-1         "docker-entrypoint.s…"   redis               running             
service-storage                         "/usr/bin/docker-ent…"   storage             running (healthy)   9000/tcp
traefik                                 "/entrypoint.sh --pr…"   traefik             running             0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, :::80->80/tcp, :::443->443/tcp
Enter fullscreen mode Exit fullscreen mode

If any of the services is unhealthy you can debug it running:

docker-compose logs -f <service-name>
In the above command, replace <service-name> with the name of the service you want to debug.
Enter fullscreen mode Exit fullscreen mode

Example:

turbo@test-medusa:~/medusa-stack-dockerized$ docker compose logs traefik
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Configuration loaded from flags."
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Traefik version 2.9.8 built on 2023-02-15T15:23:25Z"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="\nStats collection is disabled.\nHelp us improve Traefik by turning this feature on :)\nMore details on: https://doc.traefik.io/traefik/contributing/data-collection/\n"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Starting provider aggregator aggregator.ProviderAggregator"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Starting provider *traefik.Provider"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Starting provider *docker.Provider"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Starting provider *acme.ChallengeTLSALPN"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Starting provider *acme.Provider"
traefik  | time="2023-03-02T22:47:26Z" level=info msg="Testing certificate renew..." providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
traefik  | time="2023-03-03T22:47:26Z" level=info msg="Testing certificate renew..." providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
traefik  | time="2023-03-04T12:20:26Z" level=error msg="Error while Peeking first byte: read tcp 172.18.0.4:80->151.235.195.76:33779: read: connection timed out"
traefik  | time="2023-03-04T22:47:26Z" level=info msg="Testing certificate renew..." providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
Enter fullscreen mode Exit fullscreen mode

Configure Minio cloud storage

  1. Access your Minio console and create a new bucket.
  2. Set the policy of the bucket to "Public".
  3. Go to "Access keys" and generate the access key and the secret key.
  4. Set the variables in .env accordingly.
MINIO_ENDPOINT=https://minio.example.com
MINIO_BUCKET=medusa-test
MINIO_ACCESS_KEY=supers3cr3t
MINIO_SECRET_KEY=v3rystr0ngpassw0rd
MINIO_ROOT_USER=admin
MINIO_ROOT_PASS=changeme1234
MINIO_DOMAIN=minio.example.com
MINIO_CONSOLE_DOMAIN=minio-console.example.com
MINIO_CERT_RESOLVER=letsencrypt
Enter fullscreen mode Exit fullscreen mode

Configure MeiliSearch variables

MEILI_DOMAIN=search.example.com
MEILI_CERT_RESOLVER=letsencrypt
MEILISEARCH_HOST=https://search.example.com
MEILISEARCH_API_KEY=
MEILI_MASTER_KEY=
Enter fullscreen mode Exit fullscreen mode

Secure your MeiliSearch instance.

Once you set the master key and restart the container your request will be protected. Check the endpoint https://search.example.com/keys, it should show a message informing you the request is not authorized.

MeiliSearch not authorized request

Troubleshooting

P: Docker containers don't finish getting up
S: Check that your VPS has at least 1GB of RAM available.

P: Errors requesting the SSL LetsEncrypt certificates.
S: Don't use free TLDs like .ga, .ml, .tk, etc. Ensure you wait enough time to propagate the DNS changes.

P: Can't login to Traefik dashboard.
S: Ensure you generate a correct user and hashed password.

I hope you found my post useful! If you did, please consider giving it a star on Github. It will help others find and benefit from the post as well.

Thank you for your support!

https://github.com/beakman/medusa-stack-dockerized.

Top comments (0)