Use Fig and Docker to run a Rails app... without installing Rails
We're going to use Fig to set up and run a Rails/PostgreSQL app without installing Rails or PostgreSQL—or Ruby, for that matter.
To follow along at home, you'll need Fig and Docker (if you're on a Mac, docker-osx has you covered). Clone the (very small) starting repo, or manually create a directory and copy/paste the 3 code samples below.
$ git clone https://github.com/orchardup/fig-rails-example.git myapp $ cd myapp
There are 3 files which work together to get us off the ground. First,
Dockerfile describes how to get our app's dependencies ready:
FROM binaryphile/ruby:2.0.0-p247 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev RUN mkdir /myapp WORKDIR /myapp ADD Gemfile /myapp/Gemfile RUN bundle install ADD . /myapp
Next, we have a bootstrap Gemfile which just loads Rails. It'll be overwritten in a moment by
source 'https://rubygems.org' gem 'rails', '4.0.2'
fig.yml is where the magic happens. It describes what services our app comprises (a database and a web app), how to get each one's Docker image (the database just runs on a pre-made PostgreSQL image, and the web app is built from the current directory), and the configuration we need to link them together and expose the web app's port.
db: image: orchardup/postgresql ports: - 5432 web: build: . command: bundle exec rackup -p 3000 volumes: - .:/myapp ports: - 3000:3000 links: - db
With those files in place, we can now generate the Rails skeleton app using
$ fig run web rails new . --force --database=postgresql --skip-bundle
First, Fig will build the image for the
web service using the
Dockerfile. Then it'll run
rails new inside a new container, using that image. Once it's done, you should have a fresh app generated:
$ ls Dockerfile app fig.yml tmp Gemfile bin lib vendor Gemfile.lock config log README.rdoc config.ru public Rakefile db test
Uncomment the line in your new
Gemfile which loads
gem 'therubyracer', platforms: :ruby
Now that we've got a new
Gemfile, we need to build the image again. (This, and changes to the Dockerfile itself, should be the only times you'll need to rebuild).
$ fig build
Rails should now be bootable. Let's do that.
$ fig up
If all's well, you should see some PostgreSQL output, and then—after a few seconds—the familiar refrain:
myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick 1.3.1 myapp_web_1 | [2014-01-17 17:16:29] INFO ruby 2.0.0 (2013-11-22) [x86_64-linux-gnu] myapp_web_1 | [2014-01-17 17:16:29] INFO WEBrick::HTTPServer#start: pid=1 port=3000
The app is now running, but we're not quite there yet. By default, Rails expects a database to be running on
localhost - we need to point it at the
db container instead. We also need to change the username and password to align with the defaults set by
fig up (Ctrl-C) and open up your newly-generated
database.yml. Replace its contents with the following:
development: &default adapter: postgresql encoding: unicode database: myapp_development pool: 5 username: docker password: docker host: <%= ENV.fetch('MYAPP_DB_1_PORT_5432_TCP_ADDR', 'localhost') %> port: <%= ENV.fetch('MYAPP_DB_1_PORT_5432_TCP_PORT', '5432') %> test: <<: *default database: myapp_test
fig up again, and Rails will reload the database configuration, enabling it to complain that the database doesn't exist yet. We can fix that, though.
In another terminal, run:
$ fig run web rake db:create