Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Latest commit 047f062 Jul 12, 2016
Type Name Latest commit message Commit time
Failed to load latest commit information.
app Add tmp file creator Mar 17, 2015
docker Change to install gems to system location Mar 18, 2015
lib Fix wrong JSON usage Mar 27, 2015
log Initial commit Mar 5, 2015
public Initial commit Mar 5, 2015
test Add post controller with Resque to do `sleep` Mar 5, 2015
.dockerignore Fix typo Aug 12, 2015
.gitignore Add rails-conf and configuration for tmp file Mar 17, 2015
Capfile Add capistrano tasks to deploy Mar 13, 2015
Dockerfile Change to install gems to system location Mar 18, 2015
Gemfile Add rails-conf and configuration for tmp file Mar 17, 2015
Gemfile.lock Add rails-conf and configuration for tmp file Mar 17, 2015
config.rb Add Vagrantfile and files for provisioning Mar 24, 2015 Initial commit Mar 5, 2015
docker-compose-development.yml Add comment Mar 24, 2015
docker-compose.yml Fix compose config to up only shared containers Mar 25, 2015
railways.cache Add post controller with Resque to do `sleep` Mar 5, 2015




This repository is a example project by Rails with Resque worker. The structure of the project is following; quite simple:

                 ███████████████████         ███████████████████  
                 ███████████████████         ███████████████████  
                 ███████Redis███████         ██████Postgre██████  
                 ███████████████████         ███████████████████  
                 ███████████████████         ███████████████████  
                       ┼  ▲                           ▲
                       │  │                           │
     Load    ┌─────────┘  │                           │
 information │            │                ┌─────────────────────┐
   for job   │            │                │        Rails        │
            ╱│╲           │                │   Web application   │
    ┌─────────────────┐   │                │                     │
    │                 │   │                │   ┌──────────────┐  │
    │  Rescue worker  │   │ Register jobs  │   │              │  │
    │                 │   └────────────────┼───│ Resque Task  │  │
    │                 │                    │   │              │  │
    └─────────────────┘                    │   └──────────────┘  │
  • Rails
  • Resque
    • It can be used by Rails and also worker is run independently
    • It is expected to be run as several workers
  • Postgre
    • DB for models of Rails
  • Redis
    • For Resque
  • Data container
    • data-only-container for persistent data like temporary file and data for DB
    • This is mounted to containers

How to run containers


These are required to run it as Docker containers.

  • docker
  • docker-compose

Run containers

All you have to do is bellow:

docker-compose up

For development environment

For development environment, you can use docker-compose-development.yml on your local machine.

It is basically same as docker-compose.yml for staging or production environment but it shares your local Rails project with web container with using same image as staging/production. When you update code, you can see changes for it as you run rails server on your local too.

This is docker-compose-development.yml:

  build: .
    - postgres
    - redis
    - "80:80"
  # Following is development configuration
  command: /bin/bash -c "rake db:migrate && rails server -b -p 80"
    RAILS_ENV: development
    - data
# ...
# omitted some lines...
# ...
  image: busybox
    - /tmp
    # For postgres
    - /var/lib/postgresql/data
    - .:/usr/src/app


Currently, this example does not support hot-deployment. This example has deployment task by capistrano but it needs to restart all containers when you want to update application.

This is example to deploy these containers to a Ubuntu 14.04 droplet on DigitalOcean.

Set up for DigitalOcean droplet

Install Docker and Docker Compose

Install the latest Docker by following documentation: Ubuntu - Docker Documentation

apt-key adv --keyserver hkp:// --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
sudo sh -c "echo deb docker main \
sudo apt-get update && \
    apt-get install -y lxc-docker

Install Docker Compose

curl -L`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod a+x /usr/local/bin/docker-compose

Set up deploy user

It needs that deploy user to deploy source code to this droplet.

sudo adduser deploy
sudo passwd -l deploy # Do this to make password string which is not able to input

Add deploy user to docker group to be able to execute docker command.

sudo gpasswd -a deploy docker

And create key for deploy user.

su deploy
ssh-keygen -t rsa -C "deploy"

Add deploy keys to repo on Github

Create deploy key of your repository with key of deploy user: Managing deploy keys | GitHub API

After set up deploy key of your repository, you can clone your repository via git command like this:

git clone


To deploy the application to droplet, it has capistrano file. Execute deployment manually by executing this command: bundle exec cap staging docker:deploy

docker.rake has 3 tasks.

  1. update
  • Update git repository of Rails project
  1. build
  • Build Docker images
  1. deploy
  • Run Docker containers
  • This task executes 3 commands of docker-compose: stop, rm and up. You don't have to care of containers running as it stops all of running containers.

Building images and running containers works by execute docker-compose. See docker-compose.yml

* If you met exit status 4 while building Docker image

You may meet this error while you build your Docker image:

Your compiler failed with the exit status 4. This probably means that it ran out of memory. To solve this problem, try increasing your swap space:

You can upgrade space to add swap space following this procedure: How To Add Swap on Ubuntu 14.04 | DigitalOcean

I confirmed that swap 4GB works for this project.

Deploy with CircleCI


This project has a sample circle.yml to deploy it to DO's droplet.

Manage persistent data

This project uses data-only-container for portability of persistent data, for example, temporary file which is needed by the application, DB data and etc. It follows the instruction in Documentation of Docker: Managing data in containers - Docker Documentation and There's nothing new to the documentation.

This project has Resque job, FileCreator. This is just to create file when the new post was created. And file is saved in /tmp in production; this is sample so it is meaningless!. See config/settings/production.yml and app/jobs/file_creator.rb.

Following is the way to backup files which was saved in /tmp and restore them.

Backup and restore data

Static files in /tmp directory

In this case, it just needs to create backup file from container directory and extract it to container.

# Create backup as a tar file
docker run --volumes-from railsdockerexample_data_1 -v $(pwd)/backup:/backup busybox tar cvf /backup/backup.tar /tmp
# Restore it
docker run --volumes-from railsdockerexample_data_1 -v $(pwd)/backup:/backup busybox tar xvf /backup/backup.tar

DB data

If you need to backup and restore postgres DB data, you can do it by following:

# Create backup as a tar file
docker run --volumes-from railsdockerexample_data_1 -v $(pwd)/backup:/backup busybox tar cvf /backup/backup.tar /var/lib/postgresql/data
# Restore it
docker run --volumes-from railsdockerexample_data_1 -v $(pwd)/backup:/backup busybox tar xvf /backup/backup.tar
# Restart containers; As restarted container may have new ip address and Rails knows it only to read ENV --- it was set --link option and it will not update automatically
docker-compose restart

TIPS: Zero time deployment with CoreOS and vulcand

We can do zero time deployment by using CoreOS and mailgun/vulcand. This project has Vagrantfile to up the environment for it.

Ref: Vulcand を使って Docker コンテナをブルーグリーンデプロイする - Qiita

Quite simple to do that. vulcand has the very simple system to handle some endpoints; Frontend, Backend and Servers. In this case, the container is Server.

We can build and start container with versioned source code with commit-id then switch endpoint like this:

# Create new Backend linked to new version
etcdctl set /vulcand/backends/8c5a86/backend '{"Type": "http"}'

# Create new Server linked to the Backend
etcdctl set /vulcand/backends/8c5a86/servers/srv1 '{"URL": "http://localhost:5000"}'

# Update Frontend with new Backend Id
etcdctl set /vulcand/frontends/f1/frontend '{"Type": "http", "BackendId": "8c5a86", "Route": "PathRegexp(`/.*`)"}'
│                             FrontEnd                              │
│              {"Type": "http", "BackendId": "a43bd2",              │
│                   "Route": "PathRegexp(`/.*`)"}                   │
│                                                                   │
Frontend forwards request to      │  * Switch the target "Server" by set
the container which was linked    │  backend Id of commit id via etcd
to backend                        │  API after the new container was
                ┌─────────────────┘  built and ready.
┌───────────────────────────────┐   ┌───────────────────────────────┐
│            Backend            │   │            Backend            │
│   /vulcand/backends/a43bd2    │   │   /vulcand/backends/8c5a86    │
│       {"Type": "http"}        │   │       {"Type": "http"}        │
│                               │   │                               │
└───────────────────────────────┘   └───────────────────────────────┘
                ┼                                   ┼
                │                                   │
                ┼                                   ┼
┌───────────────────────────────┐   ┌───────────────────────────────┐
│            Server             │   │            Server             │
│/vulcand/backends/a43bd2/server│   │/vulcand/backends/8c5a86/server│
│            s/srv1             │   │            s/srv1             │
│{"URL": ""} │   │{"URL": ""} │
└───────────────────────────────┘   └───────────────────────────────┘
                ┼                                   ┼
                │                                   │
                ┼                                   ┼
┌───────────────────────────────┐   ┌───────────────────────────────┐
│       Docker container        │   │       Docker container        │
│       (built as a43bd2)       │   │       (built as 8c5a86)       │
│          │   │          │
│                               │   │                               │
└───────────────────────────────┘   └───────────────────────────────┘

NOTICE: This wouldn't fit production environment as it builds Docker image inside the only host. It may affects performance while users send request to the only host. For production, it needs to change to use Docker registry and run containers by pulling image from there.

Setup environment as Vagrant

Install vagrant dns plugin for local dns. Then run vagrant up to up your local environment.

This plugin supports MacOS only

vagrant plugin install vagrant-dns
vagrant dns --install
vagrant ssh-config >> ~/.ssh/config
vagrant up

See how it works to deploy it to Vagrant

All needed tasks are already included in rails-docker-example/docker.rake at master · mookjp/rails-docker-example. You can deploy new containers with zero time deployment with Vagrant:

vagrant up
bundle exec cap local docker:deploy # `local` environment is for vagrant
You can’t perform that action at this time.