Last Updated: September 09, 2019
·
3.842K
· 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 http://static.dockerfiles.io/boot2docker-v1.2.0-virtualbox-guest-additions-v4.3.14.iso > 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 \
   --automount
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 https://github.com/sstephenson/rbenv.git /usr/local/rbenv
RUN echo '# rbenv setup' > /etc/profile.d/rbenv.sh
RUN echo 'export RBENV_ROOT=/usr/local/rbenv' >> /etc/profile.d/rbenv.sh
RUN echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> /etc/profile.d/rbenv.sh
RUN echo 'eval "$(rbenv init -)"' >> /etc/profile.d/rbenv.sh
RUN chmod +x /etc/profile.d/rbenv.sh

# install ruby-build
RUN mkdir /usr/local/rbenv/plugins
RUN git clone https://github.com/sstephenson/ruby-build.git /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:

mysql:
  image: mysql
  environment:
    MYSQL_ROOT_PASSWORD: fizzbuzz
web:
  build: .
  command: bundle exec rails server
  volumes:
    # This seems to work as-is once you expose /Users to the boot2docker vm.
    - .:/my_awesome_social_media_app
  links:
    - mysql
  ports:
    - "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 'https://rubygems.org'
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:

...etc...
development: 
  <<: *default
  password: <%= ENV['<YOURAPPNAME>_MYSQL_1_ENV_MYSQL_ROOT_PASSWORD'] %>
  host: <%= ENV['<YOURAPPNAME>_MYSQL_1_PORT_3306_TCP_ADDR'] %>
  database: my_awesome_social_media_app_development
...etc...

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.

1 Response
Add your response

Thx for the writeup.

over 1 year ago ·