Docker::Compose
This is a Ruby OOP wrapper for the docker-compose container orchestration tool from Docker Inc.
In addition to wrapping the CLI, this gem provides an environment-variable mapping feature that allows you to export environment variables into your host that point to network services exposed by containers. This allows you to run an application on your host for quicker and easier development, but run all of its architectural dependencies -- database, cache, adjacent microservices -- in containers. The dependencies can even be running on another machine, e.g. a cloud instance or a container cluster, provided your development machine has TCP connectivity on every port exposed by a container.
Throughout this documentation we will refer to this gem as Docker::Compose
as opposed to the docker-compose
tool that this gem wraps.
Installation
Add this line to your application's Gemfile:
gem 'docker-compose'
And then execute:
$ bundle
Or install it yourself as:
$ gem install docker-compose
Usage
Invoking from Ruby code
require 'docker/compose'
# Create a new session in Dir.pwd using the file "docker-compose.yml".
# For fine-grained control over options, see Docker::Compose::Session#new
compose = Docker::Compose.new
compose.version
compose.up(detached:true)
Invoking from Rake
Open your Rakefile and add the Docker::Compose tasks.
require 'docker/compose/rake_tasks'
Docker::Compose::RakeTasks.new do |tasks|
# customize by calling setter methods of tasks;
# see the class documentation for details
end
Notice that rake -T
now has a few additional tasks for invoking gem
functionality. You can docker:compose:env
to print bash export statements
for host-to-container environment mapping; you can docker:compose:up
or
docker:compose:stop
to start and stop containers.
The docker-compose
command is a perfectly valid way to start
and stop containers, but the gem provides some env-substitution functionality
for your YML files that will be built into docker-compose 1.5 but is not
released yet. If your YML contains ${ENV}
references, i.e. in order to
point your containers at network services running on the host, then you must
invoke docker-compose through Rake in order to peform the substitution.
Mapping container IPs and ports
Assuming that your app accepts its configuration in the form of environment
variables, you can use the docker:compose:env
to export environment values
into your bash shell that point to services running inside containers. This
allows you to run the app on your host (for easier debugging and code editing)
but let it communicate with services running inside containers.
Docker::Compose uses a heuristic to figure out which IP your services are actually reachable at; the heuristic works regardless whether you are running "bare" docker daemon on localhost, communicating with a docker-machine instance, or even using a cloud-hosted docker machine!
As a trivial example, let's say that your docker-compose.yml
contains one
service, the database that your app needs in order to run.
db:
image: mysql:latest
environment:
MYSQL_DATABASE: myapp_development
MYSQL_ROOT_PASSWORD: opensesame
ports:
- "3306"
Your app needs two inputs, DATABASE_HOST
and DATABASE_PORT
. You can specify
this in the env section of the Rake task:
Docker::Compose::RakeTasks.new do |tasks|
tasks.env = {
'DATABASE_HOST' => 'db:[3306]'
'DATABASE_PORT' => '[db]:3306'
}
end
(If I had a DATABASE_URL
input, I could provide a URL such as
mysql://db/myapp_development
; Docker::Compose would parse the URL and replace
the hostname and port appropriately.)
Now, I can run my services, ask Docker::Compose to map the environment values
to the actual IP and port that db
has been published to, and run my app:
user@machine$ docker-compose up -d
# This prints bash code resembling the following:
# export DATABASE_HOST=127.0.0.1
# export DATABASE_PORT=34387
# We eval it, which makes the variables available to our shell and to all
# subprocesses.
user@machine$ eval "$(bundle exec rake docker:compose:env)"
user@machine$ bundle exec rackup
To learn more about mapping, read the class documentation for
Docker::Compose::Mapper
.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/xeger/docker-compose. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.