docker-rails 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/README.md +190 -74
- data/Rakefile +7 -1
- data/bin/docker-rails +3 -133
- data/docker-rails.gemspec +5 -3
- data/lib/docker/rails.rb +11 -1
- data/lib/docker/rails/CLI/db_check.rb +67 -0
- data/lib/docker/rails/CLI/gems_volume.rb +27 -0
- data/lib/docker/rails/CLI/main.rb +117 -0
- data/lib/docker/rails/app.rb +176 -0
- data/lib/docker/rails/config.rb +40 -0
- data/lib/docker/rails/version.rb +1 -1
- data/spec/docker/rails/config_spec.rb +95 -0
- data/spec/docker/rails/docker-rails.yml +159 -0
- data/spec/spec_helper.rb +11 -0
- metadata +64 -12
- data/bin/docker-rails-db-check +0 -38
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd13b3e449ebecf3beeeaf1ccce34d9d8a4d82ad
|
4
|
+
data.tar.gz: ef722489bc87dd8c6078d470360289456633f0f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a166ca39b19deacf676c1794066b51c05ff3885f76398785c3d28f2d95d2d977926cec5fbb11ed3703925df04b5ae676debe4d0a2a3ac1a6a4e64c6529a8ee8
|
7
|
+
data.tar.gz: 51f1969e15638ecdd42f8cf20d2c8838d7e947c19158a7af6ed41b4406f28ecc91ee24b72f2d92905e2b0146eef8df14216e79a60a3b106721edc945dd2d0706
|
data/.rspec
ADDED
data/README.md
CHANGED
@@ -3,21 +3,36 @@
|
|
3
3
|
A simplified pattern to execute rails applications within Docker (with a CI build emphasis).
|
4
4
|
|
5
5
|
## Features
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
-
|
6
|
+
- Provides individual functions for development/test usage, or a full workflow for CI usage (with automated container, volume, and image cleanup).
|
7
|
+
- Automated cached global gems data volume (automatic) based on ruby version
|
8
|
+
- DRY declarative `docker-rails.yml` allowing multiple environments to be defined with an inherited `docker-compose` configuration
|
9
|
+
- Interpolates `docker-compose.yml` making CI builds much easier
|
10
|
+
- DB check CLI function provided for docker-compose `command` to check if db is ready
|
11
11
|
|
12
12
|
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
```bash
|
16
|
+
Commands:
|
17
|
+
docker-rails ci <build_name> <environment_name> # Execute the works, everything with cleanup included i.e. bundle exec docker-rails ci 222 test
|
18
|
+
docker-rails compose <build_name> <environment_name> # Writes a resolved docker-compose.yml file
|
19
|
+
docker-rails db_check <db> # Runs db_check
|
20
|
+
docker-rails gems_volume <command> # Gems volume management
|
21
|
+
docker-rails help [COMMAND] # Describe available commands or one specific command
|
22
|
+
docker-rails rm_compose # Remove generated docker_compose file
|
23
|
+
docker-rails rm_dangling # Remove danging images
|
24
|
+
docker-rails rm_volumes <build_name> <environment_name> # Stop all running containers and remove corresponding volumes for the given build_name/environment_name
|
25
|
+
docker-rails show_all_containers # Show all remaining containers regardless of state
|
26
|
+
docker-rails stop <build_name> <environment_name> # Stop all running containers for the given build_name/environment_name
|
27
|
+
docker-rails up <build_name> <environment_name> # Up the docker-compose configuration for the given build_name/environment_name
|
28
|
+
```
|
29
|
+
|
13
30
|
## Work in progress - contributions welcome
|
14
|
-
Open to pull requests
|
31
|
+
Open to pull requests. It can be expanded to suit many different configurations.
|
15
32
|
|
16
33
|
TODO:
|
17
|
-
-
|
18
|
-
- expand to different db status detection as
|
19
|
-
- move to proper CLI (it's mostly in script form at the moment)
|
20
|
-
- (perhaps) provide name based compose configurations, i.e. running `docker-rails development` vs. `docker-rails test` vs. `docker-rails parallel_tests` might be nice to have (and easy) since most of the configuration is the same, sans `command`.
|
34
|
+
- **Permissions** - [Shared volume for project has files written as root](https://github.com/alienfast/docker-rails/issues/5)
|
35
|
+
- **DB versatility** - expand to different db status detection as-needed e.g. postgres. CLI is now modularized to allow for this.
|
21
36
|
|
22
37
|
|
23
38
|
## Installation
|
@@ -55,82 +70,183 @@ RUN apt-get update -qq && \
|
|
55
70
|
|
56
71
|
# https://github.com/docker/docker/issues/4032
|
57
72
|
ENV DEBIAN_FRONTEND newt
|
58
|
-
|
59
|
-
ADD . /project
|
60
|
-
WORKDIR /project
|
61
73
|
```
|
62
74
|
|
63
|
-
### 2. Add a docker-
|
75
|
+
### 2. Add a docker-rails.yml
|
64
76
|
|
65
|
-
Environment variables will be interpolated, so feel free to use them.
|
77
|
+
Environment variables will be interpolated, so feel free to use them.
|
78
|
+
Below shows an example with all of the environments `development | test | parallel_tests | staging' to show reuse of the primary `docker-compose' configuration.
|
66
79
|
|
67
80
|
```yaml
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
81
|
+
verbose: true
|
82
|
+
|
83
|
+
# local environments need elasticsearch, staging/production connects to existing running instance.
|
84
|
+
elasticsearch: &elasticsearch
|
85
|
+
elasticsearch:
|
86
|
+
image: library/elasticsearch:1.7
|
87
|
+
ports:
|
88
|
+
- "9200"
|
89
|
+
|
90
|
+
development:
|
91
|
+
docker-compose:
|
92
|
+
<<: *elasticsearch
|
93
|
+
web:
|
94
|
+
links:
|
95
|
+
- elasticsearch # standard yaml doesn't merge arrays so we have to add this explicitly
|
96
|
+
environment:
|
97
|
+
- RAILS_ENV=development
|
98
|
+
command: >
|
99
|
+
bash -c "
|
100
|
+
|
101
|
+
echo 'Bundling gems'
|
102
|
+
&& bundle install --jobs 4 --retry 3
|
103
|
+
|
104
|
+
&& echo 'Generating Spring binstubs'
|
105
|
+
&& bundle exec spring binstub --all
|
106
|
+
|
107
|
+
&& echo 'Clearing logs and tmp dirs'
|
108
|
+
&& bundle exec rake log:clear tmp:clear
|
109
|
+
|
110
|
+
&& echo 'Check and wait for database connection'
|
111
|
+
&& bundle exec docker-rails db_check mysql
|
112
|
+
|
113
|
+
&& echo 'Setting up new db if one doesn't exist'
|
114
|
+
&& bundle exec rake db:version || { bundle exec rake db:setup; }
|
115
|
+
|
116
|
+
&& echo "Starting app server"
|
117
|
+
&& bundle exec rails s -p 3000
|
118
|
+
|
119
|
+
&& echo 'Setup and start foreman'
|
120
|
+
&& gem install foreman
|
121
|
+
&& foreman start
|
122
|
+
"
|
123
|
+
|
124
|
+
test:
|
125
|
+
before_command: rm -Rf target
|
126
|
+
docker-compose:
|
127
|
+
<<: *elasticsearch
|
128
|
+
web:
|
129
|
+
links:
|
130
|
+
- elasticsearch # standard yaml doesn't merge arrays so we have to add this explicitly
|
131
|
+
environment:
|
132
|
+
- RAILS_ENV=test
|
133
|
+
command: >
|
134
|
+
bash -c "
|
135
|
+
echo 'Bundling gems'
|
136
|
+
&& bundle install --jobs 4 --retry 3
|
137
|
+
|
138
|
+
&& echo 'Clearing logs and tmp dirs'
|
139
|
+
&& bundle exec rake log:clear tmp:clear
|
140
|
+
|
141
|
+
&& echo 'Check and wait for database connection'
|
142
|
+
&& bundle exec docker-rails db_check mysql
|
143
|
+
|
144
|
+
&& echo 'Setting up new db if one doesn't exist'
|
145
|
+
&& bundle exec rake db:version || { bundle exec rake db:setup; }
|
146
|
+
|
147
|
+
&& echo 'Tests'
|
148
|
+
&& cd ../..
|
149
|
+
&& xvfb-run -a bundle exec rake spec cucumber
|
150
|
+
"
|
151
|
+
|
152
|
+
parallel_tests:
|
153
|
+
before_command: rm -Rf target
|
154
|
+
docker-compose:
|
155
|
+
<<: *elasticsearch
|
156
|
+
web:
|
157
|
+
links:
|
158
|
+
- elasticsearch # standard yaml doesn't merge arrays so we have to add this explicitly
|
159
|
+
environment:
|
160
|
+
- RAILS_ENV=test
|
161
|
+
command: >
|
162
|
+
bash -c "
|
163
|
+
|
164
|
+
echo 'Bundling gems'
|
165
|
+
&& bundle install --jobs 4 --retry 3
|
166
|
+
|
167
|
+
&& echo 'Clearing logs and tmp dirs'
|
168
|
+
&& bundle exec rake log:clear tmp:clear
|
169
|
+
|
170
|
+
&& echo 'Check and wait for database connection'
|
171
|
+
&& bundle exec docker-rails db_check mysql
|
172
|
+
|
173
|
+
&& echo 'Setting up new db if one doesn't exist'
|
174
|
+
&& bundle exec rake parallel:drop parallel:create parallel:migrate parallel:seed
|
175
|
+
|
176
|
+
&& echo 'Tests'
|
177
|
+
&& cd ../..
|
178
|
+
&& xvfb-run -a bundle exec rake parallel:spec parallel:features
|
179
|
+
"
|
180
|
+
|
181
|
+
staging:
|
182
|
+
docker-compose:
|
183
|
+
web:
|
184
|
+
environment:
|
185
|
+
- RAILS_ENV=staging
|
186
|
+
command: >
|
187
|
+
bash -c "
|
188
|
+
|
189
|
+
echo 'Bundling gems'
|
190
|
+
&& bundle install --jobs 4 --retry 3
|
191
|
+
|
192
|
+
&& echo 'Clearing logs and tmp dirs'
|
193
|
+
&& bundle exec rake log:clear tmp:clear
|
194
|
+
|
195
|
+
&& echo 'Check and wait for database connection'
|
196
|
+
&& bundle exec docker-rails db_check mysql
|
197
|
+
|
198
|
+
&& echo 'Setting up new db if one doesn't exist'
|
199
|
+
&& bundle exec rake db:migrate
|
200
|
+
|
201
|
+
&& echo "Starting app server"
|
202
|
+
&& bundle exec rails s -p 3000
|
203
|
+
|
204
|
+
&& echo 'Setup and start foreman'
|
205
|
+
&& gem install foreman
|
206
|
+
&& foreman start
|
207
|
+
"
|
208
|
+
|
209
|
+
docker-compose:
|
210
|
+
web:
|
211
|
+
build: .
|
212
|
+
working_dir: /project/spec/dummy
|
213
|
+
ports:
|
214
|
+
- "3000"
|
215
|
+
|
216
|
+
links:
|
217
|
+
- db
|
218
|
+
|
219
|
+
volumes:
|
220
|
+
- .:/project
|
221
|
+
|
222
|
+
volumes_from:
|
223
|
+
# Mount the gems data volume container for cached bundler gem files
|
224
|
+
- #{GEMS_VOLUME_NAME}
|
225
|
+
|
226
|
+
# https://docs.docker.com/v1.6/docker-compose/cli/#environment-variables
|
227
|
+
environment:
|
228
|
+
# Tell bundler where to get the files
|
229
|
+
- GEM_HOME=#{GEMS_VOLUME_PATH}
|
230
|
+
|
231
|
+
db:
|
232
|
+
# https://github.com/docker-library/docs/tree/master/mysql
|
233
|
+
image: library/mysql:5.7.6
|
234
|
+
ports:
|
235
|
+
- "3306"
|
236
|
+
|
237
|
+
# https://github.com/docker-library/docs/tree/master/mysql#environment-variables
|
238
|
+
environment:
|
239
|
+
- MYSQL_ALLOW_EMPTY_PASSWORD=true
|
125
240
|
```
|
126
241
|
|
127
242
|
### 3. Run it
|
128
243
|
|
129
|
-
`bundle exec docker-rails`
|
244
|
+
`bundle exec docker-rails ci 111 test`
|
130
245
|
|
131
246
|
### 4. Submit pull requests!
|
132
247
|
|
133
|
-
|
248
|
+
The intent for this is to make rails with docker a snap. The code should be modular enough that adding a check for a different database etc should be quite simple.
|
249
|
+
We are open to expanding functionality beyond what is already provided.
|
134
250
|
|
135
251
|
|
136
252
|
## Contributing
|
data/Rakefile
CHANGED
data/bin/docker-rails
CHANGED
@@ -1,139 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
# compose cli
|
5
|
-
# https://docs.docker.com/v1.6/compose/cli/#environment-variables
|
6
|
-
|
7
|
-
# compose yml
|
8
|
-
# https://docs.docker.com/v1.6/compose/yml/
|
9
|
-
|
10
|
-
# remote api
|
11
|
-
# https://docs.docker.com/reference/api/docker_remote_api_v1.20
|
12
|
-
|
13
|
-
|
14
|
-
# docker-compose -f docker-compose-build-119.yml -p 119 up -d db
|
15
|
-
# docker-compose -f docker-compose-build-119.yml -p 119 up web
|
16
|
-
|
17
|
-
|
18
|
-
SHOW_COMMANDS = true
|
19
|
-
|
20
3
|
# enable local usage from cloned repo
|
21
|
-
root = File.expand_path('../..', __FILE__)
|
22
|
-
$LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
|
4
|
+
# root = File.expand_path('../..', __FILE__)
|
5
|
+
# $LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
|
23
6
|
|
24
7
|
require 'docker/rails'
|
25
8
|
|
26
|
-
|
27
|
-
ENV['BUILD_NAME'] = BUILD_NAME
|
28
|
-
|
29
|
-
# Discover ruby version from the Dockerfile image
|
30
|
-
IO.read('Dockerfile') =~ /^FROM \w+\/ruby:(\d+.\d+(?:.\d+))/
|
31
|
-
BUILD_RUBY_VERSION = $1
|
32
|
-
|
33
|
-
# Set as variable for interpolation
|
34
|
-
GEMS_VOLUME_PATH = "/gems/#{BUILD_RUBY_VERSION}"
|
35
|
-
GEMS_VOLUME_NAME = "gems-#{BUILD_RUBY_VERSION}"
|
36
|
-
ENV['GEMS_VOLUME_PATH'] = GEMS_VOLUME_PATH
|
37
|
-
ENV['GEMS_VOLUME_NAME'] = GEMS_VOLUME_NAME
|
38
|
-
|
39
|
-
|
40
|
-
def exec(cmd, capture = false)
|
41
|
-
puts "Running `#{cmd}`" if SHOW_COMMANDS
|
42
|
-
if capture
|
43
|
-
output = %x[#{cmd}]
|
44
|
-
else
|
45
|
-
system cmd
|
46
|
-
end
|
47
|
-
|
48
|
-
raise "Failed to execute: `#{cmd}`" unless $?.success?
|
49
|
-
output
|
50
|
-
end
|
51
|
-
|
52
|
-
# -----------
|
53
|
-
# Create global gems data volume to cache gems for this version of ruby
|
54
|
-
#
|
55
|
-
# Docker::Container.create('name' => 'foo-gems-2.2.2', 'Image' => 'busybox', 'Mounts' => [ { 'Destination' => '/gems/2.2.2' } ])
|
56
|
-
#
|
57
|
-
require 'docker'
|
58
|
-
begin
|
59
|
-
Docker::Container.get(GEMS_VOLUME_NAME)
|
60
|
-
puts "Gem data volume container #{GEMS_VOLUME_NAME} already exists."
|
61
|
-
rescue Docker::Error::NotFoundError => e
|
62
|
-
|
63
|
-
exec "docker create -v #{GEMS_VOLUME_PATH} --name #{GEMS_VOLUME_NAME} busybox"
|
64
|
-
puts "Gem data volume container #{GEMS_VOLUME_NAME} created."
|
65
|
-
end
|
66
|
-
# gems_container.streaming_logs(stdout: true) { |stream, chunk| puts "#{GEMS_VOLUME_NAME}: #{chunk}" }
|
67
|
-
|
68
|
-
# Delete old docker compose files
|
69
|
-
exec 'rm docker-compose-build-*.yml' rescue ''
|
70
|
-
|
71
|
-
# Read docker-compose.yml and rewrite with interpolated variables and BUILD_NAME
|
72
|
-
COMPOSE_FILENAME = "docker-compose-build-#{BUILD_NAME}.yml"
|
73
|
-
compose_config = Docker::Rails::ComposeConfig.interpolate_file(COMPOSE_FILENAME)
|
74
|
-
|
75
|
-
# convenience to execute docker-compose with file and project params
|
76
|
-
def exec_compose(cmd, capture = false)
|
77
|
-
exec("docker-compose -f #{COMPOSE_FILENAME} -p #{BUILD_NAME} #{cmd}", capture)
|
78
|
-
end
|
79
|
-
|
80
|
-
# service_name i.e. 'db' or 'web'
|
81
|
-
def get_container_name(service_name)
|
82
|
-
output = exec_compose "ps #{service_name}", true
|
83
|
-
# puts "get_container(#{service_name}): \n#{output}"
|
84
|
-
output =~ /^(\w+)/ # grab the name, only thing that is at the start of the line
|
85
|
-
$1
|
86
|
-
end
|
87
|
-
|
88
|
-
def up(service_name, options = '')
|
89
|
-
exec_compose "up #{options} #{service_name}"
|
90
|
-
container_name = get_container_name(service_name)
|
91
|
-
puts "#{service_name}: container_name #{container_name}"
|
92
|
-
|
93
|
-
container = Docker::Container.get(container_name)
|
94
|
-
# container.streaming_logs(stdout: true) { |stream, chunk| puts "#{service_name}: #{chunk}" }
|
95
|
-
# puts container
|
96
|
-
|
97
|
-
[container, container_name]
|
98
|
-
end
|
99
|
-
|
100
|
-
def rm_v(service_name)
|
101
|
-
exec_compose "rm -v --force #{service_name}"
|
102
|
-
end
|
103
|
-
|
104
|
-
def stop(service_name)
|
105
|
-
exec_compose "stop #{service_name}"
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
# make sure we are built
|
110
|
-
exec_compose 'build'
|
111
|
-
|
112
|
-
begin
|
113
|
-
# Start the db container
|
114
|
-
up('db', '-d')
|
115
|
-
|
116
|
-
# Start the web container
|
117
|
-
up('web')
|
118
|
-
|
119
|
-
ensure
|
120
|
-
puts "\n\n\n\nStopping containers..."
|
121
|
-
puts '-----------------------------'
|
122
|
-
compose_config.configuration.each_key do |service_name|
|
123
|
-
stop(service_name)
|
124
|
-
end
|
125
|
-
puts "\nDone."
|
126
|
-
|
127
|
-
puts "\n\nRemoving container volumes..."
|
128
|
-
puts '-----------------------------'
|
129
|
-
compose_config.configuration.each_key do |service_name|
|
130
|
-
rm_v(service_name)
|
131
|
-
end
|
132
|
-
puts "\nDone."
|
133
|
-
puts "\n\n\n"
|
134
|
-
|
135
|
-
# cleanup build interpolated docker-compose.yml
|
136
|
-
# File.delete COMPOSE_FILENAME if File.exists? COMPOSE_FILENAME
|
137
|
-
|
138
|
-
system 'docker ps -a'
|
139
|
-
end
|
9
|
+
Docker::Rails::CLI::Main.start( ARGV )
|