Table of Contents

Introduction

A curious developer and tech enthusiast never miss an opportunity to learn a little more every day! I can absolutely relate to this urge to learn. So, we are back with another Rails tutorial on how to dockerize rails app with the help of rails docker compose. Please be familiar with what is Docker and why do we need Docker.

Let’s get started with app development and dockerizing it.

Create a Rails App

Fire the following commands to create a rails app.

Copy Text
mkdir ~/projects/noteapp
cd ~/projects/noteapp

Prerequisites: Dockerize Rails App

As we are implementing Docker Compose, make sure about the following installations before getting started.

Create a Dockerfile

The Dockerfile is the foundation of any Dockerize Ruby on Rails app. It contains all the instructions for building the application image. You can set this up by installing Ruby and all of its dependencies. The Dockerfile consists of the following instructions.

// Dockerfile

Copy Text
FROM ruby:2.3.0
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /noteapp
WORKDIR /noteapp
ADD Gemfile /noteapp/Gemfile
ADD Gemfile.lock /noteapp/Gemfile.lock
RUN bundle install
ADD . /noteapp

Dockerfile will keep the app code inside an image, building a container with Bundler, Ruby, and other dependencies. Therefore in the root directory of the application, create a new Dockerfile using the command touch Dockerfile and put the content of the above dockerfile inside it.

Explanation

1. FROM ruby:2.3.0: Tells Docker to use the prebuilt Ruby image. There are several choices, but this project uses the ruby:2.3.0 image.
2. RUN: To run commands. Here, RUN is for installing different software pieces with Apt.
3. WORKDIR: For stating the base directory from where all the commands are executed.
4. ADD: For copying files from the host machine to our container.

Create a Gemfile

Next, open the editor and create a bootstrap Gemfile that loads Rails.

// gemfile

Copy Text
source 'https://rubygems.org'
gem 'rails', '~>5.0.0'

Create an empty Gemfile.lock file to build our Dockerfile.

Copy Text
touch Gemfile.lock

Dockerize Rails App: Add Portability, Modularity, and Scalability to your app
Contact Bacancy and hire Rails developer to dockerize your rails application.

Define Services Using Docker Compose

Finally, moving towards the most important section. The docker-compose.yml file will consist of services needed for your app (web application and DB), for getting each other’s Docker image, and the config for connecting them and making it visible on the port.

// docker-compose.yml

Copy Text
version: '2'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: noteapp
        MYSQL_USER: appuser
        MYSQL_PASSWORD: password
   ports:
        - "3307:3306"
    app:
        build: .
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
        volumes:
            - ".:/noteapp"
        ports:
            - "3001:3000"
        depends_on
          - db
        links:  
             - db

Build the Project

Now build the skeleton of the rails application with the help of docker-compose run.

Copy Text
docker-compose run app rails new . --force --database=mysql 
  • compose– builds the image for the app service, which we have to define inside our docker-compose.yml
  • runs rails new – using that image it runs the app inside a new container
  • database=mysql– to define the database

Your application should be created after the command is successfully executed. List the files using ls -l

Database Connection

In this section, we will connect the database as rails wants a database to be running on the localhost.

We will also alter the database and username for aligning it with the defaults by the MySQL image. When we run the docker-compose command first, it will create a DB container that downloads the MySQL database image and creates a DB based on the environment variables set in the docker-compose.yml file.

By now, we have a database container, and app structure created. We need to edit the config/database.yml file and set the configurations from the environment variables.

Replace the contents of config/database.yml with the following:

// docker-compose.yml

Copy Text
version: '2'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
        MYSQL_ROOT_PASSWORD: password
        MYSQL_DATABASE: noteapp
        MYSQL_USER: appuser
        MYSQL_PASSWORD: password
   ports:
        - "3307:3306"
    app:
        build: .
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
        volumes:
            - ".:/noteapp"
        ports:
            - "3001:3000"
        depends_on:
          - db
        links:  
             - db
        environment :
            DB_USER: root
            DB_NAME: noteapp
            DB_PASSWORD: password
            DB_HOST: db

After setting up the docker-compose.yml, run the docker-compose build command to build an image for the app and install all the required gems.

Run the below command for database creation.

Copy Text
docker-compose run --rm app rake db:migrate

Before creating any migrations/models, let’s do a docker-compose up to start both app and database services and boot the application after making the changes in database.yml.

We can see that rails is running on port 3000 in the container after the command is successfully executed. But, that’s not the port on the host, so we won’t be able to access it on the browser. As per docker-compose, we have exposed the port on the localhost from 3000 to 3001; therefore, it should be available on localhost:3001.

Once you are done with the app running on the browser, create a model and perform the migration using these commands in a different console of the project directory.

Copy Text
docker-compose run --rm app rails g scaffold note title body:text
docker-compose run --rm app rake db:migrate

Now, we can access the application on port 3001- localhost:3001/notes and perform actions on the application.

Summary: How to Dockerize Rails App

  • mkdir ~/projects/noteapp
  • cd ~/projects/noteapp
  • Create Gemfile and empty Gemfile.lock (content is given above)
  • Create Dockerfile (content is given above)
  • Create docker-compose.yml (content is given above)
  • docker-compose run app rails new . –force –database=mysql
  • Make changes in config/database.yml
  • docker-compose build
  • docker-compose up
  • http://localhost:3001
  • docker-compose run –rm app rails g scaffold note title body:text
  • docker-compose run –rm app rake db:migrate
  • http://localhost:3001/notes

Watch the video tutorial on how to dockerize rails app as well.

Source Code: dockerize-rails-app

You can also clone the code and go through the project. Here’s the source code of the repository: dockerize-rails-app

Commands: Stop, Restart, and Rebuild the Application

  • To stop the application
Copy Text
docker-compose down
  • To restart the application
Copy Text
docker-compose up
  • To rebuild the application

Rebuilding the application is a must when you’re trying different configs and altering the Gemfile or Compose file.
➡ Sometimes only docker-compose up –build is enough.
➡ But, if you want to rebuild the entire app fully, then use docker-compose run app bundle install, followed by docker-compose up –build for synchronizing changes between the Gemfile.lock and the host.

Conclusion

That’s it for the tutorial: how to dockerize rails app using Docker compose. I hope the tutorial was helpful to you for building your own demo app and exploring more.

Visit the Ruby on Rails tutorials page for similar tutorials, where you can explore your interests and play around with the code. Looking for skilled rails developers who can help you meet your project requirements? Contact us and hire Rails developer.

Hire Ruby on Rails Developer

Connect Now

Build Your Agile Team

Hire Skilled Developer From Us

[email protected]

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.

How Can We Help You?