<?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>Forem: Matvei Tratseuski</title>
    <description>The latest articles on Forem by Matvei Tratseuski (@set27).</description>
    <link>https://forem.com/set27</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%2F1137778%2F36ecc539-ee3d-48b5-8f14-a789fd6d03b1.jpeg</url>
      <title>Forem: Matvei Tratseuski</title>
      <link>https://forem.com/set27</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/set27"/>
    <language>en</language>
    <item>
      <title>How to Dockerize a Ruby on Rails application</title>
      <dc:creator>Matvei Tratseuski</dc:creator>
      <pubDate>Tue, 21 May 2024 14:59:36 +0000</pubDate>
      <link>https://forem.com/datarockets/how-to-dockerize-a-ruby-on-rails-application-4h81</link>
      <guid>https://forem.com/datarockets/how-to-dockerize-a-ruby-on-rails-application-4h81</guid>
      <description>&lt;p&gt;Containerization is a game-changer in software development, delivering key advantages like streamlined deployment, scalability, and consistency across development, testing, and production environments.&lt;/p&gt;

&lt;p&gt;In this post, I’m going to walk you through a configuration for dockerizing your Ruby on Rails app and dive into each detail so you know exactly how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Docker
&lt;/h2&gt;

&lt;p&gt;Install &lt;a href="https://www.docker.com/products/docker-desktop/"&gt;Docker Desktop&lt;/a&gt; if you’re on Mac or Windows, or a &lt;a href="https://docs.docker.com/engine/install/"&gt;Docker Engine&lt;/a&gt; if you’re using Linux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Here’s the structure of the project that will be dockerized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;your-project-name/
│
├── backend (rails backend)
│   ├── Gemfile
│   ├── Gemfile.lock
│   └── ... (other rails files)

├── frontend (frontend folder)
│   ├── package.json
│   └── ... (other frontend files)
│
├── bin (place for script)
│   ├── run (script that run docker)
│   └── ... (other scripts)
│
├── docker
│   ├── development
│   ├──├── frontend.Dockerfile
│   └──└── backend.Dockerfile
│
└── docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Proposed Configuration
&lt;/h2&gt;

&lt;p&gt;Most folks just want to copy the config and hit the ground running. Below, I’ve shared my configuration and broken it down for you.&lt;/p&gt;

&lt;p&gt;Tech stack for this sample project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 3.3.0&lt;/li&gt;
&lt;li&gt;Svelte 4 (you can use any other)&lt;/li&gt;
&lt;li&gt;Postgres 14&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  backend.Dockerfile
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ruby:3.3.0-bookworm&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-eux&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get update&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; upgrade

&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; UID=1000&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-eux&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    useradd &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;UID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; backend&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /backend/vendor/bundle&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; backend:backend /backend

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; backend&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /backend&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_PATH=vendor/bundle&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_APP_CONFIG=$BUNDLE_PATH&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; BUNDLE_USER_CACHE=vendor/bundle/cache&lt;/span&gt;

&lt;span class="c"&gt;# This will force using gems with native extensions instead&lt;/span&gt;
&lt;span class="c"&gt;# of pre-compiled versions.&lt;/span&gt;
&lt;span class="c"&gt;# Using precompiled versions leads to compatibility issues&lt;/span&gt;
&lt;span class="c"&gt;# in the case of ARM platform.&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;bundle config &lt;span class="nb"&gt;set &lt;/span&gt;force_ruby_platform &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  docker-compose.yml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;backend&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/development/backend.Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./backend:/backend:cached&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend_tmp:/backend/tmp&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bundle:/backend/vendor&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bin/rails s -b 0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;stdin_open&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;

  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&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;postgres:14&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db_data:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;

  &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/development/frontend.Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./frontend:/frontend:cached&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node_modules:/frontend/node_modules&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn dev --port 3001 --host 0.0.0.0&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3001:3001"&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bundle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node_modules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;backend_tmp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver_opts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
      &lt;span class="na"&gt;device&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
      &lt;span class="na"&gt;o&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;uid=1000,gid=1000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change default in &lt;code&gt;backend/config/database.yml&lt;/code&gt; to:&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;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("DB_HOST", "db") %&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("DB_PASSWORD", "password") %&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get everything up and running, you need to build images (or pull), install gem, prepare db, and install packages for the frontend. You can find all of these scripts in this repository. &lt;/p&gt;

&lt;p&gt;For simplicity, I combined all scripts into one &lt;code&gt;bin/setup&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  bin/setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="c"&gt;#exit immediately if any command within the script or session &lt;/span&gt;
&lt;span class="c"&gt;#exits with a non-zero status&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; 

docker compose build

docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; backend /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'bundle install'&lt;/span&gt;
docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; backend /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'bundle exec rails db:prepare'&lt;/span&gt;
docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; backend /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'bundle exec rails db:seed'&lt;/span&gt;
&lt;span class="c"&gt;#change yarn to your package manager&lt;/span&gt;
docker compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; frontend /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'yarn install'&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Give permission to run scripts from the bin folder using &lt;code&gt;chmod +x -R ./bin/&lt;/code&gt; from the project root folder. Then run this script &lt;code&gt;bin/setup&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Congratulations! Now you can run docker using &lt;code&gt;docker compose up&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration Explained
&lt;/h2&gt;

&lt;p&gt;Now let’s talk more about the specific configuration of the &lt;strong&gt;backend.Dockerfile&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bookworm
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;FROM ruby:3.3.0-bookworm&lt;/code&gt;, why bookworm, and what is it? &lt;/p&gt;

&lt;p&gt;Bookworm is the name of the &lt;a href="https://www.debian.org/releases/"&gt;Debian version&lt;/a&gt;. Most of the time, we don’t care about the size of the docker image, so I recommend picking the latest Debian version. &lt;/p&gt;

&lt;p&gt;Also, I recommend always explicitly specifying the version of an image - never pick the &lt;em&gt;latest&lt;/em&gt; as it can upgrade and break the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update and upgrade software packages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-eux&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get update&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nt"&gt;-y&lt;/span&gt; upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands update and upgrade the software packages within a Docker container, ensuring they are up-to-date and secure. The script exits on errors and automatically confirms all prompts for a smooth, non-interactive process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up Application User and Directory Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; UID=1000&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-eux&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    useradd &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;UID&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; backend&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /backend/vendor/bundle&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; backend:backend /backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It creates a new user named backend with a specified user ID, sets up a directory for the application, and assigns ownership of this directory to the new user. Then it creates a directory for Ruby dependencies and sets the application user as its owner for secure and organized access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;frontend.Dockerfile&lt;/strong&gt; has almost the same configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Volumes for the backend service
&lt;/h3&gt;

&lt;p&gt;The main thing to understand in &lt;strong&gt;docker-compose.yml&lt;/strong&gt; is how volumes are mounted.&lt;br&gt;
Volumes for the backend service:&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;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./backend:/backend:cached&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend_tmp:/backend/tmp&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bundle:/backend/vendor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Bind Mount from Local Directory
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;./backend:/backend:cached&lt;/code&gt;&lt;br&gt;
This volume mounts the backend directory on the host machine to &lt;em&gt;/backend&lt;/em&gt; inside the container. With &lt;em&gt;:cached&lt;/em&gt;  for optimized I/O performance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Named Volumes
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;backend_tmp:/backend/tmp&lt;/code&gt;&lt;br&gt;
A named volume &lt;em&gt;backend_tmp&lt;/em&gt; is mounted to &lt;em&gt;/backend/tmp&lt;/em&gt; inside the container, managed by Docker for data persistence.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bundle:/backend/vendor&lt;/code&gt;&lt;br&gt;
This bundle is another named volume mounted to &lt;em&gt;/backend/vendor&lt;/em&gt;, ensuring the persistence of Ruby dependencies (gems) across container restarts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Volumes for the db service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db_data:/var/lib/postgresql/data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;db_data:/var/lib/postgresql/data&lt;/code&gt;&lt;br&gt;
This volume is used to store the Postgres database within &lt;em&gt;db_data&lt;/em&gt;, ensuring that data remains persistent across container restarts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Volumes for the frontend service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./frontend:/frontend:cached&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node_modules:/frontend/node_modules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;./frontend:/frontend:cached&lt;/code&gt;&lt;br&gt;
The local frontend directory is mounted to &lt;em&gt;/frontend&lt;/em&gt; inside the container, with &lt;em&gt;:cached&lt;/em&gt; for optimized I/O performance.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;node_modules:/frontend/node_modules&lt;/code&gt;&lt;br&gt;
Ensures persistent storage of Node.js dependencies in &lt;em&gt;node_modules&lt;/em&gt;, avoiding loss on container rebuild.&lt;/p&gt;

&lt;h3&gt;
  
  
  Volume Definitions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;bundle&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node_modules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;backend_tmp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver_opts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
      &lt;span class="na"&gt;device&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tmpfs&lt;/span&gt;
      &lt;span class="na"&gt;o&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;uid=1000,gid=1000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;bundle, db_data, node_modules&lt;/code&gt;&lt;br&gt;
These are simply declared, allowing Docker to manage them for persistence.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;backend_tmp&lt;/code&gt;&lt;br&gt;
Specified with &lt;em&gt;driver_opts&lt;/em&gt; to configure as &lt;em&gt;tmpfs&lt;/em&gt;, meaning it's stored in memory, not persisted on the host disk, with &lt;em&gt;uid=1000, gid=1000&lt;/em&gt; for file ownership. Ideal for temporary data not requiring persistence across restarts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Debugging
&lt;/h2&gt;

&lt;p&gt;If you take scripts from &lt;a href="https://github.com/Set27/dockerize_rails_example"&gt;this repository&lt;/a&gt;, you can smoothly debug a rails application by running this script &lt;code&gt;bin/run_and_attach&lt;/code&gt;. This allows you to debug inside the same terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By dockerizing your Rails app, you're setting yourself up for success with an application that's portable and easy to deploy.&lt;/p&gt;

&lt;p&gt;Whether you are hosting it on a server, using a PaaS like Heroku, or orchestrating it with Kubernetes, Docker lays a solid foundation.&lt;br&gt;
Well done on dockerizing your Rails app! Here's to smooth sailing in your app development and deployment!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Originally published on the &lt;a href="https://datarockets.com/blog/code/dockerize-ruby-on-rails-application/"&gt;datarockets' blog&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>docker</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
