docker-rails 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8076e4ce6d1d20d727afadb4c99e5b9e57c18e21
4
- data.tar.gz: 235f58b8be4f973954bbad1055df04b7bfb2a523
3
+ metadata.gz: 796f9a53d45a20066b265a383d0e649c69f3a870
4
+ data.tar.gz: c265056920b6b21936b3726b780ceb08b28875b3
5
5
  SHA512:
6
- metadata.gz: 92189a1adf213f3cbb9def7fc31e95819c251c7b2a2e196add0971ce97bcc1c733d9af9154a8597d28eb03518fda597627df3418421e0b1d242899afe05e28ed
7
- data.tar.gz: 5f977d58eebb066ce2a7717000dc60d6836010e55633dcd4b07e74f5ee61b48be34a417479e02186d4656a8df0f34775c7663dfa08630624cea6ae9e2e795aa9
6
+ metadata.gz: 880934be3caa2524812e4ddf8a18f089cf1333473549c59b49919fd4917912ddc27a93a1fbada92d5b3d5d03c33606163260bfaed647a19817fd50503fb82f0f
7
+ data.tar.gz: e8c352b19260fc47ace95a562f66a72d43df67dd622f83a50cd23f605e668bd23097a93d713a3cda9d6db242c2957c8d7235e193e21411a4873e874e3f4ad782
data/README.md CHANGED
@@ -6,31 +6,39 @@
6
6
  A simplified pattern to execute rails applications within Docker (with a CI build emphasis).
7
7
 
8
8
  ## Features
9
- - Provides individual functions for development/test usage, or a full workflow for CI usage (with automated container, volume, and image cleanup).
9
+ - DRY declarative `docker-rails.yml` allowing multiple environments to be defined with an inherited docker `compose` configuration
10
+ - Provides individual convenience functions `up | bash | stop | cleanup` to easily work with target environment (even in a concurrent situation)
11
+ - Full workflow for CI usage with automated container, volume, and image cleanup.
10
12
  - Automated cached global gems data volume based on ruby version
11
- - DRY declarative `docker-rails.yml` allowing multiple environments to be defined with an inherited `docker-compose` configuration
12
- - Interpolates `docker-compose.yml` making CI builds much easier
13
+ - Interpolates variables `docker-compose.yml` making CI builds much easier
13
14
  - DB check CLI function provided for docker-compose `command` to check if db is ready
14
15
 
15
16
  ## Usage
16
17
 
17
18
  ```bash
18
19
  Commands:
19
- docker-rails ci <build_name> <environment_name> # Execute the works, everything with cleanup included i.e. bundle exec docker-rails ci 222 test
20
- docker-rails compose <build_name> <environment_name> # Writes a resolved docker-compose.yml file
21
- docker-rails db_check <db> # Runs db_check
22
- docker-rails gems_volume <command> # Gems volume management
23
- docker-rails help [COMMAND] # Describe available commands or one specific command
24
- docker-rails rm_compose # Remove generated docker_compose file
25
- docker-rails rm_dangling # Remove danging images
26
- docker-rails rm_volumes <build_name> <environment_name> # Stop all running containers and remove corresponding volumes for the given build_name/environment_name
27
- docker-rails show_all_containers # Show all remaining containers regardless of state
28
- docker-rails stop <build_name> <environment_name> # Stop all running containers for the given build_name/environment_name
29
- docker-rails up <build_name> <environment_name> # Up the docker-compose configuration for the given build_name/environment_name
20
+ docker-rails bash <target> <service_name> # Open a bash shell to a running container e.g. bundle exec docker-rails bash --build=222 development db
21
+ docker-rails ci <target> # Execute the works, everything with cleanup included e.g. bundle exec docker-rails ci --build=222 test
22
+ 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
23
+ docker-rails compose <target> # Writes a resolved docker-compose.yml file e.g. bundle exec docker-rails compose --build=222 test
24
+ docker-rails db_check <db> # Runs db_check e.g. bundle exec docker-rails db_check mysql
25
+ docker-rails gems_volume <command> # Gems volume management e.g. bundle exec docker-rails gems_volume create
26
+ docker-rails help [COMMAND] # Describe available commands or one specific command
27
+ docker-rails ps <target> # List containers for the target compose configuration e.g. bundle exec docker-rails ps --build=222 development
28
+ docker-rails ps_all # List all remaining containers regardless of state e.g. bundle exec docker-rails ps_all
29
+ docker-rails rm_compose # Remove generated docker_compose file e.g. bundle exec docker-rails rm_compose --build=222 development
30
+ docker-rails rm_dangling # Remove danging images e.g. bundle exec docker-rails rm_dangling
31
+ docker-rails rm_volumes <target> # Stop all running containers and remove corresponding volumes for the given build/target e.g. bundle exec docker-rails rm_volumes --build=222 development
32
+ docker-rails stop <target> # Stop all running containers for the given build/target e.g. bundle exec docker-rails stop --build=222 development
33
+ docker-rails up <target> # Up the docker-compose configuration for the given build/target. Use -d for detached mode. e.g. bundle exec docker-rails up -d --build=222 test
34
+
35
+ Options:
36
+ -b, [--build=BUILD] # Build name e.g. 123
37
+ # Default: 1
30
38
  ```
31
39
 
32
40
  ## Work in progress - contributions welcome
33
- Open to pull requests. It can be expanded to suit many different configurations.
41
+ Open to pull requests. Open to refactoring. It can be expanded to suit many different configurations.
34
42
 
35
43
  TODO:
36
44
  - **Permissions** - [Shared volume for project has files written as root](https://github.com/alienfast/docker-rails/issues/5)
@@ -77,7 +85,7 @@ ENV DEBIAN_FRONTEND newt
77
85
  ### 2. Add a docker-rails.yml
78
86
 
79
87
  Environment variables will be interpolated, so feel free to use them.
80
- Below shows an example with all of the environments `development | test | parallel_tests | staging` to show reuse of the primary `docker-compose' configuration.
88
+ Below shows an example with all of the environments `development | test | parallel_tests | staging` to show reuse of the primary `compose` configuration.
81
89
 
82
90
  ```yaml
83
91
  verbose: true
@@ -224,12 +232,12 @@ compose:
224
232
 
225
233
  volumes_from:
226
234
  # Mount the gems data volume container for cached bundler gem files
227
- - #{GEMS_VOLUME_NAME}
235
+ - #{DOCKER_RAILS_GEMS_VOLUME_NAME}
228
236
 
229
237
  # https://docs.docker.com/v1.6/docker-compose/cli/#environment-variables
230
238
  environment:
231
239
  # Tell bundler where to get the files
232
- - GEM_HOME=#{GEMS_VOLUME_PATH}
240
+ - GEM_HOME=#{DOCKER_RAILS_GEMS_VOLUME_PATH}
233
241
 
234
242
  db:
235
243
  # https://github.com/docker-library/docs/tree/master/mysql
data/lib/docker/rails.rb CHANGED
@@ -8,6 +8,8 @@ end
8
8
  require 'thor'
9
9
  require 'docker'
10
10
 
11
+ require 'docker/rails/core_ext/hash'
12
+
11
13
  require 'docker/rails/config'
12
14
  require 'docker/rails/compose_config'
13
15
  require 'docker/rails/app'
@@ -3,15 +3,15 @@ module Docker
3
3
  require 'singleton'
4
4
  class App
5
5
  include Singleton
6
- attr_reader :config, :compose_config, :ruby_version, :build_name, :environment_name, :gems_volume_path, :gems_volume_name, :compose_filename
6
+ attr_reader :config, :compose_config, :ruby_version, :build, :target, :gems_volume_path, :gems_volume_name, :compose_filename
7
7
 
8
8
  class << self
9
- def configured(build_name, environment_name)
9
+ def configured(target, options)
10
10
  app = App.instance
11
11
  if app.is_configured?
12
- puts "Already configured"
12
+ # puts "Already configured"
13
13
  else
14
- app.configure(build_name: build_name, environment_name: environment_name)
14
+ app.configure(Thor::CoreExt::HashWithIndifferentAccess.new(target: target).merge(options))
15
15
  end
16
16
  app
17
17
  end
@@ -23,12 +23,12 @@ module Docker
23
23
  end
24
24
 
25
25
  def configure(options)
26
- ENV['BUILD_NAME'] = @build_name = options[:build_name]
27
- @environment_name = options[:environment_name]
26
+ ENV['DOCKER_RAILS_BUILD'] = @build = options[:build]
27
+ @target = options[:target]
28
28
 
29
29
  # load the docker-rails.yml
30
30
  @config = Docker::Rails::Config.new
31
- @config.load!(@environment_name)
31
+ @config.load!(@target)
32
32
 
33
33
  @is_configured = true
34
34
  end
@@ -39,7 +39,7 @@ module Docker
39
39
 
40
40
  def compose
41
41
  # Write a docker-compose.yml with interpolated variables
42
- @compose_filename = compose_filename_from @build_name, @environment_name
42
+ @compose_filename = compose_filename_from @build, @target
43
43
 
44
44
  rm_compose
45
45
 
@@ -59,9 +59,14 @@ module Docker
59
59
  (exec before_command unless before_command.nil?) #unless skip? :before_command
60
60
  end
61
61
 
62
- def exec_up
62
+ def exec_up(options = '')
63
63
  # Run the compose configuration
64
- exec_compose 'up' #unless skip? :up
64
+ exec_compose 'up', false, options #unless skip? :up
65
+ end
66
+
67
+ def exec_ps
68
+ # Run the compose configuration
69
+ exec_compose 'ps'
65
70
  end
66
71
 
67
72
  def exec_stop
@@ -95,6 +100,12 @@ module Docker
95
100
  system 'docker ps -a'
96
101
  end
97
102
 
103
+ def exec_bash(service_name)
104
+ # docker exec -it 222_db_1 bash
105
+ container_name = get_container_name(service_name)
106
+ exec "docker exec -it #{container_name} bash"
107
+ end
108
+
98
109
  protected
99
110
 
100
111
  def exec(cmd, capture = false)
@@ -110,8 +121,8 @@ module Docker
110
121
  end
111
122
 
112
123
  # convenience to execute docker-compose with file and project params
113
- def exec_compose(cmd, capture = false)
114
- exec("docker-compose -f #{@compose_filename} -p #{App.instance.build_name} #{cmd}", capture)
124
+ def exec_compose(cmd, capture = false, options = '')
125
+ exec("docker-compose -f #{@compose_filename} -p #{@build} #{cmd} #{options}", capture)
115
126
  end
116
127
 
117
128
  # service_name i.e. 'db' or 'web'
@@ -157,8 +168,8 @@ module Docker
157
168
 
158
169
  def set_gems_volume_vars
159
170
  # Set as variable for interpolation
160
- ENV['GEMS_VOLUME_PATH'] = @gems_volume_path = "/gems/#{@ruby_version}"
161
- ENV['GEMS_VOLUME_NAME'] = @gems_volume_name = "gems-#{@ruby_version}"
171
+ ENV['DOCKER_RAILS_GEMS_VOLUME_PATH'] = @gems_volume_path = "/gems/#{@ruby_version}"
172
+ ENV['DOCKER_RAILS_GEMS_VOLUME_NAME'] = @gems_volume_name = "gems-#{@ruby_version}"
162
173
  end
163
174
 
164
175
  def discover_ruby_version
@@ -168,8 +179,8 @@ module Docker
168
179
  end
169
180
 
170
181
  # accessible so that we can delete patterns
171
- def compose_filename_from(build_name, environment_name)
172
- "docker-compose-build-#{build_name}-#{environment_name}.yml"
182
+ def compose_filename_from(build, target)
183
+ "docker-compose-#{target}-#{build}.yml"
173
184
  end
174
185
  end
175
186
  end
@@ -6,9 +6,9 @@ module Docker
6
6
  default_task :help
7
7
 
8
8
  desc 'create', 'Create a gem volume'
9
- def create(build_name = nil, environment_name = nil)
9
+ def create(target = nil)
10
10
  # Create global gems data volume to cache gems for this version of ruby
11
- app = App.configured(build_name, environment_name)
11
+ app = App.configured(target, options)
12
12
  begin
13
13
  Docker::Container.get(app.gems_volume_name)
14
14
  puts "Gem data volume container #{app.gems_volume_name} already exists."
@@ -4,112 +4,133 @@ module Docker
4
4
  class Main < Thor
5
5
  # default_task :help
6
6
 
7
- desc 'db_check <db>', 'Runs db_check'
8
- subcommand 'db_check', Docker::Rails::CLI::DbCheck
7
+ class_option :build, aliases: ['-b'], type: :string, desc: 'Build name e.g. 123', default: '1'
9
8
 
9
+ desc 'db_check <db>', 'Runs db_check e.g. bundle exec docker-rails db_check mysql'
10
+ subcommand 'db_check', Docker::Rails::CLI::DbCheck
10
11
 
11
- desc 'gems_volume <command>', 'Gems volume management'
12
+ desc 'gems_volume <command>', 'Gems volume management e.g. bundle exec docker-rails gems_volume create'
12
13
  subcommand 'gems_volume', Docker::Rails::CLI::GemsVolume
13
14
 
14
-
15
- desc 'ci <build_name> <environment_name>', 'Execute the works, everything with cleanup included i.e. bundle exec docker-rails ci 222 test'
15
+ desc 'ci <target>', 'Execute the works, everything with cleanup included e.g. bundle exec docker-rails ci --build=222 test'
16
16
  long_desc <<-D
17
17
 
18
- `ci` will run the targeted environment_name with the given build number then cleanup everything upon completion.
18
+ `ci` will run the target with the given build (-b) number then cleanup everything upon completion.
19
19
  While it is named `ci`, there is no harm in using this for other environments as long as you understand that volumes
20
20
  and remaining dangling images will be cleaned up upon completion.
21
21
  D
22
22
 
23
- def ci(build_name, environment_name)
23
+ def ci(target)
24
+ # init singleton with full options
25
+ App.configured(target, options)
26
+
24
27
  invoke :compose
25
- invoke CLI::GemsVolume, :create
28
+ invoke CLI::GemsVolume, :create, [target], options
26
29
  invoke :before
27
30
  begin
28
31
  invoke :up
29
32
  ensure
30
- invoke :stop
31
- invoke :rm_volumes
32
- invoke :rm_compose
33
- invoke :rm_dangling
34
- invoke :show_all_containers
33
+ invoke :cleanup
35
34
  end
36
35
  end
37
36
 
38
- desc 'compose <build_name> <environment_name>', 'Writes a resolved docker-compose.yml file'
39
-
40
- def compose(build_name, environment_name)
41
- App.configured(build_name, environment_name).compose
37
+ desc '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'
38
+ def cleanup(target)
39
+ invoke :stop
40
+ invoke :rm_volumes
41
+ invoke :rm_compose
42
+ invoke :rm_dangling
43
+ invoke :ps_all
42
44
  end
43
45
 
44
- desc 'before <build_name> <environment_name>', 'Invoke before_command', hide: true
46
+ desc 'up <target>', 'Up the docker-compose configuration for the given build/target. Use -d for detached mode. e.g. bundle exec docker-rails up -d --build=222 test'
45
47
 
46
- def before(build_name, environment_name)
47
- invoke :compose
48
- App.configured(build_name, environment_name).exec_before_command
48
+ option :detached, aliases: ['-d'], type: :boolean, desc: 'Detached mode: Run containers in the background'
49
+
50
+ def up(target)
51
+ # init singleton with full options
52
+ app = App.configured(target, options)
53
+ base_options = options.except(:detached)
54
+
55
+ invoke CLI::GemsVolume, :create, [target], base_options
56
+ invoke :before, [target], base_options
57
+
58
+ compose_options = ''
59
+ compose_options = '-d' if options[:detached]
60
+
61
+ app.exec_up(compose_options)
49
62
  end
50
63
 
51
- desc 'up <build_name> <environment_name>', 'Up the docker-compose configuration for the given build_name/environment_name'
64
+ desc 'compose <target>', 'Writes a resolved docker-compose.yml file e.g. bundle exec docker-rails compose --build=222 test'
52
65
 
53
- def up(build_name, environment_name)
66
+ def compose(target)
67
+ App.configured(target, options).compose
68
+ end
54
69
 
55
- invoke CLI::GemsVolume, :create
56
- invoke :before
57
- App.configured(build_name, environment_name).exec_up
70
+ desc 'before <target>', 'Invoke before_command', hide: true
71
+
72
+ def before(target)
73
+ invoke :compose, [target]
74
+ App.configured(target, options).exec_before_command
58
75
  end
59
76
 
60
- desc 'stop <build_name> <environment_name>', 'Stop all running containers for the given build_name/environment_name'
61
77
 
62
- def stop(build_name, environment_name)
78
+ desc 'stop <target>', 'Stop all running containers for the given build/target e.g. bundle exec docker-rails stop --build=222 development'
79
+
80
+ def stop(target)
63
81
  invoke :compose
64
- App.configured(build_name, environment_name).exec_stop
82
+ App.configured(target, options).exec_stop
65
83
  end
66
84
 
67
- desc 'rm_volumes <build_name> <environment_name>', 'Stop all running containers and remove corresponding volumes for the given build_name/environment_name'
85
+ desc 'rm_volumes <target>', 'Stop all running containers and remove corresponding volumes for the given build/target e.g. bundle exec docker-rails rm_volumes --build=222 development'
68
86
 
69
- def rm_volumes(build_name, environment_name)
87
+ def rm_volumes(target)
70
88
  invoke :stop
71
- App.configured(build_name, environment_name).exec_remove_volumes
89
+ App.configured(target, options).exec_remove_volumes
72
90
  end
73
91
 
74
- desc 'rm_compose', 'Remove generated docker_compose file'
92
+ desc 'rm_compose', 'Remove generated docker_compose file e.g. bundle exec docker-rails rm_compose --build=222 development'
75
93
 
76
- def rm_compose(build_name = nil, environment_name = nil)
94
+ def rm_compose(build = nil, target = nil)
77
95
  App.instance.rm_compose
78
96
  end
79
97
 
80
- desc 'rm_dangling', 'Remove danging images'
98
+ desc 'rm_dangling', 'Remove danging images e.g. bundle exec docker-rails rm_dangling'
81
99
 
82
- def rm_dangling(build_name = nil, environment_name = nil)
100
+ def rm_dangling(build = nil, target = nil)
83
101
  App.instance.rm_dangling
84
102
  end
85
103
 
86
- desc 'show_all_containers', 'Show all remaining containers regardless of state'
104
+ desc 'ps <target>', 'List containers for the target compose configuration e.g. bundle exec docker-rails ps --build=222 development'
105
+
106
+ def ps(target)
107
+ invoke :compose
108
+ App.configured(target, options).exec_ps
109
+ end
110
+
111
+ desc 'ps_all', 'List all remaining containers regardless of state e.g. bundle exec docker-rails ps_all'
87
112
 
88
- def show_all_containers(build_name = nil, environment_name = nil)
113
+ def ps_all(build = nil, target = nil)
89
114
  App.instance.show_all_containers
90
115
  end
91
116
 
117
+ desc 'bash <target> <service_name>', 'Open a bash shell to a running container e.g. bundle exec docker-rails bash --build=222 development db'
118
+
119
+ def bash(target, service_name)
120
+ # init singleton with full options
121
+ app = App.configured(target, options)
122
+
123
+ invoke :compose, [target], []
124
+
125
+ app.exec_bash(service_name)
126
+ end
127
+
128
+
129
+ protected
92
130
 
93
- # desc 'hello NAME', 'This will greet you'
94
- # long_desc <<-HELLO_WORLD
95
- #
96
- # `hello NAME` will print out a message to the person of your choosing.
97
- #
98
- # Brian Kernighan actually wrote the first "Hello, World!" program
99
- # as part of the documentation for the BCPL programming language
100
- # developed by Martin Richards. BCPL was used while C was being
101
- # developed at Bell Labs a few years before the publication of
102
- # Kernighan and Ritchie's C book in 1972.
103
- #
104
- # http://stackoverflow.com/a/12785204
105
- # HELLO_WORLD
106
- #
107
- # option :upcase
108
- #
109
- # def hello(name)
110
- # greeting = "Hello, #{name}"
111
- # greeting.upcase! if options[:upcase]
112
- # puts greeting
131
+ # invoke with an empty set of options
132
+ # def invoke_new(command, options=[])
133
+ # invoke command, nil, options
113
134
  # end
114
135
  end
115
136
  end
@@ -0,0 +1,21 @@
1
+ class Hash
2
+ # Returns a hash that includes everything but the given keys.
3
+ # hash = { a: true, b: false, c: nil}
4
+ # hash.except(:c) # => { a: true, b: false}
5
+ # hash # => { a: true, b: false, c: nil}
6
+ #
7
+ # This is useful for limiting a set of parameters to everything but a few known toggles:
8
+ # @person.update(params[:person].except(:admin))
9
+ def except(*keys)
10
+ dup.except!(*keys)
11
+ end
12
+
13
+ # Replaces the hash without the given keys.
14
+ # hash = { a: true, b: false, c: nil}
15
+ # hash.except!(:c) # => { a: true, b: false}
16
+ # hash # => { a: true, b: false }
17
+ def except!(*keys)
18
+ keys.each { |key| delete(key) }
19
+ self
20
+ end
21
+ end
@@ -1,5 +1,5 @@
1
1
  module Docker
2
2
  module Rails
3
- VERSION = '0.1.1'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
@@ -141,12 +141,12 @@ compose:
141
141
 
142
142
  volumes_from:
143
143
  # Mount the gems data volume container for cached bundler gem files
144
- - #{GEMS_VOLUME_NAME}
144
+ - #{DOCKER_RAILS_GEMS_VOLUME_NAME}
145
145
 
146
146
  # https://docs.docker.com/v1.6/compose/cli/#environment-variables
147
147
  environment:
148
148
  # Tell bundler where to get the files
149
- - GEM_HOME=#{GEMS_VOLUME_PATH}
149
+ - GEM_HOME=#{DOCKER_RAILS_GEMS_VOLUME_PATH}
150
150
 
151
151
  db:
152
152
  # https://github.com/docker-library/docs/tree/master/mysql
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: docker-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Ross
@@ -148,6 +148,7 @@ files:
148
148
  - lib/docker/rails/cli/main.rb
149
149
  - lib/docker/rails/compose_config.rb
150
150
  - lib/docker/rails/config.rb
151
+ - lib/docker/rails/core_ext/hash.rb
151
152
  - lib/docker/rails/version.rb
152
153
  - spec/docker/rails/config_spec.rb
153
154
  - spec/docker/rails/docker-rails.yml