docker-compose 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/README.md +43 -31
- data/lib/docker/compose/mapper.rb +4 -11
- data/lib/docker/compose/rake_tasks.rb +48 -63
- data/lib/docker/compose/shell_printer.rb +21 -0
- data/lib/docker/compose/shell_printer/fish.rb +16 -0
- data/lib/docker/compose/shell_printer/posix.rb +32 -0
- data/lib/docker/compose/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04a52fb98e79311b5e3c771d24d41d434ab08e53
|
4
|
+
data.tar.gz: d1a04e25f5164edff5e2651ceed331fd58a20eb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52a9df711b6120701e3359fb30c3b22bc3c87abaa7823724c39e0efb462bc288b091efbce6eb77561b42f0ab112b9ea5568ac856de18ac7511d5a08292d60c30
|
7
|
+
data.tar.gz: ecd93e2c5c33b10acde0b8bd7c15c025676a53ff43f5b5df020e07f103961ccd5833e2096e965bd0766be2f768d0abdcb55b0b0ccab27572411f8f6fa07ec7e4
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
0.6
|
2
|
+
---
|
3
|
+
|
4
|
+
#### Interface-breaking changes
|
5
|
+
|
6
|
+
- Replaced `docker:compose:server` Rake task with more general `docker:compose:host`
|
7
|
+
- Replaced `server_env` option with `host_env`
|
8
|
+
- Replaced `extra_server_env` option with `extra_host_env`
|
9
|
+
- Stopped mapping values in `extra_host_env`; they are now exported verbatim
|
10
|
+
|
11
|
+
#### New features
|
12
|
+
|
13
|
+
Produce `docker:compose:env` output that is compatible with user's login shell.
|
14
|
+
|
15
|
+
0.5
|
16
|
+
---
|
17
|
+
|
18
|
+
Initial public release of prototype. Features work well, but there is no test
|
19
|
+
coverage.
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ In addition to wrapping the CLI, this gem provides an environment-variable mappi
|
|
7
7
|
feature that allows you to export environment variables into your _host_ that point
|
8
8
|
to network services exposed by containers. This allows you to run an application on
|
9
9
|
your host for quicker and easier development, but run all of its architectural
|
10
|
-
dependencies -- database, cache, adjacent
|
10
|
+
dependencies -- database, cache, adjacent services -- in containers. The
|
11
11
|
dependencies can even be running on another machine, e.g. a cloud instance or a
|
12
12
|
container cluster, provided your development machine has TCP connectivity on every
|
13
13
|
port exposed by a container.
|
@@ -62,29 +62,26 @@ end
|
|
62
62
|
```
|
63
63
|
|
64
64
|
Notice that `rake -T` now has a few additional tasks for invoking gem
|
65
|
-
functionality. You can `docker:compose:env`
|
66
|
-
|
67
|
-
`docker:compose:stop` to start and stop containers.
|
65
|
+
functionality. You can `docker:compose:env` print shell exports for
|
66
|
+
host-to-container environment mapping, or you can `docker:compose:host[foo]`.
|
68
67
|
|
69
|
-
|
70
|
-
and stop containers, but the gem provides some env-substitution functionality
|
71
|
-
for your YML files that will be built into docker-compose 1.5 but is not
|
72
|
-
released yet. If your YML contains `${ENV}` references, i.e. in order to
|
73
|
-
point your containers at network services running on the host, then you must
|
74
|
-
invoke docker-compose through Rake in order to peform the substitution.
|
68
|
+
### Hosting a Command
|
75
69
|
|
76
|
-
|
70
|
+
To run a process on your host and allow it to talk to containers, use
|
71
|
+
the `docker:compose:host` task. For example, I could enter a shell
|
72
|
+
with `rake docker:compose:host[bash]`.
|
73
|
+
|
74
|
+
Before "hosting" your command, the Rake task export ssome environment
|
75
|
+
variables that your command can use to discover services running in
|
76
|
+
containers. Your Rakefile specifies which variables your app needs
|
77
|
+
(the `host_env` option) and which container information each variable should
|
78
|
+
map to.
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
allows you to run the app on your host (for easier debugging and code editing)
|
82
|
-
but let it communicate with services running inside containers.
|
80
|
+
By hosting commands, you benefit from easier debugging and code editing of
|
81
|
+
the app you're working on, but still get to rely on containers to provide
|
82
|
+
the companion services your app requires to run.
|
83
83
|
|
84
|
-
|
85
|
-
are actually reachable at; the heuristic works regardless whether you are
|
86
|
-
running "bare" docker daemon on localhost, communicating with a docker-machine
|
87
|
-
instance, or even using a cloud-hosted docker machine!
|
84
|
+
### Mapping container IPs and ports
|
88
85
|
|
89
86
|
As a trivial example, let's say that your `docker-compose.yml` contains one
|
90
87
|
service, the database that your app needs in order to run.
|
@@ -101,30 +98,27 @@ db:
|
|
101
98
|
```
|
102
99
|
|
103
100
|
Your app needs two inputs, `DATABASE_HOST` and `DATABASE_PORT`. You can specify
|
104
|
-
this
|
101
|
+
this with the host_env option of the Rake task:
|
105
102
|
|
106
103
|
```ruby
|
107
104
|
Docker::Compose::RakeTasks.new do |tasks|
|
108
|
-
tasks.
|
109
|
-
'DATABASE_HOST' => 'db:[3306]'
|
110
|
-
'DATABASE_PORT' => '[db]:3306'
|
105
|
+
tasks.host_env = {
|
106
|
+
'DATABASE_HOST' => 'db:[3306]',
|
107
|
+
'DATABASE_PORT' => '[db]:3306',
|
111
108
|
}
|
112
109
|
end
|
113
110
|
```
|
114
111
|
|
115
|
-
(If I had a `DATABASE_URL` input, I could provide a URL such as
|
116
|
-
`mysql://db/myapp_development`; Docker::Compose would parse the URL and replace
|
117
|
-
the hostname and port appropriately.)
|
118
|
-
|
119
112
|
Now, I can run my services, ask Docker::Compose to map the environment values
|
120
113
|
to the actual IP and port that `db` has been published to, and run my app:
|
121
114
|
|
122
115
|
```bash
|
116
|
+
# First, bring up the containers we will be interested in
|
123
117
|
user@machine$ docker-compose up -d
|
124
118
|
|
125
|
-
#
|
126
|
-
# export DATABASE_HOST=127.0.0.1
|
127
|
-
# export DATABASE_PORT=34387
|
119
|
+
# The rake task prints bash code resembling the following:
|
120
|
+
# export DATABASE_HOST='127.0.0.1'
|
121
|
+
# export DATABASE_PORT='34387'
|
128
122
|
# We eval it, which makes the variables available to our shell and to all
|
129
123
|
# subprocesses.
|
130
124
|
user@machine$ eval "$(bundle exec rake docker:compose:env)"
|
@@ -132,6 +126,24 @@ user@machine$ eval "$(bundle exec rake docker:compose:env)"
|
|
132
126
|
user@machine$ bundle exec rackup
|
133
127
|
```
|
134
128
|
|
129
|
+
The `host_env` option also handles substitution of URLs, and arrays of values
|
130
|
+
(which are serialized back to the environment as JSON)
|
131
|
+
For example:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
tasks.host_env = {
|
135
|
+
'DATABASE_URL' => 'mysql://db:3306/myapp_development',
|
136
|
+
'MIXED_FRUIT' => ['db:[3306]', '[db]:3306']
|
137
|
+
}
|
138
|
+
```
|
139
|
+
|
140
|
+
This would result in the following exports:
|
141
|
+
|
142
|
+
```bash
|
143
|
+
export DATABASE_URL='mysql://127.0.0.1:34387/myapp_development'
|
144
|
+
export MIXED_FRUIT='["127.0.0.1", "34387"]'
|
145
|
+
```
|
146
|
+
|
135
147
|
To learn more about mapping, read the class documentation for
|
136
148
|
`Docker::Compose::Mapper`.
|
137
149
|
|
@@ -15,11 +15,10 @@ module Docker::Compose
|
|
15
15
|
# Instantiate a mapper; map some environment variables; yield to caller for
|
16
16
|
# additional processing.
|
17
17
|
#
|
18
|
-
# @param [Boolean] strict
|
19
18
|
# @param [Session] session
|
20
19
|
# @param [NetInfo] net_info
|
21
20
|
# @yield yields with each substituted (key, value) pair
|
22
|
-
def self.map(env,
|
21
|
+
def self.map(env, session:Session.new, net_info:NetInfo.new)
|
23
22
|
# TODO: encapsulate this trickiness better ... inside NetInfo perhaps?
|
24
23
|
docker_host = ENV['DOCKER_HOST']
|
25
24
|
if docker_host.nil? || docker_host =~ /^(\/|unix|file)/
|
@@ -32,7 +31,7 @@ module Docker::Compose
|
|
32
31
|
override_host = net_info.docker_routable_ip
|
33
32
|
end
|
34
33
|
|
35
|
-
mapper = self.new(session, override_host
|
34
|
+
mapper = self.new(session, override_host)
|
36
35
|
env.each_pair do |k, v|
|
37
36
|
begin
|
38
37
|
v = mapper.map(v)
|
@@ -47,13 +46,9 @@ module Docker::Compose
|
|
47
46
|
# @param [Docker::Compose::Session] session
|
48
47
|
# @param [String] override_host forcible address or DNS hostname to use;
|
49
48
|
# leave nil to trust docker-compose output.
|
50
|
-
|
51
|
-
# syntax is passed to #map; if false, simply return unrecognized
|
52
|
-
# values without substituting anything
|
53
|
-
def initialize(session, override_host=nil, strict:true)
|
49
|
+
def initialize(session, override_host=nil)
|
54
50
|
@session = session
|
55
51
|
@override_host = override_host
|
56
|
-
@strict = strict
|
57
52
|
end
|
58
53
|
|
59
54
|
# Substitute service hostnames and ports that appear in a URL or a
|
@@ -133,10 +128,8 @@ module Docker::Compose
|
|
133
128
|
host, port = host_and_port(pair.first, pair.last)
|
134
129
|
return "#{host}:#{port}"
|
135
130
|
end
|
136
|
-
elsif @strict
|
137
|
-
raise BadSubstitution, "Can't understand '#{value}'"
|
138
131
|
else
|
139
|
-
|
132
|
+
raise BadSubstitution, "Can't understand '#{value}'"
|
140
133
|
end
|
141
134
|
end
|
142
135
|
end
|
@@ -5,6 +5,9 @@ require 'shellwords'
|
|
5
5
|
# In case this file is required directly
|
6
6
|
require 'docker/compose'
|
7
7
|
|
8
|
+
# Only used here, so only required here
|
9
|
+
require 'docker/compose/shell_printer'
|
10
|
+
|
8
11
|
module Docker::Compose
|
9
12
|
class RakeTasks < Rake::TaskLib
|
10
13
|
# Set the directory in which docker-compose commands will be run. Default
|
@@ -17,32 +20,33 @@ module Docker::Compose
|
|
17
20
|
# @return [String]
|
18
21
|
attr_accessor :file
|
19
22
|
|
20
|
-
# Provide a mapping of environment variables that should be set in
|
21
|
-
# _host_
|
23
|
+
# Provide a mapping of environment variables that should be set in
|
24
|
+
# _host_ processes, e.g. when running docker:compose:env or
|
25
|
+
# docker:compose:host.
|
26
|
+
#
|
22
27
|
# The values of the environment variables can refer to names of services
|
23
|
-
# and ports defined in the docker-compose file, and this gem will
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
28
|
+
# and ports defined in the docker-compose file, and this gem will substitute
|
29
|
+
# the actual IP and port that the containers are reachable on. This allows
|
30
|
+
# commands invoked via "docker:compose:host" to reach services running
|
31
|
+
# inside containers.
|
27
32
|
#
|
28
33
|
# @see Docker::Compose::Mapper for information about the substitution syntax
|
29
|
-
attr_accessor :
|
30
|
-
|
31
|
-
# Extra environment variables
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# location of a container; they are simply extra environment values that are
|
35
|
-
# useful to change the server's behavior when it runs in cooperation
|
36
|
-
# with containers.
|
34
|
+
attr_accessor :host_env
|
35
|
+
|
36
|
+
# Extra environment variables to set before invoking host processes. These
|
37
|
+
# are set _in addition_ to server_env, but are not substituted in any way
|
38
|
+
# and must not contain any service information.
|
37
39
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
attr_accessor :
|
40
|
+
# Extra host env should be disjoint from host_env; if there is overlap
|
41
|
+
# between the two, then extra_host_env will "win."
|
42
|
+
attr_accessor :extra_host_env
|
41
43
|
|
42
|
-
#
|
43
|
-
# This is
|
44
|
-
#
|
45
|
-
|
44
|
+
# Services to bring up with `docker-compose up` before running any hosted
|
45
|
+
# command. This is useful if your `docker-compose.yml` contains a service
|
46
|
+
# definition for the app you will be hosting; if you host the app, you
|
47
|
+
# want to specify all of the _other_ services, but not the app itself, since
|
48
|
+
# that will run on the host.
|
49
|
+
attr_accessor :host_services
|
46
50
|
|
47
51
|
# Namespace to define the rake tasks under. Defaults to "docker:compose'.
|
48
52
|
attr_accessor :rake_namespace
|
@@ -53,14 +57,15 @@ module Docker::Compose
|
|
53
57
|
def initialize
|
54
58
|
self.dir = Rake.application.original_dir
|
55
59
|
self.file = 'docker-compose.yml'
|
56
|
-
self.
|
57
|
-
self.
|
60
|
+
self.host_env = {}
|
61
|
+
self.extra_host_env = {}
|
58
62
|
self.rake_namespace = 'docker:compose'
|
59
63
|
yield self if block_given?
|
60
64
|
|
61
65
|
@shell = Backticks::Runner.new
|
62
66
|
@session = Docker::Compose::Session.new(@shell, dir:dir, file:file)
|
63
67
|
@net_info = Docker::Compose::NetInfo.new
|
68
|
+
@shell_printer = Docker::Compose::ShellPrinter.new
|
64
69
|
|
65
70
|
@shell.interactive = true
|
66
71
|
|
@@ -73,41 +78,22 @@ module Docker::Compose
|
|
73
78
|
task :env do
|
74
79
|
@shell.interactive = false # suppress useless 'port' output
|
75
80
|
|
76
|
-
if
|
77
|
-
|
78
|
-
# environment _and_ print bash export commands to stdout.
|
79
|
-
# Also print usage hints if user invoked rake directly vs.
|
80
|
-
# eval'ing it's output
|
81
|
-
print_usage
|
82
|
-
export_env(print:true)
|
83
|
-
else
|
84
|
-
# This task is a dependency of something else; just export the
|
85
|
-
# environment variables for use in-process by other Rake tasks.
|
86
|
-
export_env(print:false)
|
87
|
-
end
|
81
|
+
print_usage if STDOUT.tty?
|
82
|
+
export_env(print:true)
|
88
83
|
|
89
84
|
@shell.interactive = true
|
90
85
|
end
|
91
86
|
|
92
|
-
desc '
|
93
|
-
task :
|
94
|
-
only = (ENV['ONLY'] || '').split(',').compact.uniq
|
95
|
-
@session.up(*only, detached:true)
|
96
|
-
end
|
97
|
-
|
98
|
-
desc 'Tail logs of all running services'
|
99
|
-
task :logs do
|
100
|
-
@session.logs
|
101
|
-
end
|
87
|
+
desc 'Run command on host, linked to services in containers'
|
88
|
+
task :host, [:command] => ['docker:compose:env'] do |task, args|
|
102
89
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
90
|
+
if self.host_services
|
91
|
+
@session.up(*self.host_services, detached:true)
|
92
|
+
else
|
93
|
+
@session.up(detached:true)
|
94
|
+
end
|
107
95
|
|
108
|
-
|
109
|
-
task :server => ['docker:compose:up', 'docker:compose:env'] do
|
110
|
-
exec(self.server)
|
96
|
+
exec(args[:command])
|
111
97
|
end
|
112
98
|
end
|
113
99
|
end
|
@@ -116,17 +102,14 @@ module Docker::Compose
|
|
116
102
|
# published by docker-compose services. Optionally also print bash export
|
117
103
|
# statements so this information can be made available to a user's shell.
|
118
104
|
private def export_env(print:)
|
119
|
-
Docker::Compose::Mapper.map(self.
|
105
|
+
Docker::Compose::Mapper.map(self.host_env,
|
120
106
|
session:@session,
|
121
107
|
net_info:@net_info) do |k, v|
|
122
108
|
ENV[k] = serialize_for_env(v)
|
123
109
|
print_env(k, ENV[k]) if print
|
124
110
|
end
|
125
111
|
|
126
|
-
|
127
|
-
strict:false,
|
128
|
-
session:@session,
|
129
|
-
net_info:@net_info) do |k, v|
|
112
|
+
self.extra_host_env.each do |k, v|
|
130
113
|
ENV[k] = serialize_for_env(v)
|
131
114
|
print_env(k, ENV[k]) if print
|
132
115
|
end
|
@@ -148,19 +131,21 @@ module Docker::Compose
|
|
148
131
|
end
|
149
132
|
end
|
150
133
|
|
151
|
-
# Print
|
134
|
+
# Print an export or unset statement suitable for user's shell
|
152
135
|
private def print_env(k, v)
|
153
136
|
if v
|
154
|
-
puts
|
137
|
+
puts @shell_printer.export(k, v)
|
155
138
|
else
|
156
|
-
puts
|
139
|
+
puts @shell_printer.unset(k)
|
157
140
|
end
|
158
141
|
end
|
159
142
|
|
143
|
+
|
160
144
|
private def print_usage
|
161
|
-
|
162
|
-
|
163
|
-
puts
|
145
|
+
command = "rake #{rake_namespace}:env"
|
146
|
+
command = "bundle exec " + command if defined?(Bundler)
|
147
|
+
puts @shell_printer.comment('To export these variables to your shell, run:')
|
148
|
+
puts @shell_printer.comment(@shell_printer.eval_output(command))
|
164
149
|
end
|
165
150
|
end
|
166
151
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'etc'
|
2
|
+
|
3
|
+
module Docker::Compose
|
4
|
+
module ShellPrinter
|
5
|
+
def self.new
|
6
|
+
shell = Etc.getpwuid(Process.uid).shell
|
7
|
+
basename = File.basename(shell)
|
8
|
+
|
9
|
+
# Crappy titleize (bash -> Bash)
|
10
|
+
basename[0] = basename[0].upcase
|
11
|
+
|
12
|
+
# Find adapter class named after shell; default to posix if nothing found
|
13
|
+
klass = const_get(basename.to_sym) rescue Posix
|
14
|
+
|
15
|
+
klass.new
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require_relative 'shell_printer/posix'
|
21
|
+
require_relative 'shell_printer/fish'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Docker::Compose::ShellPrinter
|
2
|
+
# Printer that works with the Friendly Interactive Shell (fish).
|
3
|
+
class Fish < Posix
|
4
|
+
def eval_output(command)
|
5
|
+
format('eval (%s)', command)
|
6
|
+
end
|
7
|
+
|
8
|
+
def export(name, value)
|
9
|
+
format('set -gx %s %s; ', name, single_quoted_escaped(value))
|
10
|
+
end
|
11
|
+
|
12
|
+
def unset(name)
|
13
|
+
format('set -ex %s; ', name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Docker::Compose::ShellPrinter
|
2
|
+
# Printer that works with any POSIX-compliant shell e.g. sh, bash, zsh
|
3
|
+
class Posix
|
4
|
+
def comment(value)
|
5
|
+
format('# %s', value)
|
6
|
+
end
|
7
|
+
|
8
|
+
def eval_output(command)
|
9
|
+
format('eval "$(%s)"', command)
|
10
|
+
end
|
11
|
+
|
12
|
+
def export(name, value)
|
13
|
+
format('export %s=%s', name, single_quoted_escaped(value))
|
14
|
+
end
|
15
|
+
|
16
|
+
def unset(name)
|
17
|
+
format('unset %s', name)
|
18
|
+
end
|
19
|
+
|
20
|
+
protected def single_quoted_escaped(value)
|
21
|
+
# "escape" any occurrences of ' in value by closing the single-quoted
|
22
|
+
# string, concatenating a single backslash-escaped ' character, and reopening
|
23
|
+
# the single-quoted string.
|
24
|
+
#
|
25
|
+
# This relies on the shell's willingness to concatenate adjacent string
|
26
|
+
# literals. Tested under sh, bash and zsh; should work elsewhere.
|
27
|
+
escaped = value.gsub("'") { "'\\''" }
|
28
|
+
|
29
|
+
"'#{escaped}'"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docker-compose
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Spataro
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04
|
11
|
+
date: 2016-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backticks
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- ".rspec"
|
79
79
|
- ".ruby-version"
|
80
80
|
- ".travis.yml"
|
81
|
+
- CHANGELOG.md
|
81
82
|
- CODE_OF_CONDUCT.md
|
82
83
|
- Gemfile
|
83
84
|
- LICENSE.txt
|
@@ -92,6 +93,9 @@ files:
|
|
92
93
|
- lib/docker/compose/net_info.rb
|
93
94
|
- lib/docker/compose/rake_tasks.rb
|
94
95
|
- lib/docker/compose/session.rb
|
96
|
+
- lib/docker/compose/shell_printer.rb
|
97
|
+
- lib/docker/compose/shell_printer/fish.rb
|
98
|
+
- lib/docker/compose/shell_printer/posix.rb
|
95
99
|
- lib/docker/compose/version.rb
|
96
100
|
homepage: https://github.com/xeger/docker-compose
|
97
101
|
licenses:
|