docker-rails 0.4.1 → 0.5.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/.travis.yml +6 -1
- data/README.md +28 -2
- data/lib/docker/rails.rb +2 -1
- data/lib/docker/rails/app.rb +72 -74
- data/lib/docker/rails/cli/main.rb +8 -3
- data/lib/docker/rails/ext/container.rb +33 -0
- data/lib/docker/rails/{core_ext → ext}/hash.rb +0 -0
- data/lib/docker/rails/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 285dc77cef10695d9e17976de3d0d4ce48191422
|
4
|
+
data.tar.gz: f8e2eca7b132eb6b97dced3fe8a04b64512d5dd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ab35a4c1b39129157b8962f383e02eb4004a37c798c2512aa49ad993e97f39e7fb5229a7b5901175a767b057d5d2ab38fbd20ba385534530cde0df53cb25a3a
|
7
|
+
data.tar.gz: a9f88b10b75cdf755de564ed85479d6eee098ec522d98415fdc4211e23b57c092d83fb299fdd2dd697c8cfd6af5c4a41a980d5c3ef1b0f1bd0f0e2059935aed5
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -18,6 +18,26 @@ A simplified pattern to execute rails applications within Docker (with a CI buil
|
|
18
18
|
### CI
|
19
19
|
|
20
20
|
CI, the reason this is built. Do it all, do it consistently, do it concurrently, do it easily, and always cleanup after yourself.
|
21
|
+
|
22
|
+
`bundle exec ci test`
|
23
|
+
|
24
|
+
#### CI workflow
|
25
|
+
|
26
|
+
`ci` executes:
|
27
|
+
|
28
|
+
1. `before_command` - run anything on the host prior to building the docker image e.g. `rm -Rf target`
|
29
|
+
2. `compose` - create the resolved `docker-compose.yml`
|
30
|
+
3. `gems_volume` - find or create the shared global gems volume for this ruby version
|
31
|
+
4. `build` - `docker-compose build` the configuration
|
32
|
+
5. `up` - `docker-compose up` the configuration
|
33
|
+
6. `cleanup`
|
34
|
+
1. `stop` - stop all containers for this configuration (including one-off sessions)
|
35
|
+
2. `extract` - extract any defined files from any container
|
36
|
+
3. `rm_volumes` - `docker-compose rm -v --force` to cleanup any container volumes (excluding the gems volume)
|
37
|
+
4. `rm_compose` - cleanup the generated compose.yml file for the `build`
|
38
|
+
5. `rm_dangling` - cleanup any dangling images
|
39
|
+
|
40
|
+
#### CI execution options
|
21
41
|
|
22
42
|
```bash
|
23
43
|
bundle exec docker-rails ci --build=222 test
|
@@ -33,7 +53,7 @@ or for local testing (uses `1` for build)
|
|
33
53
|
|
34
54
|
```bash
|
35
55
|
bundle exec docker-rails ci test
|
36
|
-
|
56
|
+
```
|
37
57
|
|
38
58
|
### General CLI
|
39
59
|
|
@@ -41,7 +61,7 @@ Almost all of the commands below are in support of the `ci` command, so why not
|
|
41
61
|
|
42
62
|
```bash
|
43
63
|
Commands:
|
44
|
-
docker-rails bash_connect <target> <service_name> # Open a bash shell to a running container e.g. bundle exec docker-rails bash --build=222 development db
|
64
|
+
docker-rails bash_connect <target> <service_name> # Open a bash shell to a running container (with automatic cleanup) e.g. bundle exec docker-rails bash --build=222 development db
|
45
65
|
docker-rails build <target> # Build for the given build/target e.g. bundle exec docker-rails build --build=222 development
|
46
66
|
docker-rails ci <target> # Execute the works, everything with cleanup included e.g. bundle exec docker-rails ci --build=222 test
|
47
67
|
docker-rails cleanup <target> # Runs container cleanup functions stop, rm_volumes, rm_compose, rm_dangling, ps_all e.g. bundle exec docker-rails cleanup --build=222 development
|
@@ -107,6 +127,12 @@ RUN apt-get update -qq && \
|
|
107
127
|
|
108
128
|
# https://github.com/docker/docker/issues/4032
|
109
129
|
ENV DEBIAN_FRONTEND newt
|
130
|
+
|
131
|
+
# Bypass the union file system for better performance https://docs.docker.com/userguide/dockervolumes/
|
132
|
+
VOLUME /project
|
133
|
+
|
134
|
+
# Copy the project files into the container (again, better performance). Use `extract` in the docker-rails.yml to obtain files such as test results.
|
135
|
+
COPY . /project
|
110
136
|
```
|
111
137
|
|
112
138
|
### 2. Add a docker-rails.yml
|
data/lib/docker/rails.rb
CHANGED
@@ -9,7 +9,8 @@ require 'thor'
|
|
9
9
|
require 'docker'
|
10
10
|
require 'archive/tar/minitar'
|
11
11
|
|
12
|
-
require 'docker/rails/
|
12
|
+
require 'docker/rails/ext/hash'
|
13
|
+
require 'docker/rails/ext/container'
|
13
14
|
|
14
15
|
require 'docker/rails/config'
|
15
16
|
require 'docker/rails/compose_config'
|
data/lib/docker/rails/app.rb
CHANGED
@@ -76,36 +76,15 @@ module Docker
|
|
76
76
|
end
|
77
77
|
|
78
78
|
puts "\nExtracting #{service_name} #{from} to #{to}"
|
79
|
-
|
79
|
+
begin
|
80
|
+
extract_files(container, from, to)
|
81
|
+
rescue => e
|
82
|
+
puts e.message
|
83
|
+
end
|
80
84
|
end
|
81
85
|
end
|
82
86
|
end
|
83
87
|
|
84
|
-
|
85
|
-
def extract_files(container, from, to)
|
86
|
-
# or something like
|
87
|
-
tar_stringio = StringIO.new
|
88
|
-
container.copy(from) do |chunk|
|
89
|
-
tar_stringio.write(chunk)
|
90
|
-
end
|
91
|
-
|
92
|
-
tar_stringio.rewind
|
93
|
-
|
94
|
-
input = Archive::Tar::Minitar::Input.new(tar_stringio)
|
95
|
-
input.each { |entry|
|
96
|
-
|
97
|
-
# Need to check the file name length to prevent some very bad things from happening.
|
98
|
-
if entry.full_name.length > 255
|
99
|
-
puts "ERROR - file name length is > 255 characters: #{entry.full_name}"
|
100
|
-
elsif entry.full_name.length <= 0
|
101
|
-
puts "ERROR - file name length is too small: #{entry.full_name}"
|
102
|
-
else
|
103
|
-
puts "Extracting #{entry.full_name}"
|
104
|
-
input.extract_entry(to, entry)
|
105
|
-
end
|
106
|
-
}
|
107
|
-
end
|
108
|
-
|
109
88
|
def compose
|
110
89
|
# Write a docker-compose.yml with interpolated variables
|
111
90
|
@compose_filename = compose_filename_from @build, @target
|
@@ -143,11 +122,21 @@ module Docker
|
|
143
122
|
exec_compose 'ps'
|
144
123
|
end
|
145
124
|
|
125
|
+
def exec_ps_all
|
126
|
+
puts "\n\nAll remaining containers..."
|
127
|
+
puts '-----------------------------'
|
128
|
+
exec 'docker ps -a'
|
129
|
+
end
|
130
|
+
|
146
131
|
def exec_stop
|
147
132
|
puts "\n\n\n\nStopping containers..."
|
148
133
|
puts '-----------------------------'
|
149
|
-
|
150
|
-
|
134
|
+
containers = Docker::Container.all(all: true)
|
135
|
+
containers.each do |container|
|
136
|
+
if is_build_container?(container)
|
137
|
+
puts container.compose
|
138
|
+
container.stop
|
139
|
+
end
|
151
140
|
end
|
152
141
|
puts 'Done.'
|
153
142
|
end
|
@@ -155,8 +144,14 @@ module Docker
|
|
155
144
|
def exec_remove_volumes
|
156
145
|
puts "\n\nRemoving container volumes..."
|
157
146
|
puts '-----------------------------'
|
158
|
-
|
159
|
-
|
147
|
+
|
148
|
+
# http://docs.docker.com/v1.7/reference/api/docker_remote_api_v1.19/#remove-a-container
|
149
|
+
containers = Docker::Container.all(all: true)
|
150
|
+
containers.each do |container|
|
151
|
+
if is_build_container?(container)
|
152
|
+
puts container.compose
|
153
|
+
container.remove(v: true, force: true)
|
154
|
+
end
|
160
155
|
end
|
161
156
|
puts 'Done.'
|
162
157
|
end
|
@@ -171,21 +166,21 @@ module Docker
|
|
171
166
|
puts 'Done.'
|
172
167
|
end
|
173
168
|
|
174
|
-
def show_all_containers
|
175
|
-
puts "\n\nAll remaining containers..."
|
176
|
-
puts '-----------------------------'
|
177
|
-
system 'docker ps -a'
|
178
|
-
end
|
179
|
-
|
180
169
|
def exec_run(service_name, command)
|
181
170
|
# Run the compose configuration
|
182
171
|
exec_compose "run #{service_name} #{command}"
|
183
172
|
end
|
184
173
|
|
185
174
|
def exec_bash_connect(service_name)
|
186
|
-
# docker exec -it
|
187
|
-
|
188
|
-
|
175
|
+
# docker exec -it 2ed97d0bb938 bash
|
176
|
+
container = get_container(service_name)
|
177
|
+
if container.nil?
|
178
|
+
puts "#{service_name} does not appear to be running for build #{@build}"
|
179
|
+
return
|
180
|
+
end
|
181
|
+
|
182
|
+
exec "docker exec -it #{container.id} bash"
|
183
|
+
container
|
189
184
|
end
|
190
185
|
|
191
186
|
# Create global gems data volume to cache gems for this version of ruby
|
@@ -220,46 +215,25 @@ module Docker
|
|
220
215
|
exec("docker-compose -f #{@compose_filename} -p #{@build} #{cmd} #{options}", capture)
|
221
216
|
end
|
222
217
|
|
223
|
-
# service_name i.e. 'db' or 'web'
|
224
|
-
def get_container_name(service_name)
|
225
|
-
output = exec_compose "ps #{service_name}", true
|
226
|
-
# puts "get_container(#{service_name}): \n#{output}"
|
227
|
-
output =~ /^(\w+)/ # grab the name, only thing that is at the start of the line
|
228
|
-
$1
|
229
|
-
end
|
230
|
-
|
231
218
|
def get_container(service_name)
|
232
|
-
Docker::Container.
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
# puts "#{service_name}: container_name #{container_name}"
|
239
|
-
#
|
240
|
-
# container = Docker::Container.get(container_name)
|
241
|
-
# # container.streaming_logs(stdout: true) { |stream, chunk| puts "#{service_name}: #{chunk}" }
|
242
|
-
# # puts container
|
243
|
-
#
|
244
|
-
# {service_name => {'container' => container, 'container_name' => container_name}}
|
245
|
-
# end
|
246
|
-
|
247
|
-
def rm_v(service_name)
|
248
|
-
exec_compose "rm -v --force #{service_name}"
|
249
|
-
end
|
219
|
+
containers = Docker::Container.all(all: true)
|
220
|
+
containers.each do |container|
|
221
|
+
if is_build_container?(container) && container.compose.service.eql?(service_name)
|
222
|
+
return container
|
223
|
+
end
|
224
|
+
end
|
250
225
|
|
251
|
-
|
252
|
-
exec_compose "stop #{service_name}"
|
226
|
+
nil
|
253
227
|
end
|
254
228
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
# skip = skips.include? command.to_s
|
259
|
-
# puts "Skipping #{command}" if skip && verbose?
|
260
|
-
# skip
|
261
|
-
# end
|
229
|
+
def is_build_container?(container)
|
230
|
+
# labels = container.info['Labels']
|
231
|
+
# build = labels['com.docker.compose.project']
|
262
232
|
|
233
|
+
return false if container.compose.nil?
|
234
|
+
return true if @build.eql? container.compose.project
|
235
|
+
false
|
236
|
+
end
|
263
237
|
|
264
238
|
def verbose?
|
265
239
|
@verbose ||= (@config['verbose'] unless @config.nil?) || false
|
@@ -281,6 +255,30 @@ module Docker
|
|
281
255
|
def compose_filename_from(build, target)
|
282
256
|
"docker-compose-#{target}-#{build}.yml"
|
283
257
|
end
|
258
|
+
|
259
|
+
def extract_files(container, from, to)
|
260
|
+
# or something like
|
261
|
+
tar_stringio = StringIO.new
|
262
|
+
container.copy(from) do |chunk|
|
263
|
+
tar_stringio.write(chunk)
|
264
|
+
end
|
265
|
+
|
266
|
+
tar_stringio.rewind
|
267
|
+
|
268
|
+
input = Archive::Tar::Minitar::Input.new(tar_stringio)
|
269
|
+
input.each { |entry|
|
270
|
+
|
271
|
+
# Need to check the file name length to prevent some very bad things from happening.
|
272
|
+
if entry.full_name.length > 255
|
273
|
+
puts "ERROR - file name length is > 255 characters: #{entry.full_name}"
|
274
|
+
elsif entry.full_name.length <= 0
|
275
|
+
puts "ERROR - file name length is too small: #{entry.full_name}"
|
276
|
+
else
|
277
|
+
puts "Extracting #{entry.full_name}"
|
278
|
+
input.extract_entry(to, entry)
|
279
|
+
end
|
280
|
+
}
|
281
|
+
end
|
284
282
|
end
|
285
283
|
end
|
286
284
|
end
|
@@ -131,10 +131,10 @@ module Docker
|
|
131
131
|
desc 'ps_all', 'List all remaining containers regardless of state e.g. bundle exec docker-rails ps_all'
|
132
132
|
|
133
133
|
def ps_all(build = nil, target = nil)
|
134
|
-
App.instance.
|
134
|
+
App.instance.exec_ps_all
|
135
135
|
end
|
136
136
|
|
137
|
-
desc 'bash_connect <target> <service_name>', 'Open a bash shell to a running container e.g. bundle exec docker-rails bash --build=222 development db'
|
137
|
+
desc 'bash_connect <target> <service_name>', 'Open a bash shell to a running container (with automatic cleanup) e.g. bundle exec docker-rails bash --build=222 development db'
|
138
138
|
|
139
139
|
def bash_connect(target, service_name)
|
140
140
|
# init singleton with full options
|
@@ -142,7 +142,12 @@ module Docker
|
|
142
142
|
|
143
143
|
invoke :compose, [target], []
|
144
144
|
|
145
|
-
app.exec_bash_connect(service_name)
|
145
|
+
container = app.exec_bash_connect(service_name)
|
146
|
+
|
147
|
+
# Automatically cleanup any remnants of a simple bash session.
|
148
|
+
return if container.nil?
|
149
|
+
container.stop
|
150
|
+
container.remove(v: true, force: true)
|
146
151
|
end
|
147
152
|
|
148
153
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Docker::Container
|
2
|
+
|
3
|
+
def compose
|
4
|
+
return nil unless Compose.is_compose_container?(self)
|
5
|
+
@_compose ||= Compose.new(self)
|
6
|
+
end
|
7
|
+
|
8
|
+
class Compose
|
9
|
+
attr_reader :number, :oneoff, :project, :service, :version, :name
|
10
|
+
|
11
|
+
def initialize(container)
|
12
|
+
labels = container.info['Labels']
|
13
|
+
@service = labels['com.docker.compose.service']
|
14
|
+
@project = labels['com.docker.compose.project']
|
15
|
+
@oneoff = !!labels['com.docker.compose.oneoff']
|
16
|
+
@number = labels['com.docker.compose.container-number'].to_i
|
17
|
+
@version = labels['com.docker.compose.version']
|
18
|
+
@name = container.info['Names'][0].gsub(/^\//, '')
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
@name
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
def is_compose_container?(container)
|
27
|
+
labels = container.info['Labels']
|
28
|
+
(!labels.nil? && !labels['com.docker.compose.version'].nil?)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
File without changes
|
data/lib/docker/rails/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docker-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Ross
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-09-
|
11
|
+
date: 2015-09-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -162,7 +162,8 @@ files:
|
|
162
162
|
- lib/docker/rails/cli/main.rb
|
163
163
|
- lib/docker/rails/compose_config.rb
|
164
164
|
- lib/docker/rails/config.rb
|
165
|
-
- lib/docker/rails/
|
165
|
+
- lib/docker/rails/ext/container.rb
|
166
|
+
- lib/docker/rails/ext/hash.rb
|
166
167
|
- lib/docker/rails/version.rb
|
167
168
|
- spec/docker/rails/config_spec.rb
|
168
169
|
- spec/docker/rails/docker-rails.yml
|