Developing in Rails via Docker

One of the neat things about Docker is that you don’t need to install any dev tools on your local machine.

Sometimes though you’ll need to run commands in the dev environment without your app being built (say if there is an error building the app, or you want to run a command like rails new). The way I do this is to have a separate Dockerfile and docker-compose config that configures the dev environment, rather than the app.

Here’s how I set up my local ruby environment, mounting my app directory so that I can run rails commands (like bundle update and retain the output):

Dockerfile-ruby

FROM ruby:2.3.5
RUN mkdir /app
WORKDIR /app
ADD . /app

docker-compose-ruby.yaml

services:
  ruby:
    build: 
      context: .
      dockerfile: Dockerfile-ruby
    command: sleep infinity
    volumes:
      - type: bind
        source: .
        target: /app

To run this environment, in one window run:

docker-compose -f docker-compose-ruby.yaml build
docker-compose -f docker-compose-ruby.yaml up

Then you can attach to it in another window like so:

# docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED          STATUS          PORTS
   NAMES
6c1e6650a1d9   myapp_ruby                "sleep infinity"         12 seconds ago   Up 9 seconds
   myapp_ruby_1
# docker exec -it 6c1e6650a1d9 bash
[email protected]:/app# 

You can then run commands like bundle update. Since we’re using Docker compose, and mounting the app’s directory as a volume, any output (like the updated Gemfile.lock) will be written to your app directory so you can commit to version control.