Last Updated: May 30, 2016
· fluxrad

Docker + Fig + Rails on OS X

This is a synthesis of several resources that I wound up putting together to get a Fig + Docker + rails environment up and running. I relied on Matthias Kadenbach's's awesome writeup to get host sharing working. Github user deepak's Dockerfile is a good starting point for a rbenv Docker setup. And Fig + Rails works mostly out of the box.

Martin's writeup is also good, but you shouldn't need to run any commands against the kernel as of boot2docker >= 1.2.0.

Here's what worked for me:

Install boot2docker

In order to make sure VirtualBox guest additions work, you need to grab a pretty recent release (see also)

Install the latest boot2docker from here

Download latest boot2docker ISO with VirtualBox geust additions:

You'll need this to share your local filesystem through to the container running no the boot2docker VM. Double check you're using the appropriate ISO for your version of boot2docker

cd ~/.boot2docker
mv boot2docker.iso boot2docker.iso.orig
curl > boot2docker.iso
boot2docker init

Enable host filesystem sharing

This shares out your /Users partition to the boot2docker VM:

VBoxManage sharedfolder add boot2docker-vm \
   --name home \
   --hostpath /Users \
boot2docker up

Create your Dockerfile

I prefer to use rbenv as opposed to RVM or chruby. Below seems to be a standard Docker + rbenv pattern, though I'm sure it wouldn't be too difficult to adapt this to running another ruby version manager. Alternatively, there are some ruby containers pre-built on the Docker registry but I prefer to use a stock Ubuntu container. Link to gist

FROM ubuntu:14.04

RUN apt-get update -qq && apt-get install -y build-essential nodejs npm git curl mysql-client libmysqlclient-dev
RUN mkdir -p /my_awesome_social_media_app

# Install rbenv
RUN git clone /usr/local/rbenv
RUN echo '# rbenv setup' > /etc/profile.d/
RUN echo 'export RBENV_ROOT=/usr/local/rbenv' >> /etc/profile.d/
RUN echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> /etc/profile.d/
RUN echo 'eval "$(rbenv init -)"' >> /etc/profile.d/
RUN chmod +x /etc/profile.d/

# install ruby-build
RUN mkdir /usr/local/rbenv/plugins
RUN git clone /usr/local/rbenv/plugins/ruby-build

ENV RBENV_ROOT /usr/local/rbenv
ENV PATH $RBENV_ROOT/bin:$RBENV_ROOT/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

RUN rbenv install 2.1.2
RUN bash -l -c 'rbenv global 2.1.2; gem install bundler; rbenv rehash'

WORKDIR /my_awesome_social_media_app

# Cache Gemfile steps so we don't run bundle install every time other files change.
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install

ADD . /my_awesome_social_media_app

CMD bundle exec rails server

Install/Configure Fig

Installing and configuring Fig should be as simple as brew install fig

Then create your fig.yml. Here's a basic webapp + MySQL configuration, feel free to substitute your favorite database:

  image: mysql
  build: .
  command: bundle exec rails server
    # This seems to work as-is once you expose /Users to the boot2docker vm.
    - .:/my_awesome_social_media_app
    - mysql
    - "3000:3000"

Create the Rails scaffold and generate a new app (Note: only necessary for new projects)

Setup Gemfile/Gemfile.lock

You need to create a Gemfile and a Gemfile.lock, so Fig can run can do a bundle install/exec. Note that you'll only need to do this if you're creating a new rails app. Existing rails apps can skip this bit.

First, create a basic Gemfile:

source ''
gem 'rails', '~> 4.1.0'

And create an empty Gemfile.lock so the container can mount it:

touch Gemfile.lock

Use Fig to create the container.

I think you need to run fig build twice here in order to get the Gemfile/Gemfile.lock properly instantiated. There's probably a cleaner way to do this:

fig build
fig run web bundle exec rails new . --force --database=mysql --skip-bundle
fig build 

Note: I was also having some issues with bundler/rails complaining about versioning of sass-rails. I was able to fix this by doing a fig run web bundle update to get everything updated.

Configure Rails to talk to the MySQL container

In the development environment, Rails wants to talk to a database running on localhost by default. However, when Fig runs the MySQL container it will inject variables you can use for service discovery.

Edit config/database.yml to connect to the linked MySQL container, rather than localhost:

  <<: *default
  host: <%= ENV['<YOURAPPNAME>_MYSQL_1_PORT_3306_TCP_ADDR'] %>
  database: my_awesome_social_media_app_development

Create/migrate your database

fig run web rake db:create db:migrate

and, lastly…

Start everything up

fig up

This should get you a shiny new rails app on your boot2docker instance, listening on port 3000. If you'd like to map it back to localhost, just run boot2docker ssh -L3000:localhost:3000 in a separate window.

Once you're ready to build/ship your container, all the standard docker commands that come with boot2docker should work as well.

Happy hacking.

Say Thanks

1 Response
Add your response

Radar normal

Thx for the writeup.

over 1 year ago ·