This gem provides a DSL for creating docker containers for running a family of Rails apps.
Prerequisites
- Install Docker
- 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