Docker dependencies with Fig

continue to last blog http://allenwei.cn/setup-rails-development-environment-with-docker/

Beside postgresql, we may need redis and memcache, it will become complex to start development environment

We’ll talk about how to simplfy setup local environment with fig

Install Fig

To install fig, you need run follow command

curl -L https://github.com/docker/fig/releases/download/1.0.1/fig-`uname -s`-`uname -m` > /usr/local/bin/fig; chmod +x /usr/local/bin/fig

Config Fig

You need create fig.yml in root path of your Rails project

rails:
build: .
ports:
- "3000:3000"
volumes:
- ./:/usr/src/app
links:
- "postgresql:postgresql"
postgresql:
image: postgres
environment:
POSTGRES_PASSWORD: "mypassword"

You can see fig support all configuration provided by docker

By simply add links you can specify the dependended container of your rails project

Build your container

before you start the rails container, we need build the image again, because fig will give the container a different name.

fig build

tips: if you need more than one image want to build, fig will build all of them, very handy.

Start Rails container

because we’ve configured postgresql dependency in fig.yml, we can start all containers together

fig up

Now you can see postgresql started along with Rails

You may notice your database is missing, because we are using different postgresql container now.

to create your database container is very simple

fig run rails db:create

then migrations

fig run rails db:migrate

to restart rails

fig restart rails

to run some command in container

fig run rails bash

what’s more run your test

fig run rails rspec

Add more service

rails:
build: .
ports:
- "3000:3000"
volumes:
- ./:/usr/src/app
links:
- "postgresql:postgresql"
- "redis:redis"
- "memcache:memcache"
postgresql:
image: postgres
environment:
POSTGRES_PASSWORD: "mypassword"
redis:
image: redis
memcache:
image: sylvainlasnier/memcached

you can get redis/memecache configuration by show environment variables in your rails container

fig run rails env

you may noticed fig started redis and memcache

in next blog I’ll talked about setup production environment locally with Vagrant and Docker

Setup Rails development environment with Docker

If you don’t have docker installed you can check out my last blog http://allenwei.cn/setup-docker-on-your-mac/

Build your first rails docker image

Assume you already have a rails git repo

First We need create a Dockerfile in your rails folder

This time we’ll use base image for latest ruby version, you can see other version here https://registry.hub.docker.com/u/library/ruby/

RVM? no you don’t need it, because each container is isolated, so you don’t need version management tool any more.

Here is the Dockerfile

FROM ruby:onbuild

CMD rails s

That’s it, really simple right?

Before you start the container, we need build it first

docker build -t my-rails-app .

How to setup postgresql

You still need database like mysql and postgresql, you don’t need install it on your mac, just use Docker container

You can find postgresql docker image here https://registry.hub.docker.com/_/postgres/

To start the postgresql container

docker run --name my-postgresql -e POSTGRES_PASSWORD=mypassword -d postgres

Next you need link to postgresql to your rails project
How the rails app connect to postgresql?

When you link postgresql container to your rails app container, all configuration for postgresql as ENV variable

You can check those configuration by run follow command

docker run --name my-rails-app --link my-postgresql:postgresql --rm my-rails-app env

you can see environment variables like:

POSTGRESQL_PORT=tcp://172.17.0.43:5432
POSTGRESQL_PORT_5432_TCP=tcp://172.17.0.43:5432
POSTGRESQL_PORT_5432_TCP_ADDR=172.17.0.43
POSTGRESQL_PORT_5432_TCP_PORT=5432
POSTGRESQL_PORT_5432_TCP_PROTO=tcp
POSTGRESQL_NAME=/nostalgic_newton/postgresql
POSTGRESQL_ENV_POSTGRES_PASSWORD=mypassword
POSTGRESQL_ENV_LANG=en_US.utf8
POSTGRESQL_ENV_PG_MAJOR=9.3
POSTGRESQL_ENV_PG_VERSION=9.3.5-1.pgdg70+1
POSTGRESQL_ENV_PGDATA=/var/lib/postgresql/data

When you know the postgresql environment, you can edit your rails database config in config/database.yml

default: &default
  adapter: postgresql
  pool: 5
  username: postgres
  password: <%= ENV['POSTGRESQL_ENV_POSTGRES_PASSWORD'] %>
  host: <%= ENV['POSTGRESQL_PORT_5432_TCP_ADDR'] %>
  port: <%= ENV['POSTGRESQL_PORT_5432_TCP_PORT'] %>

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test

production:
  <<: *default
  database: myapp_production

if you didn’t add pg gem into your Gemfile, you need added gem 'pg' into you your Gemfile and rebuild your docker image

let’s try out our pg configuration

    docker run --link my-postgresql:postgresql -it  my-rails-app rake db:create

OK, we’ve setup our environment, let’s start to change our code.

I still ssh to my docker container? no, you edit your code on your mac directly, let’s see how we do it.

We can mount your local folder on docker container, let’s mount current rails folder to docker container

docker run --link my-postgresql:postgresql -it -v $(pwd):/usr/src/app my-rails-app bundle install

you can see when we run bundle install again, it is very fast, because the installed gem is already in the docker image

to access your rails server, you still need one more step, port docker port to you local machine

docker run --link my-postgresql:postgresql -it -v $(pwd):/usr/src/app -p 3000:3000 my-rails-app rails s

Because on Mac, we can only access docker container through boot2docker, we can run boot2docker ip to get the ip address

there is a convienent way to do it

open http://$(boot2docker ip):3000

you can give a name to your container and run it as daemon

docker run --name=my-rails-app --link my-postgresql:postgresql -it -v $(pwd):/usr/src/app -p 3000:3000 -d my-rails-app rails s

So when you need restart your server, just restart the container by it’s name

docker restart my-rails-app

How to run test

There is two ways:

1) start new container to test your test. It possible since start a new container is super faster

docker run --link my-postgresql:postgresql -it -v $(pwd):/usr/src/app my-rails-app rspec

2) You can log in to your started docker container

docker exec -it my-rails-app bash

in next blog http://allenwei.cn/docker-dependencies-with-fig/, I’ll introduce a way to simplfy the flow

Setup docker on your mac

There is no native docker support yet, you need virtualbox and boot2docker

Install virtualbox

You can find virtualbox binaries file here: https://www.virtualbox.org/wiki/Downloads

Install boot2docker

You can find boot2docker binaries file here: https://github.com/boot2docker/osx-installer/releases

To start boot2docker you need

init boot2docker environment

$ boot2docker init
```bash

Start boot2docker virtualbox

```bash
$ boot2docker up

Test

You can test docker by run a smallest docker image busybox

On your Mac termnial

You can run

docker run busybox echo "hello word"

SSH into your boot2docker vm

boot2docker ssh

get your boot2docker vm ip address

boot2docker ip

Upgrade boot2docker

boot2docker stop
boot2docker delete
boot2docker download
boot2docker init
boot2docker up

Trouble Shooting

2014/11/30 10:28:50 Get http:///var/run/docker.sock/v1.15/containers/json: dial unix /var/run/docker.sock: no such file or directory

Possible reasons:

  • You didn’t start boot2docker, you can try boot2docker up
  • boot2docker environment didn’t set, you can try $(boot2docker shellinit)
  • To be convienent you can put $(boot2docker shellinit) in your bash.rc or zsh.rc