You read thoughtbot’s Rails on Docker article, moved your entire development environment into Docker containers via Docker Compose, then realized everytime you update a gem you have to run bundle
from scratch and it takes forever.
With Docker data containers and a clever hack in the docker-compose.yml
file you don’t have to wait around for bundler to build from scratch everytime you bump a gem.
Building on thoughtbot’s Dockerfile example, set the BUNDLE_PATH
environment variable to store the bundler cache outside of your project folder:
FROM ruby:2.2.0
RUN apt-get update -qq && apt-get install -y build-essential
# for postgres
RUN apt-get install -y libpq-dev
# for nokogiri
RUN apt-get install -y libxml2-dev libxslt1-dev
# for capybara-webkit
RUN apt-get install -y libqt4-webkit libqt4-dev xvfb
# for a JS runtime
RUN apt-get install -y nodejs
ENV APP_HOME /myapp
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
ADD Gemfile* $APP_HOME/
# --- Add this to your Dockerfile ---
ENV BUNDLE_GEMFILE=$APP_HOME/Gemfile \
BUNDLE_JOBS=2 \
BUNDLE_PATH=/bundle
RUN bundle install
ADD . $APP_HOME
Now add a bundle
host to the docker-compose.yml
file. This may be the fig.yml
file if you haven’t yet upgraded from Fig 1.0 to Docker Compose 1.1.
web:
build: .
command: bin/rails server --port 3000 --binding 0.0.0.0
ports:
- "3000:3000"
links:
- db
volumes:
- .:/myapp
# This tells the web container to mount the `bundle` images'
# /bundle volume to the `web` containers /bundle path.
volumes_from:
- bundle
# --- Add this to your fig.yml or docker-compose.yml file ---
bundle:
# 'image' will vary depending on your docker-compose
# project name. You may need to run `docker-compose build`
# before this works.
image: myapp_web
command: echo I'm a little data container, short and stout...
volumes:
- /bundle
When the web
container runs it mounts the bundle
container’s /bundle
folder. Between runs the bundle
container’s /bundle
directory is persisted so you don’t have to rebuild your entire bundle from scratch everytime you add or upgrade a gem from the web
container.
A few months back and took an oath to only run development environments inside Docker containers so that I’d Learn The Hard Way™ all of its pitfalls before rolling it out to the rest of the crew at Poll Everywhere. I’ve got a few more articles in the works that discuss the nuances of Docker in a development environment that I’ll tweet about @bradgessler. Stay tuned!