Adding docker to a Ruby on Rails application might seem like a herculean task at first, but it’s actually not as difficult as it seems. In this article, I will walk you through Docker and how to dockerize a rails application.
What is Docker?
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and deploy it as one package. Docker is a set of platform-as-a-service products that use OS-level virtualization to deliver software in packages called containers.
To install docker on your computer, click here and select your OS.
Creating a Rails Application
I am using rails 6 to create a new rails application called docker-rails, with Postgres and without running a test.
rails new docker-rails -T --database=postgresql
Dockerizing the Application
Add a file called Dockerfile to the root directory of your application. Notice the file has no extension. Add the following lines of code in that file. I will explain each line later.
- FROM ruby:2.7.1
- RUN curl -sL https://deb.nodesource.com/setup_10.x | bash – \ && apt-get install -y nodejs postgresql-client
- RUN mkdir /docker-rails
- WORKDIR /docker-rails
- COPY Gemfile /docker-rails/Gemfile
- COPY Gemfile.lock /docker-rails/Gemfile.lock
- RUN bundle install –full-index
- COPY . /docker-rails
- COPY entrypoint.sh /usr/bin/
- RUN chmod +x /usr/bin/entrypoint.sh
- ENTRYPOINT [“entrypoint.sh”]
- EXPOSE 3000
- CMD [“rails”, “server”, “-b”, “0.0.0.0”]
* On line 1 we download Ruby; version 2.7.2 in this case.
* On line 2 we install NodeJS along with all its dependencies and Postgres.
* The code on line 3 creates a directory I called
docker-rails. But you can call yours any name you like.
* Line 4 sets
docker-railsas our working directory that holds all our files.
* Line 5 copies the content of the Gemfile from our directory to
docker-rails/Gemfile in the container.
* Line 6 also copies the content of
* Line 7 runs
bundle install to install and update our new
* Line 8 copies the entire content from the current directory to our working directory in the container
* Line 9 copies the content of a file named
entrypoint.sh We will add the file in a bit.
* Line 10 grants access to the file while line number 11 specifies the file to be used as an entrypoint.
* Line 12 exposes port 3000 so we can run the rails app on our browser on port 3000.
* Finally, Line 13 contains the command that will be executed to start or run the container.
Add a file named
entrypoint.sh and copy the following to it.
#!/bin/bash set -e # If the database exists, migrate. Otherwise setup #(create and migrate) bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:create db:migrate echo "Database has been created & migrated!" # Remove server.pid if it exists rm -f /docker-rails/tmp/pids/server.pid # execute container's main process (CMD in docker file) exec "$@"
The above code is executed when the entrypoint script is called in the Dockerfile. Add a file named
docker-compose.yml. It will contain dependencies of the application. The code that should be in the file is shown below:
version: '3' services: db: image: postgres environment: POSTGRES_PASSWORD: 'password1' PGHOST: "db" PGUSER: "postgres" PGDBNAME: "docker-rails" volumes: - ./tmp/db:/var/lib/postgresql/data web: build: . command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" volumes: - .:/docker-rails ports: - "3000:3000" depends_on: - db dns: - 18.104.22.168 - 22.214.171.124
To build our docker container we run
docker-compose build in the project root directory. This will download all required dependencies. After that, run
docker-compose up to start our docker container. Visit localhost:3000 to see your app running in a docker container.
Phew! You just dockerized your first rails application, not so difficult…was it?