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.
Written by Aaron
Related protips
1 Response
Thx for the writeup.