Categories
Uncategorized

Docker for Rails Developers in 2022

The pragprog team has a great book called “Docker for Rails Developers” however it’s about 3 year old now… So just some minor notes here on how to make everything work right in Ruby 3 / Rails 7 world.

Docker is primary designed for deploying finished images of your software to production. Docker can work great in development, but just keep in mind that it’s not really designed for development, so you’ll always have to jump through a few extra hoops in exchange. Things like sharing files as your building an image and caching to speed up development builds are extra complicated. If you’ve ever setup a chroot environment, it’s not as simply as just including the stuff you directly want to use — there’s overhead.

As I’m writing, Rails v7.0.3 with Ruby 3.1.2 is current.
Yet this book is based on Rails v5.2.2 and Ruby 2.6.

Docker makes these kind of version changes super easy. I recommend just sticking with exactly what the book uses and explicitly setting:

gem install rails -v 5.2.2

If you keep rails on v5.2.2 then all of the rest of the instructions should work, and when you start the rails server with:

docker run -p 3000:3000 ${my-image-id} bin/rails s -b 0.0.0.0

You should get the Rails 5 welcome page…

Your other also very easy option is to just switch to a Ruby 3.1.2 based image… So in your Dockerfile just use:

From: ruby:3.1.2
# instead of From: ruby:2.6

The examples are so simple from a Ruby perspective that you should be fine either way. Always comforting when your screenshots exactly match the authors though, so I would stick with Rails 5.2.2 and Ruby 2.6 and work though this short book.

Highly recommend this one though. Changed the way I think about Docker, especially all the docker-compose stuff.

Once you get to Chapter 7, Playing Nice with JavaScript, the Ruby 2.6 instructions really start to break down. Node 8 and Node 10 are deprecated, so you’ll need to move to Node 12, and the default packages for that aren’t compatible with the Debian base image that Ruby 2.6 is built on.

With Rails 7, we’ve kind of moved on from WebPacker anyway, but if you really want to do that part, I got it to build fine by using this as my Dockerfile.Basically, set ruby to 3.1.2, use setup_12.x for Node JS AND make sure to generate your rails app with Rails 7.

❯ cat Dockerfile        
FROM ruby:3.1.2

RUN apt-get update -yqq &&\
    apt-get install -yqq --no-install-recommends \
    apt-transport-https

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | \
    tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -yqq &&\
    apt-get install -yqq --no-install-recommends \
    apt-utils \
    nodejs \
    yarn \
    vim

COPY . /usr/src/app

WORKDIR /usr/src/app
RUN bundle install

Webpacker comes up again in Advanced Gem Management and finally in Chapter 13, A Production-Like Playground.

The Rspec/testing chapter doesn’t use Node or webpacker, so you can tear the yarn and nodejs update stuff out of your Dockerfile and get rid of Webpacker in your Gemfile.

FROM ruby:2.6

LABEL maintainer="erwin@fastmail.org"
LABEL foo="bar"

RUN apt-get update -yqq &&\
    apt-get install -yqq --no-install-recommends \
    apt-utils \
    nodejs \
    vim

COPY Gemfile* /usr/src/app/
WORKDIR /usr/src/app
RUN bundle install

COPY . /usr/src/app/

CMD ["bin/rails", "server", "-b", "0.0.0.0"]

The automated testing with Capybara/Selenium didn’t work for me, but I’ve done some browser automation with Goland and Chrome so I didn’t want to spend a lot of time debugging it. If you want to do the RSpec/Capybara test examples in 2022, probably best to reference this post instead:

https://dev.to/amree/ruby-on-rails-and-docker-for-testing-4n8a

The authors tutorial approach of working though each step a piece at a time was extremely helpful for me, even being fairly familiar with Docker, but passively as a developer/user without having been excited enough to deep dive into Docker itself.