Create And Dockerize Rails Application With PostgreSQL And Sidekiq (Docker + Docker Compose)
ThinEi
Posted on March 6, 2023
For this setup, I will use the ruby version 3.1.2 which will generate the rails app of rails version 7.0.4.
rails new ecs_rails_app -d postgresql
Our application is created. Let’s create Dockerfile.
cd ecs_rails_app
# Creating Dockfile
touch Dockerfile
# Creating development directory and docker-compose file
mkdir development && touch development/docker-compose.yml
# Creating entrypoint.sh file
touch entrypoint.sh
Dockerfile
Paste the following content into Dockerfile
FROM ruby:3.1.3
# install rails dependencies
RUN apt-get clean all && apt-get update -qq && apt-get install -y build-essential libpq-dev \
curl gnupg2 apt-utils postgresql-client postgresql-server-dev-all git libcurl3-dev cmake \
libssl-dev pkg-config openssl imagemagick file nodejs npm yarn
RUN mkdir /rails-app
WORKDIR /rails-app
# Adding gems
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install
COPY . /rails-app
# 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"]
Entrypoint.sh
paste the following code into entrypoint.sh file
#!/bin/bash
set -e
# Remove a potentially pre-existing server.pid for Rails.
rm -f /rails-app/tmp/pids/server.pid
exec "$@"
Now build the docker image.
docker build .
Docker Compose
I'll add Postgresql, Redis and web (our rails project) services in our docker compose file.
Firstly, we need some adjustment, database.yml file should look like this:
default: &default
adapter: postgresql
encoding: unicode
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
port: <%= ENV['DB_PORT'] %>
host: <%= ENV['DB_HOST'] %>
database: <%= ENV['DB_NAME'] %>
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
test:
<<: *default
production:
<<: *default
Open the docker-compose.yml file located in development folder and paste the following code:
version: "3.8"
services:
db:
image: postgres
restart: always
environment:
- POSTGRES_HOST_AUTH_METHOD=trust
volumes:
- db:/var/lib/postgresql/data'
logging:
driver: none
ports:
- 5432:5432
redis:
image: redis:4.0-alpine
command: redis-server
volumes:
- redis:/data
ports:
- 6379
logging:
driver: none
web:
build: ../
command: bundle exec rails s -p 3000 -e development -b '0.0.0.0'
environment:
DB_USERNAME: postgres
DB_PASSWORD: password
DB_NAME: ecs_application_db
DB_PORT: 5432
DB_HOST: db
RAILS_ENV: development
RAILS_MAX_THREADS: 5
REDIS_HOST: redis
REDIS_PORT: 6379
BUNDLE_PATH: /bundle
volumes:
- ../:/rails-app
- bundle:/bundle
ports:
- "3000:3000"
depends_on:
- "db"
- "redis"
volumes:
db:
bundle:
redis:
I have created 3 services (db, redis and web)
Our rails application requires postgresql database and redis (in the future for sidekiq). Docker compose is creating postgres and redis service for our rails application inside docker-compose.yml file.
- db service is using postgres docker image from docker hub
- redis service is using redis docker image from docker hub
- web service is our rails application project containing our own Dockerfile
cd development/
docker-compose run web bundle install
docker-compose run web rails db:migrate
docker-compose run web rails db:setup
docker-compose build
Then run the final command to instantiate rails server
docker-compose up
Configure sidekiq
Add gems into Gemfile:
gem 'sidekiq', '< 7'
gem 'redis-rails'
Create following files:
touch config/initializers/sidekiq.rb
Paste following code into sidekiq.rb file
# frozen_string_literal: true
sidekiq_config = { url: "redis://#{ENV['REDIS_HOST']}:#{ENV['REDIS_PORT']}/12" }
Sidekiq.configure_server do |config|
config.redis = sidekiq_config
end
Sidekiq.configure_client do |config|
config.redis = sidekiq_config
end
Go to development folder and install the new gems
docker-compose run web bundle install
We need to add a new service to the docker-compose.yml file
sidekiq:
build: ../
command: bundle exec sidekiq
volumes:
- ../:/rails-app
environment:
RAILS_ENV: development
REDIS_HOST: redis
REDIS_PORT: 6379
depends_on:
- "redis"
then run
docker-compose up
Then we will create a Controller, ActiveJob and some changes to the routes.
Create a controller and Active Job
docker-compose run web rails g controller home
docker-compose run web rails g job home
home_controller.rb
class HomeController < ApplicationController
def index
render json: {"message": "Welcome"}
HomeJob.perform_later
end
end
home_job.rb
class HomeJob < ApplicationJob
queue_as :default
def perform(*args)
puts 'Job Executed'
end
end
routes.rb
Rails.application.routes.draw do
get '/home', to: 'home#index'
end
then run
docker-compose build
docker-compose up
Open http://localhost:3000/home in your web browser,
in the console you should be able to see that the HomeJob has been performed.
Posted on March 6, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.