docker-rails 0.0.1 → 0.0.2
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/README.md +48 -45
- data/bin/docker-rails +64 -73
- data/bin/docker-rails-db-check +38 -0
- data/docker-rails.gemspec +1 -0
- data/lib/docker/rails/compose_config.rb +1 -0
- data/lib/docker/rails/version.rb +1 -1
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6052b133ad5e1cdb58cb484baa077de133994fdc
|
4
|
+
data.tar.gz: 33124a13ab2327fbc1dfe2ae28fed2542f2656f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9fd4e6b3e13e76beb5f914b9944860101f3ccb7c36792de0de1525372396c719fbff75c4c65d6144b7d3075302c0bb0be2d118cf31ba70746168cc1c2007e19
|
7
|
+
data.tar.gz: 30f5cf9246f18910399c7eb937fdc90ed2816243b1386a0af47c68ced889258f1452a2ede03e731e55d2034aceeca4020d3bc92352bccbc41e822c29ac8e4b0c
|
data/README.md
CHANGED
@@ -1,21 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# docker-rails
|
2
2
|
|
3
3
|
A simplified pattern to execute rails applications within Docker (with a CI build emphasis).
|
4
4
|
|
5
|
-
Features
|
5
|
+
## Features
|
6
6
|
- cached global bundler data volume (automatic) based on ruby version
|
7
7
|
- interpolates `docker-compose.yml` making CI builds much easier
|
8
|
-
- starts `db` container first
|
9
|
-
-
|
8
|
+
- starts `db` container first and continues with `web`
|
9
|
+
- function provided for docker-compose `command` to check if db is ready, currently executed as script `docker-rails-db-check`
|
10
|
+
- cleans up all containers **and** volumes once completed
|
10
11
|
|
11
12
|
|
12
|
-
|
13
|
+
## Work in progress - contributions welcome
|
13
14
|
Open to pull requests, while this starts off as one-person's environment, it can be expanded to suit many different configurations.
|
14
15
|
|
15
|
-
|
16
|
-
- remove hardcoded ip for db ip resolution
|
16
|
+
TODO:
|
17
17
|
- remove or default hardcoded BUILD_NAME
|
18
|
-
- expand to different db status detection as needed
|
18
|
+
- expand to different db status detection as needed e.g. postgres
|
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`.
|
21
|
+
|
19
22
|
|
20
23
|
## Installation
|
21
24
|
|
@@ -43,8 +46,7 @@ ENV DEBIAN_FRONTEND noninteractive
|
|
43
46
|
# For building, nokogiri support, capybara-webkit, mysql client
|
44
47
|
# Clean up APT when done.
|
45
48
|
RUN apt-get update -qq && \
|
46
|
-
apt-get install -qy build-essential libxml2-dev libxslt1-dev \
|
47
|
-
g++ qt5-default libqt5webkit5-dev xvfb libmysqlclient-dev && \
|
49
|
+
apt-get install -qy build-essential libxml2-dev libxslt1-dev g++ qt5-default libqt5webkit5-dev xvfb libmysqlclient-dev && \
|
48
50
|
|
49
51
|
# cleanup
|
50
52
|
apt-get clean && \
|
@@ -56,7 +58,6 @@ ENV DEBIAN_FRONTEND newt
|
|
56
58
|
|
57
59
|
ADD . /project
|
58
60
|
WORKDIR /project
|
59
|
-
RUN ["chmod", "+x", "/project/scripts/*"]
|
60
61
|
```
|
61
62
|
|
62
63
|
### 2. Add a docker-compose.yml
|
@@ -66,8 +67,36 @@ Environment variables will be interpolated, so feel free to use them.
|
|
66
67
|
```yaml
|
67
68
|
web:
|
68
69
|
build: .
|
70
|
+
# e.g. engine dummy, otherwise omit.
|
69
71
|
working_dir: /project/spec/dummy
|
70
|
-
command:
|
72
|
+
command: >
|
73
|
+
bash -c
|
74
|
+
"
|
75
|
+
echo 'Bundling gems'
|
76
|
+
&& bundle install --jobs 4 --retry 3
|
77
|
+
|
78
|
+
&& echo 'Generating Spring binstubs'
|
79
|
+
&& bundle exec spring binstub --all
|
80
|
+
|
81
|
+
&& echo 'Clearing logs'
|
82
|
+
&& bin/rake log:clear
|
83
|
+
|
84
|
+
&& echo 'Check and wait for database connection'
|
85
|
+
&& bundle exec docker-rails-db-check
|
86
|
+
|
87
|
+
&& echo 'Setting up new db if one doesn't exist'
|
88
|
+
&& bin/rake db:version || { bundle exec rake db:setup; }
|
89
|
+
|
90
|
+
&& echo 'Removing contents of tmp dirs'
|
91
|
+
&& bin/rake tmp:clear
|
92
|
+
|
93
|
+
&& echo 'Starting app server'
|
94
|
+
&& bundle exec rails s -p 3000
|
95
|
+
|
96
|
+
&& echo 'Setup and start foreman'
|
97
|
+
&& gem install foreman
|
98
|
+
&& foreman start
|
99
|
+
"
|
71
100
|
ports:
|
72
101
|
- "3000:3000"
|
73
102
|
links:
|
@@ -83,6 +112,10 @@ web:
|
|
83
112
|
# Tell bundler where to get the files
|
84
113
|
- GEM_HOME=#{GEMS_VOLUME_PATH}
|
85
114
|
|
115
|
+
elasticsearch:
|
116
|
+
image: library/elasticsearch:1.7
|
117
|
+
ports:
|
118
|
+
- "9200:9200"
|
86
119
|
db:
|
87
120
|
image: library/mysql:5.7.6
|
88
121
|
ports:
|
@@ -91,43 +124,13 @@ db:
|
|
91
124
|
- MYSQL_ALLOW_EMPTY_PASSWORD=true
|
92
125
|
```
|
93
126
|
|
94
|
-
### 3.
|
95
|
-
|
96
|
-
TODO: verify a good sample
|
97
|
-
|
98
|
-
```bash
|
99
|
-
#!/usr/bin/env bash
|
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"
|
108
|
-
bin/rake log:clear
|
109
|
-
|
110
|
-
echo "Setting up new db if one doesn't exist"
|
111
|
-
bin/rake db:version || { bundle exec rake db:setup; }
|
112
|
-
|
113
|
-
echo "Removing contents of tmp dirs"
|
114
|
-
bin/rake tmp:clear
|
115
|
-
|
116
|
-
echo "Starting app server"
|
117
|
-
bundle exec rails s -p 3000
|
118
|
-
|
119
|
-
# or use foreman
|
120
|
-
# gem install foreman
|
121
|
-
# foreman start
|
122
|
-
```
|
123
|
-
|
124
|
-
### 4. Run it
|
127
|
+
### 3. Run it
|
125
128
|
|
126
129
|
`bundle exec docker-rails`
|
127
130
|
|
128
|
-
###
|
131
|
+
### 4. Submit pull requests!
|
129
132
|
|
130
|
-
This is starting off simple, but again, we welcome pulls to make this and the process of using docker for rails
|
133
|
+
This is starting off simple, but again, we welcome pulls to make this and the process of using docker for rails even easier.
|
131
134
|
|
132
135
|
|
133
136
|
## Contributing
|
data/bin/docker-rails
CHANGED
@@ -11,13 +11,19 @@
|
|
11
11
|
# https://docs.docker.com/reference/api/docker_remote_api_v1.20
|
12
12
|
|
13
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
|
+
|
14
20
|
# enable local usage from cloned repo
|
15
21
|
root = File.expand_path('../..', __FILE__)
|
16
22
|
$LOAD_PATH << "#{root}/lib" if File.exist?("#{root}/Gemfile")
|
17
23
|
|
18
24
|
require 'docker/rails'
|
19
25
|
|
20
|
-
BUILD_NAME = '
|
26
|
+
BUILD_NAME = '119' # temp should be passed in
|
21
27
|
ENV['BUILD_NAME'] = BUILD_NAME
|
22
28
|
|
23
29
|
# Discover ruby version from the Dockerfile image
|
@@ -30,6 +36,19 @@ GEMS_VOLUME_NAME = "gems-#{BUILD_RUBY_VERSION}"
|
|
30
36
|
ENV['GEMS_VOLUME_PATH'] = GEMS_VOLUME_PATH
|
31
37
|
ENV['GEMS_VOLUME_NAME'] = GEMS_VOLUME_NAME
|
32
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
|
+
|
33
52
|
# -----------
|
34
53
|
# Create global gems data volume to cache gems for this version of ruby
|
35
54
|
#
|
@@ -37,112 +56,84 @@ ENV['GEMS_VOLUME_NAME'] = GEMS_VOLUME_NAME
|
|
37
56
|
#
|
38
57
|
require 'docker'
|
39
58
|
begin
|
40
|
-
|
59
|
+
Docker::Container.get(GEMS_VOLUME_NAME)
|
41
60
|
puts "Gem data volume container #{GEMS_VOLUME_NAME} already exists."
|
42
61
|
rescue Docker::Error::NotFoundError => e
|
43
|
-
|
62
|
+
|
63
|
+
exec "docker create -v #{GEMS_VOLUME_PATH} --name #{GEMS_VOLUME_NAME} busybox"
|
44
64
|
puts "Gem data volume container #{GEMS_VOLUME_NAME} created."
|
45
65
|
end
|
46
|
-
gems_container.streaming_logs(stdout: true) { |stream, chunk| puts "#{GEMS_VOLUME_NAME}: #{chunk}" }
|
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 ''
|
47
70
|
|
48
71
|
# Read docker-compose.yml and rewrite with interpolated variables and BUILD_NAME
|
49
72
|
COMPOSE_FILENAME = "docker-compose-build-#{BUILD_NAME}.yml"
|
50
73
|
compose_config = Docker::Rails::ComposeConfig.interpolate_file(COMPOSE_FILENAME)
|
51
74
|
|
52
75
|
# convenience to execute docker-compose with file and project params
|
53
|
-
def
|
54
|
-
|
55
|
-
puts "Running `#{cmd}`"
|
56
|
-
output =`#{cmd}`
|
57
|
-
result=$?.success?
|
58
|
-
output
|
76
|
+
def exec_compose(cmd, capture = false)
|
77
|
+
exec("docker-compose -f #{COMPOSE_FILENAME} -p #{BUILD_NAME} #{cmd}", capture)
|
59
78
|
end
|
60
79
|
|
61
80
|
# service_name i.e. 'db' or 'web'
|
62
81
|
def get_container_name(service_name)
|
63
|
-
output =
|
82
|
+
output = exec_compose "ps #{service_name}", true
|
83
|
+
# puts "get_container(#{service_name}): \n#{output}"
|
64
84
|
output =~ /^(\w+)/ # grab the name, only thing that is at the start of the line
|
65
85
|
$1
|
66
86
|
end
|
67
87
|
|
68
|
-
|
69
|
-
|
70
|
-
cmd = "docker inspect --format '{{ .NetworkSettings.IPAddress }}' #{container_name}"
|
71
|
-
puts "Running `#{cmd}`"
|
72
|
-
output = `#{cmd}`
|
73
|
-
result=$?.success?
|
74
|
-
output
|
75
|
-
end
|
76
|
-
|
77
|
-
def up_container(service_name, options = '')
|
78
|
-
xc "up #{options} #{service_name}"
|
88
|
+
def up(service_name, options = '')
|
89
|
+
exec_compose "up #{options} #{service_name}"
|
79
90
|
container_name = get_container_name(service_name)
|
80
91
|
puts "#{service_name}: container_name #{container_name}"
|
81
92
|
|
82
93
|
container = Docker::Container.get(container_name)
|
83
|
-
container.streaming_logs(stdout: true) { |stream, chunk| puts "#{service_name}: #{chunk}" }
|
94
|
+
# container.streaming_logs(stdout: true) { |stream, chunk| puts "#{service_name}: #{chunk}" }
|
84
95
|
# puts container
|
85
96
|
|
86
|
-
|
87
|
-
[container, container_name, ip_address]
|
97
|
+
[container, container_name]
|
88
98
|
end
|
89
99
|
|
90
|
-
def
|
91
|
-
|
92
|
-
container.stop
|
93
|
-
container.delete(force: true)
|
100
|
+
def rm_v(service_name)
|
101
|
+
exec_compose "rm -v --force #{service_name}"
|
94
102
|
end
|
95
103
|
|
96
|
-
|
97
|
-
|
104
|
+
def stop(service_name)
|
105
|
+
exec_compose "stop #{service_name}"
|
106
|
+
end
|
98
107
|
|
99
|
-
# ping db to see if it is ready before continuing
|
100
|
-
require 'rubygems'
|
101
|
-
require 'active_record'
|
102
108
|
|
103
|
-
|
104
|
-
|
105
|
-
LOOP_LIMIT.times do |i|
|
106
|
-
if i == LOOP_LIMIT - 1
|
107
|
-
puts 'Time out waiting for db to be up.'
|
108
|
-
#docker logs --follow=false $DB_CONTAINER
|
109
|
-
break
|
110
|
-
end
|
111
|
-
|
112
|
-
ActiveRecord::Base.establish_connection ({
|
113
|
-
adapter: 'mysql2',
|
114
|
-
# host: db_ip_address,
|
115
|
-
host: '192.168.99.100',
|
116
|
-
port: 3306,
|
117
|
-
username: 'root'})
|
118
|
-
# connected = ActiveRecord::Base.connection_pool.with_connection { |con| con.active? } rescue false
|
119
|
-
connected =
|
120
|
-
begin
|
121
|
-
ActiveRecord::Base.connection_pool.with_connection { |con| con.active? }
|
122
|
-
rescue => e
|
123
|
-
# puts "#{e.class.name}: #{e.message}"
|
124
|
-
false
|
125
|
-
end
|
126
|
-
printf '.'
|
127
|
-
if connected
|
128
|
-
printf 'connected.'
|
129
|
-
break
|
130
|
-
end
|
131
|
-
sleep 1
|
132
|
-
end
|
133
|
-
puts ''
|
109
|
+
# make sure we are built
|
110
|
+
exec_compose 'build'
|
134
111
|
|
112
|
+
begin
|
113
|
+
# Start the db container
|
114
|
+
up('db', '-d')
|
135
115
|
|
136
|
-
# Start the web
|
137
|
-
|
116
|
+
# Start the web container
|
117
|
+
up('web')
|
138
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."
|
139
126
|
|
140
|
-
puts
|
141
|
-
|
142
|
-
|
143
|
-
|
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"
|
144
134
|
|
145
135
|
# cleanup build interpolated docker-compose.yml
|
146
|
-
#
|
136
|
+
# File.delete COMPOSE_FILENAME if File.exists? COMPOSE_FILENAME
|
147
137
|
|
148
|
-
system 'docker ps -a'
|
138
|
+
system 'docker ps -a'
|
139
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# TODO: make docker-rails CLI and put this in the lib, add optional ! method to raise if failed
|
4
|
+
|
5
|
+
# ping db to see if it is ready before continuing
|
6
|
+
require 'rubygems'
|
7
|
+
require 'active_record'
|
8
|
+
require 'mysql2'
|
9
|
+
|
10
|
+
LOOP_LIMIT=60
|
11
|
+
puts "\n"
|
12
|
+
printf 'Waiting for confirmation of db service startup...'
|
13
|
+
LOOP_LIMIT.times do |i|
|
14
|
+
if i == LOOP_LIMIT - 1
|
15
|
+
printf 'failed to connect.'
|
16
|
+
raise 'Failed to connect to db service.'
|
17
|
+
end
|
18
|
+
|
19
|
+
ActiveRecord::Base.establish_connection ({
|
20
|
+
adapter: 'mysql2',
|
21
|
+
host: 'db',
|
22
|
+
port: 3306,
|
23
|
+
username: 'root'})
|
24
|
+
connected =
|
25
|
+
begin
|
26
|
+
ActiveRecord::Base.connection_pool.with_connection { |con| con.active? }
|
27
|
+
rescue => e
|
28
|
+
# puts "#{e.class.name}: #{e.message}"
|
29
|
+
false
|
30
|
+
end
|
31
|
+
printf '.'
|
32
|
+
if connected
|
33
|
+
printf 'connected.'
|
34
|
+
break
|
35
|
+
end
|
36
|
+
sleep 1
|
37
|
+
end
|
38
|
+
puts "\n"
|
data/docker-rails.gemspec
CHANGED
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.0.
|
4
|
+
version: 0.0.2
|
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-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,11 +66,26 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.1.6
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mysql2
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.3.18
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.3.18
|
69
83
|
description: ''
|
70
84
|
email:
|
71
85
|
- kevin.ross@alienfast.com
|
72
86
|
executables:
|
73
87
|
- docker-rails
|
88
|
+
- docker-rails-db-check
|
74
89
|
extensions: []
|
75
90
|
extra_rdoc_files: []
|
76
91
|
files:
|
@@ -82,6 +97,7 @@ files:
|
|
82
97
|
- README.md
|
83
98
|
- Rakefile
|
84
99
|
- bin/docker-rails
|
100
|
+
- bin/docker-rails-db-check
|
85
101
|
- docker-rails.gemspec
|
86
102
|
- lib/docker/rails.rb
|
87
103
|
- lib/docker/rails/compose_config.rb
|