This gem provides a DSL for creating docker containers for running a family of Rails apps.

Code Climate Test Coverage Build Status

Prerequisites

  1. Install Docker
  2. Install ruby and the ruby_yacht gem.

Usage

Create a file called run.rb, which will be the main file for your docker scripts. This file can be called anything, but we will use that name here so we have a consistent reference.

Enter this in the file:

    require 'ruby_yacht'

    RubyYacht.configure do
    end

    RubyYacht::Runner.run

Your run.rb file will have two parts: A configuration block and the Runner command. The configuration block defines your projects and your apps. You can read the configuration documentation for more information on the configuration options.

The runner command invokes a RubyYacht script based on the command information.

You can also use the ruby_yacht command to generate a new project:

    ruby_yacht new test test-config

This will generate a run.rb file in test-config/run.rb, with sample config for a project called test. You can then fill it in with the details of your applications, as explained in the configuration documentation.

RubyYacht Scripts

RubyYacht provides several scripts to build and manage your application environment. You can invoke these scripts by calling ruby run.rb [command].

The examples below describe the results for the projects in the configuration sample file, which contains the following projects:

  • Project: apollo

    • apps: mars, saturn
    • database: localhost
    • domain: apollo.docker.local
  • Project: jupiter

    • apps: venus, saturn
    • database: db.test.com
    • domain: jupiter.docker.local

help

This command lists available commands, and provides information on the syntax and options for each command.

build

This command builds images for your projects, runs the containers, and updates your hosts file to add entries that point your app's domains toward the local docker address. This is a combination of build_images, run_containers, and update_hosts, so you can run those commands individually, and in different combinations, if you prefer.

build_images

This command builds all of the images for your project. For the example above, it will build the following images:

apollo-rails-app-dependencies An image with mars and saturn checked out, and all of their dependencies installed
apollo-database An image with mysql installed and a database set up with the schema and seeds from mars and saturn
apollo-mars An image with the mars app installed, and the dependencies for mars installed, set up to point to the apollo-database database.
apollo-saturn An image with the saturn app installed, and the dependencies for saturn installed, set up to point to the apollo-database database.
apollo-web An image with nginx installed, and set up to proxy the app containers for apollo-mars and apollo-saturn. Each app will get a subdomain of the project's main domain, with the subdomain named after the app.
jupiter-rails-app-dependencies An image with venus and saturn checked out, and all of their dependencies installed
jupiter-venus An image with the venus app installed, and the dependencies for mars installed, set up to point to the db.test.com database.
jupiter-saturn An image with the saturn app installed, and the dependencies for saturn installed, set up to point to the db.test.com database.
jupiter-web An image with nginx installed, and set up to proxy the app containers for jupiter-venus and jupiter-saturn.

run_containers

This command runs all of the containers for the images described above. Each container will have the same name as its image. Each container for the apollo project will be on a docker network called apollo, and will have network aliases corresponding to the container names. For instance, the apollo-web container will be able to access the apollo-mars container under the hostname apollo-mars. The apps will also be able to talk to each other using these network aliases. Containers for different projects will be in different networks, and will not be able to communicate.

It will not run a container for the app-dependencies images. Those images are intended to use as a baseline for the app and database images, to reduce their build times.

All of the containers will be run as daemons.

update_hosts

This command updates your hosts file to add entries for your containers. This is intended to help with development environments, where you won't have a real domain that resolves to your local machine.

For the examples above, it will add entries for these domains:

  • apollo.docker.local
  • mars.apollo.docker.local
  • saturn.apollo.docker.local
  • jupiter.docker.local
  • venus.jupiter.docker.local
  • saturn.jupiter.docker.local

This will allow you to access your local version of the apps in the web browser on your local machine without any additional DNS setup.

Before overwriting the hosts file, it will save a copy of the existing hosts file to /etc/hosts.{timestamp}.backup.

This will prompt you for your password, because it needs root privileges to update the hosts file. It will only use that privilege to run the commands:

    sudo cp /etc/hosts /ect/hosts.{timestamp}.backup
    sudo cp tmp/hosts /etc/hosts

The tmp/hosts file is populated prior to the privilege escalation with the updated hosts file contents.

implode

This will remove all of the containers and images for your projects, and also remove any dangling docker images. After this is done, you can run the build command to rebuild your environment from scratch.

This will not ruby the ruby and nginx images. Those are downloaded as part of the build process, and are provided by third parties as official docker images for those ruby and nginx.

services

This allows you to start, stop, or restart containers. If you run it with the start sub-command, it will also start docker-machine, if necessary. The most common use case for this is to run ruby run.rb services start after you reboot your machine, to get your docker environment up and running again.

shell

This opens a shell in an app container. By default, this opens a bash shell, but any additional commands you pass it will be forwarded to the container and run.

For instance, you can run ruby run.rb shell mars to open a bash shell in the mars app container, or ruby run.rb shell mars rails c to open a rails console, or ruby run.rb shell mars "tail -f log/development.log" to start reading all the content printed to the development log file.

If the command you want to run has any flags in it, like the -f above, you must enclose the command in quotes to prevent RubyYacht from trying to consume that as a flag of its own.

checkout

This checks out a new branch inside an app container, and restarts the app container. It will also immediately run any database migrations from the new branch.

If you run it for a branch that you already have checked out, it will pull down the latest changes from the repository.

Plugins and Customization

RubyYacht has a plugin API for customizing the behavior of your scripts. You can use plugins for defining new app types or database types, or for adding hooks for the built-in types. This plugin API is so powerful that all of the rails-specific and mysql-specific code in RubyYacht is provided through plugins.

Additional Information

If you're interested in contributing to the project, you can find more information in the contributing documentation. You can also reach out to me on Twitter @brownleej