<?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: ThinEi</title>
    <description>The latest articles on DEV Community by ThinEi (@thineikhaing).</description>
    <link>https://dev.to/thineikhaing</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%2F852006%2F9e760ae2-a524-4f8e-9d1f-caf8544a0b7c.png</url>
      <title>DEV Community: ThinEi</title>
      <link>https://dev.to/thineikhaing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thineikhaing"/>
    <language>en</language>
    <item>
      <title>Create And Dockerize Rails Application With PostgreSQL And Sidekiq (Docker + Docker Compose)</title>
      <dc:creator>ThinEi</dc:creator>
      <pubDate>Mon, 06 Mar 2023 06:38:20 +0000</pubDate>
      <link>https://dev.to/thineikhaing/create-and-dockerize-rails-application-with-postgresql-and-sidekiq-docker-docker-compose-1c23</link>
      <guid>https://dev.to/thineikhaing/create-and-dockerize-rails-application-with-postgresql-and-sidekiq-docker-docker-compose-1c23</guid>
      <description>&lt;p&gt;For this setup, I will use the ruby version 3.1.2 which will generate the rails app of rails version 7.0.4.&lt;/p&gt;

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

rails new ecs_rails_app -d postgresql


&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%2F2ucfos6w7g1c2ah0teyt.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%2F2ucfos6w7g1c2ah0teyt.png" alt="rails new setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our application is created. Let’s create Dockerfile.&lt;/p&gt;

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

cd ecs_rails_app


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

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

# Creating Dockfile
touch Dockerfile


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

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

# Creating development directory and docker-compose file
mkdir development &amp;amp;&amp;amp; touch development/docker-compose.yml


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

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

# Creating entrypoint.sh file
touch entrypoint.sh


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

&lt;/div&gt;
&lt;h1&gt;
  
  
  Dockerfile
&lt;/h1&gt;

&lt;p&gt;Paste the following content into Dockerfile&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

FROM ruby:3.1.3

# install rails dependencies
RUN apt-get clean all &amp;amp;&amp;amp; apt-get update -qq &amp;amp;&amp;amp; apt-get install -y build-essential libpq-dev \
    curl gnupg2 apt-utils  postgresql-client postgresql-server-dev-all git libcurl3-dev cmake \
    libssl-dev pkg-config openssl imagemagick file nodejs npm yarn


RUN mkdir /rails-app
WORKDIR /rails-app

# Adding gems
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install

COPY . /rails-app

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]


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

&lt;/div&gt;

&lt;p&gt;Entrypoint.sh&lt;/p&gt;

&lt;p&gt;paste the following code into entrypoint.sh file&lt;/p&gt;

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

#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /rails-app/tmp/pids/server.pid

exec "$@"


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

&lt;/div&gt;

&lt;p&gt;Now build the docker image.&lt;/p&gt;

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

docker build .


&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%2Fi5oh4skabuz3vaboelhc.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%2Fi5oh4skabuz3vaboelhc.png" alt="Build Docker Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker Compose
&lt;/h1&gt;

&lt;p&gt;I'll add Postgresql, Redis and web (our rails project) services in our docker compose file.&lt;br&gt;
Firstly, we need some adjustment, database.yml file should look like this:&lt;/p&gt;

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

default: &amp;amp;default
  adapter: postgresql
  encoding: unicode
  username: &amp;lt;%= ENV['DB_USERNAME'] %&amp;gt;
  password: &amp;lt;%= ENV['DB_PASSWORD'] %&amp;gt;
  port: &amp;lt;%= ENV['DB_PORT'] %&amp;gt;
  host: &amp;lt;%= ENV['DB_HOST'] %&amp;gt;
  database: &amp;lt;%= ENV['DB_NAME'] %&amp;gt;
  pool: &amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;

development:
  &amp;lt;&amp;lt;: *default

test:
  &amp;lt;&amp;lt;: *default

production:
  &amp;lt;&amp;lt;: *default


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

&lt;/div&gt;

&lt;p&gt;Open the docker-compose.yml file located in development folder and paste the following code:&lt;/p&gt;

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

version: "3.8"
services:
  db:
    image: postgres
    restart: always
    environment:
     - POSTGRES_HOST_AUTH_METHOD=trust
    volumes:
      - db:/var/lib/postgresql/data'
    logging:
            driver: none
    ports:
      - 5432:5432
  redis:
    image: redis:4.0-alpine
    command: redis-server
    volumes:
      - redis:/data
    ports:
      - 6379
    logging:
            driver: none
  web:
    build: ../
    command: bundle exec rails s -p 3000 -e development -b '0.0.0.0'
    environment:
     DB_USERNAME: postgres
     DB_PASSWORD: password
     DB_NAME: ecs_application_db
     DB_PORT: 5432
     DB_HOST: db
     RAILS_ENV: development
     RAILS_MAX_THREADS: 5
     REDIS_HOST: redis
     REDIS_PORT: 6379
     BUNDLE_PATH: /bundle
    volumes:
      - ../:/rails-app
      - bundle:/bundle
    ports:
      - "3000:3000"
    depends_on:
      - "db"
      - "redis"
volumes:
  db:
  bundle:
  redis:


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

&lt;/div&gt;

&lt;p&gt;I have created 3 services (db, redis and web)&lt;/p&gt;

&lt;p&gt;Our rails application requires postgresql database and redis (in the future for sidekiq). Docker compose is creating postgres and redis service for our rails application inside docker-compose.yml file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;db service is using postgres docker image from docker hub&lt;/li&gt;
&lt;li&gt;redis service is using redis docker image from docker hub&lt;/li&gt;
&lt;li&gt;web service is our rails application project containing our own Dockerfile &lt;/li&gt;
&lt;/ul&gt;

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

cd development/
docker-compose run web bundle install
docker-compose run web rails db:migrate
docker-compose run web rails db:setup
docker-compose build


&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%2Fbxc1hsb5j14eb7upj6hm.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%2Fbxc1hsb5j14eb7upj6hm.png" alt="Build Docker Compose"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then run the final command to instantiate rails server&lt;/p&gt;

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

docker-compose up


&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%2F217yku24tfuvngnk3qn5.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%2F217yku24tfuvngnk3qn5.png" alt="Docker Compose Up"&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%2Fakxhoqt8zazzd6xm9nst.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%2Fakxhoqt8zazzd6xm9nst.png" alt="Server started"&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%2Fjaimlt80yg224bf8oe3a.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%2Fjaimlt80yg224bf8oe3a.png" alt="Run Locally"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Configure sidekiq
&lt;/h1&gt;

&lt;p&gt;Add gems into Gemfile:&lt;/p&gt;

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

gem 'sidekiq', '&amp;lt; 7'
gem 'redis-rails'


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

&lt;/div&gt;

&lt;p&gt;Create following files:&lt;/p&gt;

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

touch config/initializers/sidekiq.rb


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

&lt;/div&gt;

&lt;p&gt;Paste following code into sidekiq.rb file&lt;/p&gt;

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

# frozen_string_literal: true
sidekiq_config = { url: "redis://#{ENV['REDIS_HOST']}:#{ENV['REDIS_PORT']}/12" }
Sidekiq.configure_server do |config|
  config.redis = sidekiq_config
end
Sidekiq.configure_client do |config|
  config.redis = sidekiq_config
end


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

&lt;/div&gt;

&lt;p&gt;Go to development folder and install the new gems&lt;/p&gt;

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

docker-compose run web bundle install


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

&lt;/div&gt;

&lt;p&gt;We need to add a new service to the docker-compose.yml file&lt;/p&gt;

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

  sidekiq:
    build: ../
    command: bundle exec sidekiq
    volumes:
      - ../:/rails-app
    environment:
      RAILS_ENV: development
      REDIS_HOST: redis
      REDIS_PORT: 6379
    depends_on:
      - "redis"


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

&lt;/div&gt;

&lt;p&gt;then run&lt;/p&gt;

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

docker-compose up


&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%2Fa1k02xyfov8s0227rpf3.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%2Fa1k02xyfov8s0227rpf3.png" alt="Docker compose up"&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%2Frd5vr3ac6dkm5xmcrk7e.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%2Frd5vr3ac6dkm5xmcrk7e.png" alt="Docker container"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we will create a Controller, ActiveJob and some changes to the routes.&lt;/p&gt;

&lt;p&gt;Create a controller and Active Job&lt;/p&gt;

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

docker-compose run web rails g controller home
docker-compose run web rails g job home


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

&lt;/div&gt;

&lt;p&gt;home_controller.rb&lt;/p&gt;

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

class HomeController &amp;lt; ApplicationController
    def index
        render json: {"message": "Welcome"}
        HomeJob.perform_later
      end
end


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

&lt;/div&gt;

&lt;p&gt;home_job.rb&lt;/p&gt;

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

class HomeJob &amp;lt; ApplicationJob
  queue_as :default
  def perform(*args)
    puts 'Job Executed'
  end
end


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

&lt;/div&gt;

&lt;p&gt;routes.rb&lt;/p&gt;

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

Rails.application.routes.draw do
  get '/home', to: 'home#index'  
end


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

&lt;/div&gt;

&lt;p&gt;then run&lt;/p&gt;

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

docker-compose build
docker-compose up


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

&lt;/div&gt;

&lt;p&gt;Open &lt;a href="http://localhost:3000/home" rel="noopener noreferrer"&gt;http://localhost:3000/home&lt;/a&gt; in your web browser,&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%2Fxj7fr52w4plch4nriogd.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%2Fxj7fr52w4plch4nriogd.png" alt="Localhost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;in the console you should be able to see that the HomeJob has been performed.&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%2F3t0pytryxs2s73sqjh1z.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%2F3t0pytryxs2s73sqjh1z.png" alt="Job Executed"&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%2Fblogger.googleusercontent.com%2Fimg%2Fa%2FAVvXsEhvLybsL98FhjH9HbOLBKdJa68m4IduB4UOSKBG5PzK-yasJyZ4Z5pcuokCJg01EWrfoQbm2LNwQrI3CaI9wXPIQdRzkC3I4IaoKc3EEbt57WX_mUjedzyyc7K-XaCScAeZ-eVQRQ29CTvb7LMwRqHMrMr_NyHS5tQYk-b4tHXOV2GhTDa_oG4FJvyA%3Ds320" 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%2Fblogger.googleusercontent.com%2Fimg%2Fa%2FAVvXsEhvLybsL98FhjH9HbOLBKdJa68m4IduB4UOSKBG5PzK-yasJyZ4Z5pcuokCJg01EWrfoQbm2LNwQrI3CaI9wXPIQdRzkC3I4IaoKc3EEbt57WX_mUjedzyyc7K-XaCScAeZ-eVQRQ29CTvb7LMwRqHMrMr_NyHS5tQYk-b4tHXOV2GhTDa_oG4FJvyA%3Ds320" alt="Yes."&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ruby</category>
      <category>docker</category>
      <category>sidekiq</category>
    </item>
  </channel>
</rss>
