DEV Community

Cover image for More than "Hello World" in Docker: Build Rails + Sidekiq web apps in Docker

More than "Hello World" in Docker: Build Rails + Sidekiq web apps in Docker

Raphael Jambalos on July 28, 2019

This is the first post in the More than "Hello World" in Docker series. The series will help you ready your app: from setting it up locally to dep...
Collapse
 
belgoros profile image
Serguei Cambour

Thank you for sharing, Raphael. One point - you don't need to set autoload_paths because of all the directories under app are loaded by Rails by default. See guides.rubyonrails.org/v5.2/autolo....

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Thanks for the tip Serguei! :D I'll try that out in my Rails 5.2 setup

Collapse
 
tmhall99 profile image
Tom Hall

Hi Raphael, thanks for writing this up! I made it all the way to the end but when I click any of the links on the page the number doesn't increment and I get the following message on the server. However when I reload the page the number does appear to be incremented.

web_1 | Started POST "/increment_async?post_id=3" for 172.19.0.1 at 2019-11-14 16:13:27 +0000
web_1 | Cannot render console from 172.19.0.1! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
web_1 | Processing by HomeController#increment_async as HTML
web_1 | Parameters: {"authenticity_token"=>"nJyVPYC66u05NEifhJpSU8j45OihvALWatPZded9kBbveo8I463AVM9+XjHiOABKtnh9FvjxAfOkcbdC1oEhiA==", "post_id"=>"3"}
sidekiq_1 | 2019-11-14T16:13:27.719Z pid=1 tid=gs60ykwsh class=IncrementCountWorker jid=ff410d219f7e7968abf5a765 INFO: start
sidekiq_1 | 2019-11-14T16:13:28.145Z pid=1 tid=gs60ykwsh class=IncrementCountWorker jid=ff410d219f7e7968abf5a765 elapsed=0.424 INFO: done
web_1 | No template found for HomeController#increment_async, rendering head :no_content
web_1 | Completed 204 No Content in 1241ms (ActiveRecord: 0.0ms)

Collapse
 
raphael_jambalos profile image
Raphael Jambalos • Edited

Hi Tom,

Thank you for reading through the article, and providing me with this feedback. I have update the article with the answer to your question. I also included the answer below for easier reference

In step 7.5, copy-paste this snippet instead. This adds the line redirect_to root_path in the controller function increment_async so it goes to the homepage once the link is pressed.

class HomeController < ApplicationController
  def index
    @message = "Dynamic"

    @posts = Post.all
  end

  def increment_async
    ::IncrementCountWorker.perform_async(params[:post_id])

    redirect_to root_path # THIS IS THE ADDED LINE
  end
end
Collapse
 
tmhall99 profile image
Tom Hall

Excellent, thanks Raphael!

Collapse
 
chunallen profile image
Allen Chun
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ../../tmp/db:/var/lib/postgresql/data
  web:
    build: ../../
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - ../../:/myapp
    environment:
      RAILS_ENV: "development"
      REDIS_URL: "redis://redis:6379/12"
    ports:
      - "3000:3000"
    depends_on:
      - db
  redis:
    image: redis
    volumes:
      - ../../tmp/db:/var/lib/redis/data
  sidekiq:
    build: ../../
    command: 'bundle exec sidekiq'
    volumes:
      - ../../:/myapp
    environment:
      RAILS_ENV: "development"
      REDIS_URL: "redis://redis:6379/12"
    depends_on:
      - redis

Adding sidekiq and web at docker-compose.yml will build twice when you run docker-compose build

The building process is slow. Is there anything can we improve here?

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Hi Allen, that's an interesting observation.

Indeed, the build process will be slow especially on the 1st run. This is because our Dockerfile uses the base image "ruby:2.5.1-slim". This base image itself consists of many other images that include individual parts of the system (like its slim OS).

Docker is smart in that it creates a "reusable layer" for each line in your Dockerfile. It is also intelligent enough to detect if you made changes in your system with respect to those commands. If no change has been made with respect to that line in your Dockerfile, it just reuses that layer as part of your image.

Also, ran for the 1st time, it also runs the 2nd command in the Dockerfile: RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs libsqlite3-dev. This updates apt and install critical dependencies. This indeed takes awhile. In one of the demoes I did, it downloaded 250MB worth of packages from the internet.

After the 1st run, all you change is your code (and maybe adding Gems in your Gemfile here and there). Your docker build will hopefully be much faster (unless you changed a big part of your app).

As per Sidekiq and Web having separate images, it might be that they are just tagged under different names. You can check if their image hash (it looks like this: c12dasd21c) are the same. If they are, they are using the same image. And even if they are using different images, you can check that they use command Docker image layers via docker history <chash> and they have at least some common docker image layers.

Collapse
 
mariajosecg profile image
mariajosecg

Hi Raphael, how you're doing?
I have a problem for execute sidekiq in my app, I hope you can help me.
I created a container for execute sidekiq from sidekiq-entrypoint.sh. After executing the docker-compose up rails command, I check the created containers and I get:

CONTAINER ID--------- IMAGE
282afcb874ef-------------legacy_sidekiq

COMMAND-------------------CREATED-----------STATUS
"./sidekiq-entrypoin…"-----6 minutes ago-------Up 6 minutes

PORTS--------------------------NAMES
0.0.0.0:8081->8080/tcp-----legacy_sidekiq_1

Also, I try to access the sidekiq dashboard through 0.0.0.0:8081/sidekiq or 0.0.0.0:8080/sidekiq, but I get 'Not found'.

My routes:
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'

If you need other data, I will be attentive.

Collapse
 
jayehernandez profile image
Jaye Hernandez

Such a thorough explanation about Docker. Looking forward to the next posts in this series, particularly the automatic deploys!

Collapse
 
belgoros profile image
Serguei Cambour • Edited

Raphael, what is RAILS_ENV: "docker_development"defined in the docker-compose.yml file?

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Hi Serguei, I made a mistake there. You must change it to "development" for it to work. I revised my article. Thank you for the feedback :D

Collapse
 
belgoros profile image
Serguei Cambour

Yeah, thank you, that's what I believed it to be.

Collapse
 
dangolant profile image
Daniel Golant

Hey man, this is great! I have been struggling to even get a task executing and this was exactly what I neded. Just one question: what is in docker_puma.rb? I have a puma.rb and I think it should be sufficient, trying to understand what we would want in a docker_puma.rb

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Hi Daniel, yup there shouldn't be any difference. I just copied docker_puma.rb from puma.rb. It just lets me specify a different configuration for (a) when puma is running in my local, (b) and for when puma is running on ECS. But there shouldn't be any problem if you decide to just puma.rbfor both (for now).

Collapse
 
correale12 profile image
Christopher Correale

Hello Raphael, great tutorial thanks so much. I don't have a lot of experience with docker, Sidekiq and Redis. Following the tutorial I ran into this error (Error connecting to Redis on 127.0.0.1:6379 (Errno::ECONNREFUSED) ) when clicking the "Like" link in the Rails app. It seems that the Redis URL is incorrect, it is looking for Redis in the "web" container. Any help would be greatly appreciated!!

Collapse
 
quinncuatro profile image
Henry Quinn

This needs way more post reactions. Great content, my dude.

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Thank you Henry! :D

Collapse
 
rorycawley profile image
Rory Cawley

Wonderful work Raphael, great detail that is so helpful!

Collapse
 
raphael_jambalos profile image
Raphael Jambalos

Thank you Rory! :D

Collapse
 
saluminati profile image
Salman Sohail

This is one of the best tech articles I have ever read. I was able to get AWS setup on ECS stack because of this series of articles.

Thanks for writing such detailed series mate.

Collapse
 
thomaswitt profile image
Thomas Witt

Good write. And - IS fargate coming soon? :)

Collapse
 
kingsathurthi profile image
kingsathurthi

Excellent article and I would like know the approximate cost for this setup so this would help me