How to Setup Ruby Docker Container using Docker Compose

How to Setup Ruby Docker Container using Docker Compose. If you are actively developing applications- Docker can simplify your workflow and your deployment.  Docker  is a great choice to keep things organized. This tutorial will show you how to set up a development environment for a Ruby on Rails application using Docker. You will create a containers for the application itself and we will use PostgreSQL database. Let’s start!

What is Ruby on Rails

Ruby is a free, open source and one of the popular programming languages developed by Yukihiro “Matz” Matsumoto in the mid-1990s. Compared to C and Java language, Ruby is a general purpose language. Rails makes web development easier, providing a pre built structure for development and everything you need to build a web app. Ruby on Rails uses the Model View Controller (MVC) architecture.

Ruby on Rails software code is built on top of Ruby. It is an open source web development framework that contains a collection of code libraries. It is considered a top choice of frameworks for startups as it is great for handling complex business logic and for delivering  a web apps quickly.  Ruby on Rails offers a complete solution for repetitive tasks like developing tables, forms or menus on the website.

Ruby features

  • Automated Testing- RoR runs its own set of tests on the code you write.
  • Symbol garbage collector.
  • Speedy software development.
  • Reliable and accurate as it has a test driven methodology.
  • Best for high trafficked and large projects requiring variety of drastic transformations.
  • The localization feature with ROR helps to integrate your pre designed code into the RoR framework for large projects.
  • Action Mailer and Action view.
  • Turbolinks.
  • Action cable.
  • Rails API.
  • Render from anywhere
  • Rake command
  • Scaffolding where the programmer is able to define how the application database should function. 
  • Customized library -vast libraries to assist developer with all the tools to produce high quality product (AJAX library, Database access library and Common tasks library).

What is Docker

Docker is a free and open source containerization platform that allows you to package up an application or service with all of its dependencies into a standardized image. It allows us to build and replicate images on any host, removing the inconsistencies of dev environments and reducing onboarding timelines considerably. The Docker image contains the code, runtime, system libraries and anything that required to deploy an application. If you are developing a Ruby application, you will need a specific version of Ruby, Bundler, project-specific gems and other dependencies based on the operating system. In this case, you can use Docker to keep things organized. Docker simplifies your workflow and the process of deploying your application to production.

Docker features

  • An open source solution
  • Easy and fast configuration.
  • An isolated, rapid framework.
  • Increases productivity.
  • Swarm. A clustering and scheduling tool for Docker containers.
  • Routing Mesh.
  • Cross cloud infrastructure.
  • Moderate CPU/memory overhead.
  • Fast reboot.
  • Security Management.

Follow this post to learn how to setup Ruby Docker container using Docker Compose.

How to Setup Ruby Docker Container using Docker Compose

Install Docker

To deploy a Ruby server using the Docker Compose, you will need to install the Docker on your server. By default, the latest version of Docker is not included in the Debian or Ubuntu default repository. So it is recommended to install Docker from the Docker’s official repository.

First, install all required dependencies using the following command:

				
					apt-get install git apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y
				
			

Please download and add the Docker GPG key with the following command:

				
					curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
				
			

Add the Docker repository with the following command:

				
					add-apt-repository  "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
				
			

Once the repository is added, update the repository cache using the following command:

				
					apt-get update -y
				
			

Finally, install the Docker CE by running the following command:

				
					apt-get install docker-ce -y
				
			

Once the Docker is installed, start it using the following command:

				
					systemctl start docker
				
			

To verify the active status of the Docker, run the following command:

				
					systemctl status docker
				
			

You will get the following output:

				
					● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2022-05-11 14:58:54 UTC; 59s ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 4310 (dockerd)
      Tasks: 8
     Memory: 35.0M
        CPU: 591ms
     CGroup: /system.slice/docker.service
             └─4310 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

May 11 14:58:53 debian11 dockerd[4310]: time="2022-05-11T14:58:53.130577231Z" level=info msg="scheme \"unix\" not registered, fallback to def>
May 11 14:58:53 debian11 dockerd[4310]: time="2022-05-11T14:58:53.130643324Z" level=info msg="ccResolverWrapper: sending update to cc: {[{uni>
May 11 14:58:53 debian11 dockerd[4310]: time="2022-05-11T14:58:53.130679866Z" level=info msg="ClientConn switching balancer to \"pick_first\">
May 11 14:58:53 debian11 dockerd[4310]: time="2022-05-11T14:58:53.289737295Z" level=info msg="Loading containers: start."
May 11 14:58:53 debian11 dockerd[4310]: time="2022-05-11T14:58:53.768316041Z" level=info msg="Default bridge (docker0) is assigned with an IP>
May 11 14:58:53 debian11 dockerd[4310]: time="2022-05-11T14:58:53.982174628Z" level=info msg="Loading containers: done."
May 11 14:58:54 debian11 dockerd[4310]: time="2022-05-11T14:58:54.034840356Z" level=info msg="Docker daemon" commit=4433bf6 graphdriver(s)=ov>
May 11 14:58:54 debian11 dockerd[4310]: time="2022-05-11T14:58:54.035487755Z" level=info msg="Daemon has completed initialization"
May 11 14:58:54 debian11 systemd[1]: Started Docker Application Container Engine.
May 11 14:58:54 debian11 dockerd[4310]: time="2022-05-11T14:58:54.097373599Z" level=info msg="API listen on /run/docker.sock"
				
			

To verify the Docker version, run the following command:

				
					docker version
				
			

You should see the Docker version in the following output:

				
					Client: Docker Engine - Community
 Version:           20.10.15
 API version:       1.41
 Go version:        go1.17.9
 Git commit:        fd82621
 Built:             Thu May  5 13:19:21 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.15
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.9
  Git commit:       4433bf6
  Built:            Thu May  5 13:17:26 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.4
  GitCommit:        212e8b6fa2f44b9c21b2798135fc6fb7c53efc16
 runc:
  Version:          1.1.1
  GitCommit:        v1.1.1-0-g52de29d
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

				
			

Install Docker Compose

By default, the latest version of Docker Compose is not included in the Ubuntu and Debian repository. So it is a good idea to download the latest version of Docker Compose from the GitHub.

				
					curl -s https://api.github.com/repos/docker/compose/releases/latest | grep browser_download_url  | grep docker-compose-linux-x86_64 | cut -d '"' -f 4 | wget -qi -
				
			

Once the Docker Compose binary is downloaded, set the executable permission of the downloaded binary file using the following command:

				
					chmod +x docker-compose-linux-x86_64
				
			

Next, move the Docker Compose binary to the system path using the following command:

				
					mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
				
			

You can now verify the Docker Compose version using the following command:

				
					docker-compose version
				
			

You should see the following output:

				
					Docker Compose version v2.5.0
				
			

Create Ruby on Rails Project

First, create a directory for Ruby on Rails project using the following command:

				
					mkdir -p ~/rails
				
			

Next, navigate to your rails directory and create a Rails container using the following command:

				
					cd ~/rails/
docker run --rm -v ${PWD}:/usr/src -w /usr/src -ti ruby:alpine sh
				
			

This command will download and run the Ruby container, mount the local directory to the /usr/src directory, execute the shell command and move to the app directory:

				
					Unable to find image 'ruby:alpine' locally
alpine: Pulling from library/ruby
df9b9388f04a: Pull complete 
837e9cfc7e43: Pull complete 
c7850f1a8c23: Pull complete 
ae0a3cc0f34c: Pull complete 
81637037ea3a: Pull complete 
Digest: sha256:0b91e98c4613c2287bb7274a1584ea141b68960fb6b0edd7fe32127dc888d1a0
Status: Downloaded newer image for ruby:alpine
/usr/src # 

				
			

Now, run the following commands inside the container to install the Ruby on Rails:

				
					cd app
apk add build-base
apk add git
gem install -N rails
				
			

Please create a new application named app with PostgreSQL database:

				
					rails new app --database=postgresql --skip-bundle
				
			

Next, exit from the Docker container with the following command:

				
					exit
				
			

Now, verify your app directory using the following command:

				
					ls -l app/
				
			

You should see the following output:

				
					total 60
drwxr-xr-x 10 root root 4096 May 11 15:16 app
drwxr-xr-x  2 root root 4096 May 11 15:16 bin
drwxr-xr-x  5 root root 4096 May 11 15:16 config
-rw-r--r--  1 root root  160 May 11 15:16 config.ru
drwxr-xr-x  2 root root 4096 May 11 15:16 db
-rw-r--r--  1 root root 2268 May 11 15:16 Gemfile
drwxr-xr-x  4 root root 4096 May 11 15:16 lib
drwxr-xr-x  2 root root 4096 May 11 15:16 log
drwxr-xr-x  2 root root 4096 May 11 15:16 public
-rw-r--r--  1 root root  227 May 11 15:16 Rakefile
-rw-r--r--  1 root root  374 May 11 15:16 README.md
drwxr-xr-x  2 root root 4096 May 11 15:16 storage
drwxr-xr-x 10 root root 4096 May 11 15:16 test
drwxr-xr-x  5 root root 4096 May 11 15:16 tmp
drwxr-xr-x  2 root root 4096 May 11 15:16 vendor

				
			

Configure Rails Project

First, you will need to create a Docker file for Rails application. You can create it inside the rails directory:

				
					cd ~/rails
nano Dockerfile

				
			

Add the following lines:

				
					FROM ruby:alpine

RUN apk update
RUN apk add build-base nodejs postgresql-dev tzdata
RUN gem install -N rails

RUN mkdir -p /app
WORKDIR /app

COPY ./app/Gemfile /app
COPY ./app/Gemfile.lock /app
RUN bundle install --binstubs

				
			

Save and close the file then navigate to the app directory and create a lock file:

				
					cd app/
touch Gemfile.lock
				
			

Next, edit the database configuration file:

				
					nano config/database.yml
				
			

Change the following lines:

				
					default: &default
   adapter: postgresql
   encoding: unicode
   host: db
   username: postgres
   pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
   timeout: 5000

				
			

Save and close the file when you are finished.

Create Docker Compose File

Next, create a new Docker Compose file for Rails application.

				
					nano ~/rails/docker-compose.yml
				
			

Add the following lines:

				
					version: '3.6'

services:

  db:
    image: postgres:alpine
    volumes:
      - ./postgresql:/var/lib/postgresql/data
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust

  web:
    build: .
    volumes:
      - ./app:/app
    working_dir: /app
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    ports:
      - 80:3000
    depends_on:
      - db

				
			

Save and close the file then create PostgreSQL directory:

				
					mkdir -p ~/rails/postgresql
				
			

Build the Ruby on Rails Project

Now, navigate to the rails directory and build the Ruby on Rails project using the Docker Compose:

				
					cd ~/rails/
docker-compose build

				
			

You should see the following output:

				
					 => [internal] load build definition from Dockerfile                                                                                     0.0s
 => => transferring dockerfile: 265B                                                                                                     0.0s
 => [internal] load .dockerignore                                                                                                        0.0s
 => => transferring context: 2B                                                                                                          0.0s
 => [internal] load metadata for docker.io/library/ruby:alpine                                                                           0.0s
 => [1/9] FROM docker.io/library/ruby:alpine                                                                                             0.1s
 => [internal] load build context                                                                                                        0.0s
 => => transferring context: 2.37kB                                                                                                      0.0s
 => [2/9] RUN apk update                                                                                                                 1.0s
 => [3/9] RUN apk add build-base nodejs postgresql-dev tzdata                                                                           14.5s
 => [4/9] RUN gem install -N rails                                                                                                      14.3s 
 => [5/9] RUN mkdir -p /app                                                                                                              0.5s 
 => [6/9] WORKDIR /app                                                                                                                   0.0s 
 => [7/9] COPY ./app/Gemfile /app                                                                                                        0.0s 
 => [8/9] COPY ./app/Gemfile.lock /app                                                                                                   0.0s 
 => [9/9] RUN bundle install --binstubs                                                                                                 31.9s 
 => exporting to image                                                                                                                   9.0s 
 => => exporting layers                                                                                                                  9.0s 
 => => writing image sha256:61e8f1ac1f5f288d440d1ebcbcbf5b6741bc82fa40d86e65446c5e74a478d3e1                                             0.0s 
 => => naming to docker.io/library/rails_web                                                                                             0.0s 

				
			

Next, generate the PostgreSQL database using the following command:

				
					docker-compose run web rake db:create
				
			

You should see the following output:

				
					[+] Running 1/0
 ⠿ Container rails-db-1  Recreated                                                                                                       0.1s
[+] Running 1/1
 ⠿ Container rails-db-1  Started                                                                                                         0.5s
Created database 'app_development'
Created database 'app_test'

				
			

You can verify the all Docker images using the following command:

				
					docker images
				
			

You should see the following output:

				
					REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
rails_web    latest    c8c1f2c916ef   19 minutes ago   718MB
ruby         alpine    0bf06f4f0410   4 weeks ago      68.3MB
postgres     alpine    ebf01b748a56   5 weeks ago      211MB

				
			

Finally, bring up all application defined in the Docker Compose file:

				
					docker-compose up -d
				
			

You should see the following output:

				
					[+] Running 2/2
 ⠿ Container rails-db-1   Running                                                                                                        0.0s
 ⠿ Container rails-web-1  Started                                                                                                        1.2s

				
			

Now, run the following command to see all running applications:

				
					docker-compose ps
				
			

You should see the following output:

				
					NAME                COMMAND                  SERVICE             STATUS              PORTS
rails-db-1          "docker-entrypoint.s…"   db                  running             5432/tcp
rails-web-1         "bundle exec rails s…"   web                 running             0.0.0.0:80->3000/tcp, :::80->3000/tcp

				
			

Access Ruby on Rails

Now, open your web browser and type the URL http://your-serevr-ip to access the Ruby on Rails application. You should see the Ruby on Rails dashboard on the following screen:

How to Setup Ruby Docker Container using Docker Compose Conclusion

In this post, we explained how to setup Ruby Docker container using Docker Compose. We also create a simple Rails application and deploy it inside the Docker container.

I really enjoy developing Rails applications with Docker Compose. It’s ensures your production environment is exactly the same as your local machine. As this technology matures even more this method of development will become more of a standard .

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

5 1 vote
Article Rating
Subscribe
Notify of
0 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x