<?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: Fernando Menolli</title>
    <description>The latest articles on DEV Community by Fernando Menolli (@fernandomenolli).</description>
    <link>https://dev.to/fernandomenolli</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%2F1107741%2F14ea4ec3-0473-4a85-b29d-a7e8a7b8dad6.jpeg</url>
      <title>DEV Community: Fernando Menolli</title>
      <link>https://dev.to/fernandomenolli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fernandomenolli"/>
    <language>en</language>
    <item>
      <title>MinIO + Rails Active Storage</title>
      <dc:creator>Fernando Menolli</dc:creator>
      <pubDate>Mon, 31 Jul 2023 23:24:46 +0000</pubDate>
      <link>https://dev.to/fernandomenolli/minio-rails-active-storage-5eph</link>
      <guid>https://dev.to/fernandomenolli/minio-rails-active-storage-5eph</guid>
      <description>&lt;p&gt;Currently, at the company I work for, we are working on rebuilding some modules of older applications. During this process, we decided to replace CarrierWave (a system we used for avatar uploads, for example) with Active Storage, as we believe it better suits our needs.&lt;/p&gt;

&lt;p&gt;To understand the differences between the CarrierWave gem and Active Storage, I recommend reading two excellent articles:&lt;br&gt;
&lt;a href="https://huy-hoang.medium.com/from-carrierwave-to-active-storage-b2fd3e71407f"&gt;From CarrierWave to Active Storage&lt;/a&gt;&lt;br&gt;
and&lt;br&gt;
&lt;a href="https://discuss.rubyonrails.org/t/active-storage-in-production-lessons-learned-and-in-depth-look-at-how-it-works/83289"&gt;Active Storage in production: lessons learned and in-depth look at how it works&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the decision to use Active Storage was made, we needed to consider the method or service for storing these files. This is important because we have other applications that also need to load these files. An important point is that we have powerful local servers available, so if possible, we would prefer to use these servers instead of a service like Amazon S3 or Azure for example. This led us to choose &lt;a href="https://min.io/"&gt;Min.io&lt;/a&gt;, and this is what this article will talk about.&lt;/p&gt;

&lt;p&gt;Min.io is a high-performance, distributed object storage system designed for large-scale private cloud infrastructure. The great advantage is that it is fully compatible with Amazon S3.&lt;/p&gt;

&lt;p&gt;To use Min.io, all we have to do is configure Active Storage through &lt;code&gt;config/storage.yml&lt;/code&gt; as if we were using S3, but point it to a different endpoint, which will be our server running MinIO. In our example, the endpoint will be our own machine, so we will use &lt;code&gt;localhost&lt;/code&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Running MinIO
&lt;/h1&gt;

&lt;p&gt;In our example, we will run MinIO directly on our machine (Linux), but it is also possible to run it using Docker, Kubernetes, or other non-Linux operating systems. For more information, refer to the &lt;a href="https://min.io/docs/minio/kubernetes/upstream/"&gt;Min.io documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After installing MinIO as following the instructions in documentation, we can start the server with the following command: &lt;code&gt;minio server ~/minio&lt;/code&gt;. We will know the server is running when our terminal displays the following information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MinIO Object Storage Server
Copyright: 2015-2023 MinIO, Inc.
License: GNU AGPLv3 &amp;lt;https://www.gnu.org/licenses/agpl-3.0.html&amp;gt;
Version: RELEASE.2023-07-21T21-12-44Z (go1.19.11 linux/amd64)

Status: 1 Online, 0 Offline.
S3-API: http://192.168.1.7:9000  http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin

Console: http://192.168.1.7:36187 http://127.0.0.1:36187
RootUser: minioadmin
RootPass: minioadmin

Command-line: https://min.io/docs/minio/linux/reference/minio-mc.html#quickstart
   $ mc alias set myminio http://192.168.1.7:9000 minioadmin minioadmin

Documentation: https://min.io/docs/minio/linux/index.html
Warning: The standard parity is set to 0. This can lead to data loss.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Accessing MinIO through the browser and creating a bucket
&lt;/h1&gt;

&lt;p&gt;Once our MinIO server is running, we need to create a bucket. To do this, we must access one of the addresses listed in our terminal from the previous step; let's use &lt;code&gt;http://127.0.0.1:9000&lt;/code&gt;. We will log in to the system using the username and password &lt;code&gt;minioadmin&lt;/code&gt;, and in the menu, we will go to the Bucket option and create a new bucket. In our case, we will name it &lt;code&gt;rails-bucket&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuring &lt;code&gt;config/storage.yml&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;With everything set up, we will now configure the 'config/storage.yml' file to make everything work. We will configure it as if we were using S3 as the service but add a different endpoint. Our configuration will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;local&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;S3&lt;/span&gt;
  &lt;span class="na"&gt;endpoint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://127.0.0.1:9000&lt;/span&gt;
  &lt;span class="na"&gt;access_key_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minioadmin&lt;/span&gt;
  &lt;span class="na"&gt;secret_access_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;minioadmin&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;us-east-1&lt;/span&gt;
  &lt;span class="na"&gt;bucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails-bucket&lt;/span&gt;
  &lt;span class="na"&gt;force_path_style&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, I left the &lt;code&gt;access_key_id&lt;/code&gt; and &lt;code&gt;secret_access_key&lt;/code&gt; visible for didactic purposes, but I recommend using Rails Credentials to store these keys securely. Additionally, it is necessary to include &lt;code&gt;force_path_style: true&lt;/code&gt; because otherwise, Active Storage will use a bucket context as a subdomain, and MinIO expects the &lt;code&gt;bucket&lt;/code&gt; to be included after the domain.&lt;/p&gt;

&lt;p&gt;It is also important to note that we used the name &lt;code&gt;local:&lt;/code&gt; for this service in &lt;code&gt;storage.yml&lt;/code&gt;, so in our &lt;code&gt;development.rb&lt;/code&gt; file, we need to have the same service name in the configurations: &lt;code&gt;config.active_storage.service = :local&lt;/code&gt;. If you used a different name in &lt;code&gt;storage.yml&lt;/code&gt;, be sure to change it accordingly in &lt;code&gt;development.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Furthermore, we need to add the gem &lt;code&gt;aws-sdk-s3&lt;/code&gt; to our Gemfile.&lt;/p&gt;

&lt;p&gt;Everything is now ready, and our application is set to use MinIO together with Active Storage. The next time we upload a file, it will go directly to our bucket in MinIO, on our local server.&lt;/p&gt;

&lt;p&gt;I hope this helps! :)&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>minio</category>
    </item>
    <item>
      <title>How I use MRSK and multiple Rails app on the same server</title>
      <dc:creator>Fernando Menolli</dc:creator>
      <pubDate>Sun, 25 Jun 2023 05:28:04 +0000</pubDate>
      <link>https://dev.to/fernandomenolli/how-i-use-mrsk-and-multiple-rails-app-on-the-same-server-5coe</link>
      <guid>https://dev.to/fernandomenolli/how-i-use-mrsk-and-multiple-rails-app-on-the-same-server-5coe</guid>
      <description>&lt;p&gt;Recently, we made the decision to use MRSK to deploy applications at the company I work for. We have a physical server at our disposal, and we found the approach developed by DHH and his team quite interesting.&lt;/p&gt;

&lt;p&gt;One of the requirements for using this tool was the ability to deploy multiple applications on the same server. We have several applications here, and it was important for us to be able to access each of them through a subdomain. That's what I'll be discussing in this post.&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about MRSK in its entirety, from installation to configuration and deployment, I recommend other excellent articles to guide you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://greg.molnar.io/blog/deploying-a-rails-app-with-mrsk/" rel="noopener noreferrer"&gt;https://greg.molnar.io/blog/deploying-a-rails-app-with-mrsk/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.driftingruby.com/episodes/deploying-with-mrsk" rel="noopener noreferrer"&gt;https://www.driftingruby.com/episodes/deploying-with-mrsk&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And others&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Creating two applications
&lt;/h1&gt;

&lt;p&gt;To begin, we will create two applications that will be used in the examples. They will be called &lt;code&gt;app1&lt;/code&gt; and &lt;code&gt;app2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To facilitate the identification of each application, we will create a route and configure it as the root path. In each application, we will have a view that displays "APP1" and "APP2" respectively.&lt;/p&gt;

&lt;p&gt;So far, we have two separate applications. When running each of them on our local machine, we get the following results:&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%2Fokfngvcazixzwmte9ehx.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%2Fokfngvcazixzwmte9ehx.png" alt="Image description"&gt;&lt;/a&gt;&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%2Fhqw8xk7ppxnccz81oyo0.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%2Fhqw8xk7ppxnccz81oyo0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Initializing MRSK
&lt;/h1&gt;

&lt;p&gt;At this point, we will prepare our applications for deployment by initializing MRSK in each of them using the command &lt;code&gt;mrsk init&lt;/code&gt;. This will generate three files: &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;.mrsk/hooks&lt;/code&gt;, and &lt;code&gt;config/deploy.yml&lt;/code&gt;. We will focus on the &lt;code&gt;config/deploy.yml&lt;/code&gt; file, as it allows us to deploy two applications on the same server.&lt;/p&gt;

&lt;p&gt;To perform the deployment, we also need to configure the &lt;code&gt;Dockerfile&lt;/code&gt; so that our image can be built. However, as mentioned at the beginning of the article, the complete step-by-step process for deploying using MRSK is not the focus here. Therefore, we will assume that you already know the necessary steps for configuring the &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Configuring the deploy.yml file
&lt;/h1&gt;

&lt;p&gt;Let's configure the &lt;code&gt;deploy.yml&lt;/code&gt; file for both applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To achieve our goal, it is important to know the exact role of each of our services. In the &lt;code&gt;deploy.yml&lt;/code&gt; file, the role is defined below &lt;code&gt;servers:&lt;/code&gt;. If no role is defined, MRSK will default it to &lt;code&gt;web&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# Deploy to these servers.&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# &amp;lt;- Role&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;10.10.10.10&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the above case, the role of the service will be &lt;code&gt;web&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the case below, since we haven't defined a role, it will default to &lt;code&gt;web&lt;/code&gt; too.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# Deploy to these servers.&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;10.10.10.10&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That is very important because when we define the rules for each application to communicate with &lt;code&gt;Traefik&lt;/code&gt;, we need to specify the role of the service (which will be our container).&lt;/p&gt;

&lt;p&gt;Let's see how the &lt;code&gt;Traefik&lt;/code&gt; rules will be defined in this file.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# APP1&lt;/span&gt;
&lt;span class="c1"&gt;# Name of your application. Used to uniquely configure containers.&lt;/span&gt;
&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app1&lt;/span&gt;

&lt;span class="c1"&gt;# Name of the container image.&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user/app1&lt;/span&gt;

&lt;span class="c1"&gt;# Deploy to these servers.&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;10.10.10.10&lt;/span&gt;

&lt;span class="c1"&gt;# Credentials for your image host.&lt;/span&gt;
&lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MRSK_REGISTRY_USERNAME&lt;/span&gt;

  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MRSK_REGISTRY_PASSWORD&lt;/span&gt;

&lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;traefik.http.routers.app1-web.rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Host(`app1.demo.com`)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What will make the applications accessible in distinct ways is the &lt;code&gt;labels:&lt;/code&gt; tag, which identifies the &lt;code&gt;service:&lt;/code&gt; tags and the previously mentioned Role. Note that in &lt;code&gt;labels:&lt;/code&gt; tag we have defined this rule for the service with a container identified as &lt;code&gt;app1-web&lt;/code&gt; , and in this rule, we specify that we will access this application through the subdomain &lt;code&gt;app1&lt;/code&gt; at the address &lt;code&gt;app1.demo.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's take a look at the &lt;code&gt;deploy.yml&lt;/code&gt; file for our second application:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# APP2&lt;/span&gt;
&lt;span class="c1"&gt;# Name of your application. Used to uniquely configure containers.&lt;/span&gt;
&lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app2&lt;/span&gt;

&lt;span class="c1"&gt;# Name of the container image.&lt;/span&gt;
&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user/app2&lt;/span&gt;

&lt;span class="c1"&gt;# Deploy to these servers.&lt;/span&gt;
&lt;span class="na"&gt;servers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;10.10.10.10&lt;/span&gt;

&lt;span class="c1"&gt;# Credentials for your image host.&lt;/span&gt;
&lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MRSK_REGISTRY_USERNAME&lt;/span&gt;

  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;MRSK_REGISTRY_PASSWORD&lt;/span&gt;

&lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;traefik.http.routers.app2-web.rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Host(`app2.demo.com`)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the second case, we have the &lt;code&gt;Traefik&lt;/code&gt; rule for the &lt;code&gt;app2&lt;/code&gt; service and the &lt;code&gt;web&lt;/code&gt; role.&lt;/p&gt;

&lt;h1&gt;
  
  
  After the deployment
&lt;/h1&gt;

&lt;p&gt;First of all, after we deployed our applications, let's check the status of our Docker containers on the server by running the command &lt;code&gt;docker container ls&lt;/code&gt;. Here is the result:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ubuntu@ip-172-31-14-245:~$ docker container ls
CONTAINER ID   IMAGE                                                     COMMAND                  CREATED              STATUS                        PORTS                                       NAMES
4a919eb90e92   user/app1:dc7bfa712ce9c564230c50ab48c2e61542599a43   "./bin/rails server"     About a minute ago   Up About a minute (healthy)   3000/tcp                                    app1-web-dc7bfa712ce9c564230c50ab48c2e61542599a43
9b17c1cb5db0   user/app2:1a517f061829788aeab563a732978c36d6f233d4   "./bin/rails server"     6 minutes ago        Up 6 minutes (healthy)        3000/tcp                                    app2-web-1a517f061829788aeab563a732978c36d6f233d4
157155628e36   traefik:v2.9                                              "/entrypoint.sh --pr…"   34 minutes ago       Up 34 minutes                 0.0.0.0:80-&amp;gt;80/tcp, :::80-&amp;gt;80/tcp           traefik


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Please note that we have two containers for our applications &lt;code&gt;app1&lt;/code&gt; and &lt;code&gt;app2&lt;/code&gt;. Additionally, we have a container for &lt;code&gt;Traefik&lt;/code&gt;, which is used as a reverse proxy.&lt;/p&gt;

&lt;p&gt;Now let's see if it's possible to access both applications at the same time by simply switching the subdomain for each one. Here is the result:&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%2Fa4iqxhqs4sa6rkx2e7zd.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%2Fa4iqxhqs4sa6rkx2e7zd.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great!&lt;/p&gt;

&lt;p&gt;By following these steps, we have successfully deployed multiple applications using the same target host and separated them effectively.&lt;/p&gt;

&lt;p&gt;In this example, if we access the &lt;code&gt;demo.com&lt;/code&gt; address, none of the applications will be found, ensuring complete separation between them. This is how we use multiple applications with MRSK in the company I work for, where we have several applications, and all of them are segregated in a similar manner.&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%2Faphrl5ghaay5fo995jlk.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%2Faphrl5ghaay5fo995jlk.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This approach allows for better organization, management, and isolation of the applications, ensuring that they can coexist on the same server without conflicts. It also provides a clear and structured way to access each application through distinct subdomains.&lt;/p&gt;

&lt;p&gt;I hope I have contributed in some way :)&lt;/p&gt;

</description>
      <category>kamal</category>
      <category>deploy</category>
      <category>ruby</category>
      <category>rails</category>
    </item>
  </channel>
</rss>
