<?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: Kaushik Hande</title>
    <description>The latest articles on Forem by Kaushik Hande (@kaushikhande).</description>
    <link>https://forem.com/kaushikhande</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%2F224535%2F23eb829f-357d-49cc-bd9d-f8506eab1123.png</url>
      <title>Forem: Kaushik Hande</title>
      <link>https://forem.com/kaushikhande</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kaushikhande"/>
    <language>en</language>
    <item>
      <title>Dockerise existing rails application</title>
      <dc:creator>Kaushik Hande</dc:creator>
      <pubDate>Fri, 28 Jan 2022 14:55:56 +0000</pubDate>
      <link>https://forem.com/kaushikhande/dockerise-exising-rails-application-3aol</link>
      <guid>https://forem.com/kaushikhande/dockerise-exising-rails-application-3aol</guid>
      <description>&lt;p&gt;In this blog we will see how to dockerise the existing rails application.&lt;/p&gt;

&lt;p&gt;For demo purpose, I have created a basic rails application&lt;br&gt;
App configuration are as follows,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby: Ruby 3.1.0&lt;/li&gt;
&lt;li&gt;Rails version: Rails 7.0.1&lt;/li&gt;
&lt;li&gt;Database: Postgres&lt;/li&gt;
&lt;li&gt;Model: Article(title: string, content: text)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1: Create a Dockerfile
&lt;/h2&gt;

&lt;p&gt;A docker file contains the information to create the container image. We need a basic docker container image. These basic images are already created on docker hub. Docker Hub contains predefined ruby images. Our application ruby version is 3.1.0.&lt;/p&gt;

&lt;p&gt;We will use &lt;a href="https://hub.docker.com/layers/ruby/library/ruby/3.1.0/images/sha256-6155f0235e95166b49508ff0acbea7958bec53017bd307938e4dceb2cbd99c63?context=explore" rel="noopener noreferrer"&gt;https://hub.docker.com/layers/ruby/library/ruby/3.1.0/images/sha256-6155f0235e95166b49508ff0acbea7958bec53017bd307938e4dceb2cbd99c63?context=explore&lt;/a&gt; from docker hub.&lt;br&gt;
ruby:3.1.0, here 3.1.0 is the tag of the image.&lt;/p&gt;

&lt;p&gt;Create a file with name Dockerfile without extension inside rails root folder.&lt;/p&gt;

&lt;p&gt;Here is the docker file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# syntax=docker/dockerfile:1
FROM ruby:3.1.0
RUN apt-get update -qq &amp;amp;&amp;amp; apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

# 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"]
EXPOSE 3000

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Line 1: fetches the ruby:3.1.0 image from docker hub if not present already.&lt;br&gt;
Line 2: Adds nodejs and postgresql-client to container environment.&lt;br&gt;
Line 3: It creates a working directory. Any command after this will be run inside this folder.&lt;br&gt;
Line 4 &amp;amp; Line 5: copies Gemfile and Gemfile.lock from host inside working directory. It will copy these files from current folder to container myapp folder.&lt;br&gt;
Line 6: runs the bundle install inside our container in working directory. This will install all the gems we need to run the application in our container.&lt;/p&gt;

&lt;p&gt;Next, provide an entrypoint script to fix a Rails-specific issue that prevents the server from restarting when a certain server.pid file pre-exists. This script will be executed every time the container gets started.&lt;br&gt;
entrypoint.sh consists of:&lt;br&gt;
&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 /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this script to rails root folder as entrypoint.sh&lt;br&gt;
Next it will copy it in /usr/bin/ inside container&lt;br&gt;
Run chmod on it.&lt;br&gt;
Next command exposes port 3000 of container to host. Last line starts the rails server.&lt;/p&gt;

&lt;p&gt;RUN sudo docker build .&lt;/p&gt;

&lt;p&gt;This will build the docker image &lt;br&gt;
i.e pull the ruby image and run the commands the dockerfile.&lt;/p&gt;

&lt;p&gt;Our app will also need postgres database.&lt;br&gt;
For this we will use postgres image from DockerHub.&lt;br&gt;
We will directly specify this in our docker compose file.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Docker Compose
&lt;/h2&gt;

&lt;p&gt;Create a docker-compose.yml file inside the rails app root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: "3.3"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid &amp;amp;&amp;amp; bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db

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

&lt;/div&gt;



&lt;p&gt;It consists of 2 services.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;db

&lt;ol&gt;
&lt;li&gt;image: postgres will fetch postgres image from docker hub to our local&lt;/li&gt;
&lt;li&gt;To persist our database through multiple container reruns we use volumes, where we specify local host location and map it to postgres container data location. Docker postgres image volume location is /var/lib/postgresql/data. You will find this in docker hub otherwise after image pull run &lt;code&gt;docker inspect postgres&lt;/code&gt;
and see the path in Volumes key.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;web

&lt;ol&gt;
&lt;li&gt;For postgres we use default image from docker hub. However, for rails we will use the dockerfile.&lt;/li&gt;
&lt;li&gt;build . will build the dockerfile.&lt;/li&gt;
&lt;li&gt;next we removed the server pid and started the server.&lt;/li&gt;
&lt;li&gt;next we are binding the current folder to myapp folder in container.Any changes made inside our current directly will be visible in /myapp and eventually it will show us the latest content as we edit the file.&lt;/li&gt;
&lt;li&gt;Map post 3000 of host to post 3000 of container.&lt;/li&gt;
&lt;li&gt;It depends on db service.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Run Docker Compose
&lt;/h2&gt;

&lt;p&gt;Start container using docker-compose file&lt;/p&gt;

&lt;p&gt;Command to start:&lt;br&gt;
&lt;code&gt;docker-compose up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Running this will give us errors as we have not configured our database and not connected the rails app with postgres.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We need to create database in our postgres container. We will create it using our rails commands&lt;/li&gt;
&lt;li&gt;For that we need to configure database.yml right.
use same username and password which you passed to postgres
as environment variables. In order to connect our rails app with database we have to provide correct host in database.yml&lt;/li&gt;
&lt;li&gt;In this case host is db i.e. our service name.&lt;/li&gt;
&lt;li&gt;Docker compose file creates a network of different services for us. In order to communicate with different services in this network we specify the service names.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sample database.yml contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;database: dockerise_rails_test
username: postgres
password: password
host: db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;After configuring the database.yml, create database using
&lt;code&gt;docker-compose run web rails db:create&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run database migrations:
&lt;code&gt;docker-compose run web rails db:migrate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open Rails console:
&lt;code&gt;docker-compose run web rails console&lt;/code&gt;
Or
&lt;code&gt;docker ps&lt;/code&gt;
get the name or container id and run
&lt;code&gt;docker exec -it dockerise_rails_web_1 rails c&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now run docker-compose file
&lt;code&gt;docker-compose up&lt;/code&gt;
Both db and web services starts
Docker compose logs shows us that both db_1 and web_1 have started.
&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%2Fac7mvw3gpw8gwjzs0feu.png" alt="docker-compose up console output"&gt;
Our web application:
&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%2Fu6pg6eyifk61qzv69iha.png" alt="Rails application running on port 3000"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://github.com/kaushikhande/dockerise_rails" rel="noopener noreferrer"&gt;Github repository with dockerfile and docker-compose&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Command to stop both rails and database container:&lt;br&gt;
&lt;code&gt;docker-compose down&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/samples/rails/" rel="noopener noreferrer"&gt;https://docs.docker.com/samples/rails/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Development workflows using tmux and tmuxinator</title>
      <dc:creator>Kaushik Hande</dc:creator>
      <pubDate>Sun, 07 Nov 2021 18:10:29 +0000</pubDate>
      <link>https://forem.com/kaushikhande/development-workflows-using-tmux-and-tmuxinator-599j</link>
      <guid>https://forem.com/kaushikhande/development-workflows-using-tmux-and-tmuxinator-599j</guid>
      <description>&lt;p&gt;In this blog, we will setup and startup development environment using tmux and tmuxinator.&lt;/p&gt;

&lt;p&gt;As tmuxinator is based on tmux, first we will take a look into tmux and its basic commands, then we will create yml templates for project setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tmux introduction
&lt;/h2&gt;

&lt;p&gt;Tmux stands for Terminal Multiplexer.&lt;br&gt;
Using tmux you can create different windows and panes within one window of one terminal and move around these windows and panes.&lt;br&gt;
It lets you switch between several programs inside one terminal, detach and reattach them to a different terminal at will.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tmux installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Ubuntu: &lt;code&gt;sudo apt install tmux&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Windows: Using wsl for ubuntu`&lt;/li&gt;
&lt;li&gt;OSX: &lt;code&gt;brew install tmux&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Open your terminal and start a tmux session by typing&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;tmux&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
This will open a tmux window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tmux Basic commands
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create vertical pane: Ctrl + a + %
&lt;/li&gt;
&lt;li&gt;Create horizontal pane: Ctrl + a + “
&lt;/li&gt;
&lt;li&gt;Switch between panes: Ctrl + a + &amp;lt;- -&amp;gt;
&lt;/li&gt;
&lt;li&gt;Close down pane: exit or Ctrl + a + x
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tmux window commands
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create new window: Ctrl + a + c
&lt;/li&gt;
&lt;li&gt;Switch between windows:Ctrl + a + n  OR Ctrl + a + p
&lt;/li&gt;
&lt;li&gt;Switch between windows: Ctrl + a + 0 OR Ctrl + a + 1
&lt;/li&gt;
&lt;li&gt;Rename windows: Ctrl + a + ,
&lt;/li&gt;
&lt;li&gt;Exit Windows: &lt;code&gt;exit&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Tmux session commands
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;View Tmux session: &lt;code&gt;tmux ls&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start new session: &lt;code&gt;tmux new -s docker&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Rename session: &lt;code&gt;tmux rename-session -t 0 git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Detach session: Ctrl + a + d
&lt;/li&gt;
&lt;li&gt;Reattach session: &lt;code&gt;tmux attach -t 0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delete or kill session: &lt;code&gt;tmux kill-session -t docker&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's all the commands we need to get going with tmuxinator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tmuxinator
&lt;/h2&gt;

&lt;p&gt;Tmuxinator is a tool that allows you to easily manage tmux sessions by using yaml files to describe the layout of a tmux session, and open up that session with a single command.&lt;/p&gt;

&lt;p&gt;Installation: &lt;code&gt;gem install tmuxinator&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tmuxinator commands
&lt;/h2&gt;

&lt;p&gt;Create new template: &lt;code&gt;&lt;/code&gt;&lt;code&gt;Tmuxinator new &amp;lt;todo_project_name&amp;gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
Edit existing template: &lt;code&gt;Tmuxinator edit &amp;lt;project_name&amp;gt;&lt;/code&gt;&lt;br&gt;
Start project: &lt;code&gt;Tmuxinator start &amp;lt;project_name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We have a sample rails project as backend and react project as frontend.&lt;/p&gt;

&lt;p&gt;Usually for development purpose we need.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;editor&lt;/li&gt;
&lt;li&gt;rails server&lt;/li&gt;
&lt;li&gt;sidekiq server&lt;/li&gt;
&lt;li&gt;rails console&lt;/li&gt;
&lt;li&gt;git for rails project&lt;/li&gt;
&lt;li&gt;react npm start&lt;/li&gt;
&lt;li&gt;git for react project&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can create a predefined template using tmuxinator.&lt;br&gt;
To start creating new project template in terminal: &lt;code&gt;&lt;/code&gt;&lt;code&gt;tmuxinator new &amp;lt;project name&amp;gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A editor is opened with yml file for project setup.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Give name to your project&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;name: todo&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to define root of the project&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;root: ~/Documents/react-practice/todo-api&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then you can define you different windows are shown&lt;br&gt;
and commands to execute in that window.&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;server: bundle exec rails s -p 4001&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
Above will create a window name server and start the rails server in the specified root folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can define panes in window which splits the screen&lt;/p&gt;

&lt;pre&gt;
react_project:
  root: ~/Documents/react-practice/todo-app
  layout: even-horizontal
  panes:
    - npm start
    - git status
&lt;/pre&gt;

&lt;p&gt;Above will create a window name react_project, change root folder for this window to react app then will start react server and git in 2 horizontal equally split panes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A sample tmuxinator file for starting rails and react server.&lt;/p&gt;

&lt;pre&gt;
name: todo
root: ~/Documents/react-practice/todo-api

windows:
  - editor: vim .
  - server: bundle exec rails s -p 4001
  - sidekiq: bundle exec sidekiq
  - git: git status
  - rails_console: bundle exec rails console
  - react_project:
      root: ~/Documents/react-practice/todo-app
      layout: even-horizontal
      panes:
        - npm start
        - git status
&lt;/pre&gt;

&lt;p&gt;To start the development setup using tmuxinator in terminal.&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;tmuxinator start todo&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Tmux session for todo app with different windows and panes.&lt;br&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%2Feewxt03tg4rcw6bgoj8p.jpg" 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%2Feewxt03tg4rcw6bgoj8p.jpg" alt="Todo App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To close the todo app tmux session.&lt;br&gt;
&lt;code&gt;&lt;/code&gt;&lt;code&gt;tmuxinator stop todo&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Hope this will help you.&lt;br&gt;
Thank you for reading&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>tmux</category>
      <category>tmuxinator</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
