<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Turbo Plebeian</title>
    <description>The latest articles on DEV Community by Turbo Plebeian (@turboplebeian).</description>
    <link>https://dev.to/turboplebeian</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F949637%2Ff71c25ae-90de-449e-90b7-a0cdbcfc8722.jpg</url>
      <title>DEV Community: Turbo Plebeian</title>
      <link>https://dev.to/turboplebeian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/turboplebeian"/>
    <language>en</language>
    <item>
      <title>Deploying a Medusa + Minio + MeiliSearch stack with Docker and Traefik</title>
      <dc:creator>Turbo Plebeian</dc:creator>
      <pubDate>Sun, 05 Mar 2023 19:26:02 +0000</pubDate>
      <link>https://dev.to/turboplebeian/deploying-a-medusa-minio-meilisearch-stack-with-docker-and-traefik-2mgj</link>
      <guid>https://dev.to/turboplebeian/deploying-a-medusa-minio-meilisearch-stack-with-docker-and-traefik-2mgj</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Components of the stack&lt;/li&gt;
&lt;li&gt;Requirements&lt;/li&gt;
&lt;li&gt;Setup your hosting and (sub)domains&lt;/li&gt;
&lt;li&gt;Setup Medusa stack&lt;/li&gt;
&lt;li&gt;Troubleshooting&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Components of the stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/medusajs/medusa-starter-default" rel="noopener noreferrer"&gt;Medusa Starter Default&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.medusajs.com/add-plugins/minio" rel="noopener noreferrer"&gt;Minio Cloud Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.medusajs.com/add-plugins/meilisearch/" rel="noopener noreferrer"&gt;MeiliSearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.medusajs.com/add-plugins/stripe" rel="noopener noreferrer"&gt;Stripe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;✨ SSL certificate via CloudFlare + LetsEncrypt&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A VPS with at least 1GB of RAM. &lt;/li&gt;
&lt;li&gt;Docker and Docker Compose.&lt;/li&gt;
&lt;li&gt;A custom domain pointing to CloudFlare.&lt;/li&gt;
&lt;li&gt;A CloudFlare account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setup your hosting and (sub)domains
&lt;/h2&gt;

&lt;p&gt;After getting access to your VPS you need to install and configure Docker and Docker compose. &lt;/p&gt;

&lt;p&gt;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 &lt;a href="https://doc.traefik.io/traefik/v1.6/configuration/acme/" rel="noopener noreferrer"&gt;in a easy way&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Follow the instructions to &lt;a href="https://developers.cloudflare.com/fundamentals/get-started/setup/add-site/" rel="noopener noreferrer"&gt;add your site&lt;/a&gt; to your CloudFlare's account.&lt;/li&gt;
&lt;li&gt;Setup each A record to point your VPS IP address.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsy18ywuqh3wy59ven8x1.png" alt="DNS A Records"&gt;
&lt;/li&gt;
&lt;li&gt;Set your SSL/TLS encryption mode to "Full (strict)".
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xp16xicsd22w2200vwd.png" alt="SSL/TLS encryption mode"&gt;
&lt;/li&gt;
&lt;li&gt;Obtain your &lt;a href="https://dash.cloudflare.com/profile/api-tokens" rel="noopener noreferrer"&gt;CloudFlare's API tokens&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7ksk8uxorh2xghh56kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7ksk8uxorh2xghh56kr.png" alt="CloudFlare API tokens"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Write down those codes, we are going to use them in following steps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: Free TLDs like &lt;strong&gt;.ga&lt;/strong&gt;, &lt;strong&gt;.ml&lt;/strong&gt; or &lt;strong&gt;.tk&lt;/strong&gt; &lt;a href="https://community.cloudflare.com/t/unable-to-add-free-domains-to-cloudflare-tk-ml-ga-cf-gq/303502/2" rel="noopener noreferrer"&gt;won't work with the automatic DNS validation&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setup Medusa stack
&lt;/h2&gt;

&lt;p&gt;Once you installed Docker and secure your VPS, is time to set up the Medusa stack:&lt;/p&gt;

&lt;h3&gt;
  
  
   Step 1: Clone the Github repository.
&lt;/h3&gt;

&lt;p&gt;You can clone the Github repository using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/beakman/medusa-stack-dockerized.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Edit the &lt;code&gt;.env&lt;/code&gt; file.
&lt;/h3&gt;

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

&lt;h4&gt;
  
  
  CloudFlare configuration
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# LetsEncrypt CloudFlare verification&lt;/span&gt;
&lt;span class="nv"&gt;EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;user@example.com
&lt;span class="nv"&gt;CERT_RESOLVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt
&lt;span class="nv"&gt;CLOUDFLARE_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;CLOUDFLARE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;CLOUDFLARE_DNS_API_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you should provide the previously generated API token and your CloudFlare's email.&lt;/p&gt;

&lt;h4&gt;
  
  
  Medusa server
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MEDUSA_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;example.com
&lt;span class="nv"&gt;MEDUSA_CERT_RESOLVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt
&lt;span class="nv"&gt;ADMIN_CORS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://admin.example.com
&lt;span class="nv"&gt;STORE_CORS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://store.example.com
&lt;span class="nv"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;COOKIE_SECRET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;MEDUSA_DOMAIN&lt;/code&gt; will be the address of our backend. We could use something like &lt;code&gt;api.example.com&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Traefik and dashboard
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;TRAEFIK_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;traefik.example.com
&lt;span class="nv"&gt;TRAEFIK_CERT_RESOLVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt
&lt;span class="nv"&gt;TRAEFIK_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin
&lt;span class="nv"&gt;TRAEFIK_PASSWORD_HASH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c"&gt;# echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g% &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjdzppcwwrohkqqunhta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjdzppcwwrohkqqunhta.png" alt="Traefik Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Start the containers.
&lt;/h3&gt;

&lt;p&gt;The stack is composed of different docker-compose files to deploy each part of the stack. To start the containers, simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh start.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or more explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.medusa.yml &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.minio.yml &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.search.yml &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.traefik.yml &lt;span class="se"&gt;\&lt;/span&gt;
up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Access the Medusa stack.
&lt;/h3&gt;

&lt;p&gt;If everything goes well, you could access the different components of your stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traefik dashboard: &lt;a href="https://traefik.example.com" rel="noopener noreferrer"&gt;https://traefik.example.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Medusa server: &lt;a href="https://api.example.com" rel="noopener noreferrer"&gt;https://api.example.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MeiliSearch: &lt;a href="https://search.example.com" rel="noopener noreferrer"&gt;https://search.example.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Minio cloud storage: &lt;a href="https://minio-console.example.com" rel="noopener noreferrer"&gt;https://minio-console.example.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check also the health of the containers by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turbo@test-medusa:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;medusa-stack-dockerized/
turbo@test-medusa:~/medusa-stack-dockerized&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose ps
NAME                                    COMMAND                  SERVICE             STATUS              PORTS
medusa-server-default                   &lt;span class="s2"&gt;"./develop.sh"&lt;/span&gt;           backend             running &lt;span class="o"&gt;(&lt;/span&gt;healthy&lt;span class="o"&gt;)&lt;/span&gt;   0.0.0.0:9000-&amp;gt;9000/tcp, :::9000-&amp;gt;9000/tcp
medusa-stack-dockerized-meilisearch-1   &lt;span class="s2"&gt;"tini -- /bin/sh -c …"&lt;/span&gt;   meilisearch         running             0.0.0.0:7700-&amp;gt;7700/tcp, :::7700-&amp;gt;7700/tcp
medusa-stack-dockerized-postgres-1      &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   postgres            running &lt;span class="o"&gt;(&lt;/span&gt;healthy&lt;span class="o"&gt;)&lt;/span&gt;   
medusa-stack-dockerized-redis-1         &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   redis               running             
service-storage                         &lt;span class="s2"&gt;"/usr/bin/docker-ent…"&lt;/span&gt;   storage             running &lt;span class="o"&gt;(&lt;/span&gt;healthy&lt;span class="o"&gt;)&lt;/span&gt;   9000/tcp
traefik                                 &lt;span class="s2"&gt;"/entrypoint.sh --pr…"&lt;/span&gt;   traefik             running             0.0.0.0:80-&amp;gt;80/tcp, 0.0.0.0:443-&amp;gt;443/tcp, :::80-&amp;gt;80/tcp, :::443-&amp;gt;443/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any of the services is unhealthy you can debug it running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose logs &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;service-name&amp;gt;
In the above &lt;span class="nb"&gt;command&lt;/span&gt;, replace &amp;lt;service-name&amp;gt; with the name of the service you want to debug.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;turbo@test-medusa:~/medusa-stack-dockerized&lt;span class="nv"&gt;$ &lt;/span&gt;docker compose logs traefik
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Configuration loaded from flags."&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Traefik version 2.9.8 built on 2023-02-15T15:23:25Z"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Stats collection is disabled.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Help us improve Traefik by turning this feature on :)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;More details on: https://doc.traefik.io/traefik/contributing/data-collection/&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Starting provider aggregator aggregator.ProviderAggregator"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Starting provider *traefik.Provider"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Starting provider *docker.Provider"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Starting provider *acme.ChallengeTLSALPN"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Starting provider *acme.Provider"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-02T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Testing certificate renew..."&lt;/span&gt; &lt;span class="nv"&gt;providerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt.acme ACME &lt;span class="nv"&gt;CA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://acme-v02.api.letsencrypt.org/directory"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-03T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Testing certificate renew..."&lt;/span&gt; &lt;span class="nv"&gt;providerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt.acme ACME &lt;span class="nv"&gt;CA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://acme-v02.api.letsencrypt.org/directory"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-04T12:20:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Error while Peeking first byte: read tcp 172.18.0.4:80-&amp;gt;151.235.195.76:33779: read: connection timed out"&lt;/span&gt;
traefik  | &lt;span class="nb"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2023-03-04T22:47:26Z"&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Testing certificate renew..."&lt;/span&gt; &lt;span class="nv"&gt;providerName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt.acme ACME &lt;span class="nv"&gt;CA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"https://acme-v02.api.letsencrypt.org/directory"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Minio cloud storage
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Access your Minio console and create a new bucket.&lt;/li&gt;
&lt;li&gt;Set the policy of the bucket to "Public".&lt;/li&gt;
&lt;li&gt;Go to "Access keys" and generate the access key and the secret key.&lt;/li&gt;
&lt;li&gt;Set the variables in &lt;code&gt;.env&lt;/code&gt; accordingly.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MINIO_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://minio.example.com
&lt;span class="nv"&gt;MINIO_BUCKET&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;medusa-test
&lt;span class="nv"&gt;MINIO_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;supers3cr3t
&lt;span class="nv"&gt;MINIO_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3rystr0ngpassw0rd
&lt;span class="nv"&gt;MINIO_ROOT_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin
&lt;span class="nv"&gt;MINIO_ROOT_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;changeme1234
&lt;span class="nv"&gt;MINIO_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;minio.example.com
&lt;span class="nv"&gt;MINIO_CONSOLE_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;minio-console.example.com
&lt;span class="nv"&gt;MINIO_CERT_RESOLVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure MeiliSearch variables
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MEILI_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;search.example.com
&lt;span class="nv"&gt;MEILI_CERT_RESOLVER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letsencrypt
&lt;span class="nv"&gt;MEILISEARCH_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://search.example.com
&lt;span class="nv"&gt;MEILISEARCH_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nv"&gt;MEILI_MASTER_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.meilisearch.com/learn/security/master_api_keys.html#protecting-a-meilisearch-instance" rel="noopener noreferrer"&gt;Secure your MeiliSearch instance.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you set the master key and restart the container your request will be protected. Check the endpoint &lt;a href="https://search.example.com/keys" rel="noopener noreferrer"&gt;https://search.example.com/keys&lt;/a&gt;, it should show a message informing you the request is not authorized.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ievu9puznhjwfji10j2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ievu9puznhjwfji10j2.png" alt="MeiliSearch not authorized request"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;P: Docker containers don't finish getting up&lt;br&gt;
S: Check that your VPS has at least 1GB of RAM available.&lt;/p&gt;

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

&lt;p&gt;P: Can't login to Traefik dashboard.&lt;br&gt;
S: Ensure you generate a correct&lt;a href="https://doc.traefik.io/traefik/middlewares/http/basicauth/" rel="noopener noreferrer"&gt; user and hashed password&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope you found my post useful! If you did, please consider giving it &lt;a href="https://github.com/beakman/medusa-stack-dockerized" rel="noopener noreferrer"&gt;a star on Github&lt;/a&gt;. It will help others find and benefit from the post as well.&lt;/p&gt;

&lt;p&gt;Thank you for your support!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/beakman/medusa-stack-dockerized" rel="noopener noreferrer"&gt;https://github.com/beakman/medusa-stack-dockerized&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>medusa</category>
      <category>traefik</category>
      <category>meilisearch</category>
      <category>minio</category>
    </item>
  </channel>
</rss>
