DEV Community

loading...
Cover image for Creating a
Docker image
for a Ruby on Rails application!

Creating a Docker image for a Ruby on Rails application!

devneto profile image Miguel Updated on ・3 min read

Hi everyone, this article aims to demonstrate and instruct beginners in assembling a Docker image and, subsequently, in creating a container for a Ruby on Rails application. Good reading 😉.

How to install docker?

What is Docker?
In short, the Docker is a platform with a high level of performance that aims to create development environment management, committing to quickly provide complete environments for an application.

To create this environment creation, Docker uses concepts such as images that are a static representation of the application and its configuration and dependencies. A Dockerfile is responsible for inferring all the dependencies and configurations of the application.

Imagine an image as a formless box, but with all the attributes necessary to become something.

Alt Text

Let's create an image to show in practice.

Creating a ruby ​​image.

Let's create a file called Dockerfile with the following content.

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs 
WORKDIR /app
COPY Gemfile /app/Gemfile
COPY Gemfile.lock /app/Gemfile.lock
RUN bundle install
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
Enter fullscreen mode Exit fullscreen mode

We use FROM to instantiate the image we want to use as a base, in this case we will use the official ruby ​​image in version 2.5, this image can be found on the Docker Hub.

RUN is used to execute commands when starting an image instance, in this case we are running the apt-get command to perform an update and install nodejs.

WORKDIR shows which folder will be used inside the container. In this case the /app folder will be used.

Create a Gemfile file with the following content.

source 'https://rubygems.org'
gem 'rails', '~> 5.2.6'
Enter fullscreen mode Exit fullscreen mode

And a Gemfile.lock file with the command in your console:

~$ touch Gemfile.lock
Enter fullscreen mode Exit fullscreen mode

COPY It is used to copy a Gemfile from your current host to the image.

EXPOSE inserts 3000 in the EXPOSE environment variable.

CMD The primary purpose of CMD is to provide standards for a running container.

Generating our image:

~$ docker build . --tag rails      
Enter fullscreen mode Exit fullscreen mode

We use the tag flag to name our image.

The . is used to search for a Dockerfile in our directory to generate the image.

List your images to see if they were created correctly with the command:

~$ docker images
Enter fullscreen mode Exit fullscreen mode

Alt Text

Successful.

Creating our docker compose.

Docker Compose is a tool for defining and running Docker applications from multiple containers.

Create a file called docker-compose.yml with this content:

version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    depends_on:
      - db
Enter fullscreen mode Exit fullscreen mode

We used version 3.9 for the docker compose, and created two services called db and web.

We say when composing using a postgress image to create a container and we create POSTGRES_PASSWORD as an environment variable.

The volume refers to the area we want to share between the container and our machine. We say that the current directory is referenced by /app inside the container, and so we create a connection between them.

The ports refer to which host port will be mirrored in the container.

depends_on infers that the service will only be started when the instantiated one finishes its initiation.

Build the project.

~$ docker-compose run --no-deps web rails new . --force --database=postgresql
Enter fullscreen mode Exit fullscreen mode

After that the rails architecture will be downloaded to your current directory.

Run the build command again.

~$ docker-compose build 
Enter fullscreen mode Exit fullscreen mode

and

~$ sudo chown -R $USER:$USER .
Enter fullscreen mode Exit fullscreen mode

for permissions.

Lastly, run:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

and

docker-compose run web rake db:create
Enter fullscreen mode Exit fullscreen mode

To create our database.

And so you will have a complete rails application running on a docker.

Alt Text

Time is very important, thanks for sharing a little bit of yours with me 😊.

image

image

Discussion (4)

Collapse
spaceshipdev profile image
spaceshipdev • Edited

Truly eager to get this rails docker dev workflow down. I bought PragProg’s ‘Docker for Rails Developers’ some years back and still struggle to make any real repetitive progress developing in rails this way.
Perhaps some contribution here, above it’s mentioned permissions have to change, although I think this step needs to be switched otherwise the docker build command will not run.
Also; currently docker-compose up fails with

- bundler: failed to load command: rails GemNotFound public_suffix-4.0.6 in any of the sources`
Enter fullscreen mode Exit fullscreen mode

UPDATE: spent some time today getting to the bottom of this, if I may might I suggest the following edits: -
For Dockerfile

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . .

# run this every time 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"]
Enter fullscreen mode Exit fullscreen mode

For docker-compose.yml

version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
Enter fullscreen mode Exit fullscreen mode

Not forgetting entrypoint.sh


#!/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 "$@"

Enter fullscreen mode Exit fullscreen mode
Collapse
devneto profile image
Miguel Author

Thanks for the report, I will review the article to fix possible issues.

Collapse
k41n3w profile image
Caio Ramos

Fiz uma conta aqui só para comentar o quão top é seu post, parabéns e obrigado!

Collapse
devneto profile image
Miguel Author

Muito obrigado pelo feedback, Caio!

Forem Open with the Forem app