orchestration 0.3.3 → 0.3.4

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.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +1 -1
  3. data/TODO +2 -12
  4. data/config/locales/en.yml +10 -13
  5. data/lib/orchestration/docker_compose/{application_service.rb → app_service.rb} +6 -5
  6. data/lib/orchestration/docker_compose/configuration.rb +69 -0
  7. data/lib/orchestration/docker_compose/database_service.rb +18 -25
  8. data/lib/orchestration/docker_compose/install_generator.rb +113 -0
  9. data/lib/orchestration/docker_compose/mongo_service.rb +15 -5
  10. data/lib/orchestration/docker_compose/nginx_proxy_service.rb +3 -2
  11. data/lib/orchestration/docker_compose/rabbitmq_service.rb +9 -5
  12. data/lib/orchestration/docker_compose.rb +3 -2
  13. data/lib/orchestration/environment.rb +32 -11
  14. data/lib/orchestration/errors.rb +3 -1
  15. data/lib/orchestration/file_helpers.rb +10 -5
  16. data/lib/orchestration/install_generator.rb +38 -51
  17. data/lib/orchestration/services/{application → app}/configuration.rb +5 -5
  18. data/lib/orchestration/services/{application → app}/healthcheck.rb +4 -4
  19. data/lib/orchestration/services/app.rb +13 -0
  20. data/lib/orchestration/services/configuration_base.rb +3 -1
  21. data/lib/orchestration/services/database/adapters/mysql2.rb +19 -0
  22. data/lib/orchestration/services/database/adapters/postgresql.rb +20 -0
  23. data/lib/orchestration/services/database/adapters/sqlite3.rb +4 -0
  24. data/lib/orchestration/services/database/configuration.rb +23 -13
  25. data/lib/orchestration/services/healthcheck_base.rb +1 -1
  26. data/lib/orchestration/services/nginx_proxy/configuration.rb +7 -2
  27. data/lib/orchestration/services.rb +1 -1
  28. data/lib/orchestration/templates/Makefile.erb +99 -40
  29. data/lib/orchestration/templates/application.mk.erb +14 -0
  30. data/lib/orchestration/templates/deploy.mk.erb +34 -0
  31. data/lib/orchestration/templates/docker-compose.override.yml.erb +1 -0
  32. data/lib/orchestration/templates/env.erb +6 -0
  33. data/lib/orchestration/templates/unicorn.rb.erb +1 -1
  34. data/lib/orchestration/terminal.rb +17 -1
  35. data/lib/orchestration/version.rb +1 -1
  36. data/lib/orchestration.rb +2 -1
  37. data/lib/tasks/orchestration.rake +7 -17
  38. metadata +13 -8
  39. data/lib/orchestration/docker_compose/services.rb +0 -59
  40. data/lib/orchestration/services/application.rb +0 -13
@@ -10,14 +10,15 @@ module Orchestration
10
10
  def initialize(*_args)
11
11
  super
12
12
  @env = Environment.new
13
- @terminal ||= Terminal.new
14
13
  @settings = Settings.new(@env.orchestration_configuration_path)
14
+ @terminal = Terminal.new(@settings)
15
+ @docker_compose = DockerCompose::InstallGenerator.new(@env, @terminal)
15
16
  end
16
17
 
17
18
  def orchestration_configuration
18
19
  path = @env.orchestration_configuration_path
19
- ask_setting('docker.username')
20
- ask_setting('docker.repository', @env.default_application_name)
20
+ @terminal.ask_setting('docker.username')
21
+ @terminal.ask_setting('docker.repository', @env.default_app_name)
21
22
  relpath = relative_path(path)
22
23
  return @terminal.write(:create, relpath) unless @settings.exist?
23
24
  return @terminal.write(:update, relpath) if @settings.dirty?
@@ -25,15 +26,16 @@ module Orchestration
25
26
  @terminal.write(:skip, relpath)
26
27
  end
27
28
 
28
- def makefile
29
- environment = { env: @env, wait_commands: wait_commands }
30
- content = template('Makefile', environment)
29
+ def orchestration_makefile
30
+ content = template('Makefile', makefile_environment)
31
31
  path = @env.orchestration_root.join('Makefile')
32
32
  path.exist? ? update_file(path, content) : create_file(path, content)
33
- inject_if_missing(
34
- @env.root.join('Makefile'),
35
- 'include orchestration/Makefile'
36
- )
33
+ end
34
+
35
+ def application_makefile
36
+ path = @env.root.join('Makefile')
37
+ simple_copy('application.mk', path) unless File.exist?(path)
38
+ inject_if_missing(path, 'include orchestration/Makefile')
37
39
  end
38
40
 
39
41
  def dockerfile
@@ -45,7 +47,7 @@ module Orchestration
45
47
  )
46
48
  end
47
49
 
48
- def entrypoint
50
+ def entrypoint_sh
49
51
  content = template('entrypoint.sh')
50
52
  path = orchestration_dir.join('entrypoint.sh')
51
53
  create_file(path, content, overwrite: false)
@@ -54,21 +56,14 @@ module Orchestration
54
56
 
55
57
  def gitignore
56
58
  path = @env.root.join('.gitignore')
57
- entries = %w[.build/ Gemfile Gemfile.lock *.gemspec].map do |entry|
59
+ globs = %w[.build/ .deploy/ Gemfile Gemfile.lock]
60
+ entries = ['deploy.tar'] + globs.map do |entry|
58
61
  "#{@env.orchestration_dir_name}/#{entry}"
59
62
  end
60
63
 
61
64
  ensure_lines_in_file(path, entries)
62
65
  end
63
66
 
64
- def docker_compose
65
- path = @env.orchestration_root.join('docker-compose.yml')
66
- return if File.exist?(path)
67
-
68
- docker_compose = DockerCompose::Services.new(@env, service_configurations)
69
- create_file(path, docker_compose.structure.to_yaml)
70
- end
71
-
72
67
  def unicorn
73
68
  content = template('unicorn.rb')
74
69
  path = @env.root.join('config', 'unicorn.rb')
@@ -79,46 +74,38 @@ module Orchestration
79
74
  simple_copy('yaml.bash', @env.orchestration_root.join('yaml.bash'))
80
75
  end
81
76
 
82
- private
83
-
84
- def t(key)
85
- I18n.t("orchestration.#{key}")
77
+ def env
78
+ simple_copy('env', @env.root.join('.env'), overwrite: false)
86
79
  end
87
80
 
88
- def service_configurations
89
- Hash[
90
- %i[application database mongo rabbitmq nginx_proxy].map do |key|
91
- [key, configuration(key)]
92
- end
93
- ]
81
+ def deploy_mk
82
+ simple_copy('deploy.mk', @env.orchestration_root.join('deploy.mk'))
94
83
  end
95
84
 
96
- def configuration(service)
97
- {
98
- application: Services::Application::Configuration,
99
- database: Services::Database::Configuration,
100
- mongo: Services::Mongo::Configuration,
101
- rabbitmq: Services::RabbitMQ::Configuration,
102
- nginx_proxy: Services::NginxProxy::Configuration
103
- }.fetch(service).new(@env)
85
+ def docker_compose
86
+ @docker_compose.docker_compose_yml
87
+ @docker_compose.docker_compose_test_yml
88
+ @docker_compose.docker_compose_development_yml
89
+ @docker_compose.docker_compose_production_yml
90
+ @docker_compose.docker_compose_override_yml
104
91
  end
105
92
 
106
- def wait_commands
107
- [
108
- configuration(:database).settings.nil? ? nil : 'wait-database',
109
- configuration(:mongo).settings.nil? ? nil : 'wait-mongo',
110
- configuration(:rabbitmq).settings.nil? ? nil : 'wait-rabbitmq',
111
- 'wait-nginx-proxy',
112
- 'wait-application'
113
- ].compact.join(' ')
93
+ private
94
+
95
+ def t(key)
96
+ I18n.t("orchestration.#{key}")
114
97
  end
115
98
 
116
- def ask_setting(setting, default = nil)
117
- return unless @settings.get(setting).nil?
99
+ def makefile_environment
100
+ { env: @env, wait_commands: wait_commands }
101
+ end
118
102
 
119
- @terminal.write(:setup, t("settings.#{setting}.description"))
120
- prompt = t("settings.#{setting}.prompt")
121
- @settings.set(setting, @terminal.read(prompt, default))
103
+ def wait_commands
104
+ %i[test development production].map do |environment|
105
+ @docker_compose.enabled_services(environment).map do |service|
106
+ "wait-#{service}"
107
+ end
108
+ end.flatten.uniq
122
109
  end
123
110
  end
124
111
  end
@@ -2,27 +2,27 @@
2
2
 
3
3
  module Orchestration
4
4
  module Services
5
- module Application
5
+ module App
6
6
  class Configuration
7
7
  include ConfigurationBase
8
8
 
9
- self.service_name = 'application'
9
+ self.service_name = 'app'
10
10
 
11
11
  def initialize(env, service_name = nil)
12
12
  super
13
- @settings = {} # Included for interface consistency; currently unused.
13
+ @settings = {}
14
14
  end
15
15
 
16
16
  def docker_username
17
17
  @env.settings.get('docker.username')
18
18
  end
19
19
 
20
- def application_name
20
+ def app_name
21
21
  @env.settings.get('docker.repository')
22
22
  end
23
23
 
24
24
  def friendly_config
25
- "[#{application_name}] #{host}:#{local_port}"
25
+ "[#{app_name}] #{host}:#{local_port}"
26
26
  end
27
27
 
28
28
  def database_settings
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Orchestration
4
4
  module Services
5
- module Application
5
+ module App
6
6
  class Healthcheck
7
7
  include HealthcheckBase
8
8
 
@@ -14,14 +14,14 @@ module Orchestration
14
14
  end
15
15
 
16
16
  def connection_errors
17
- [Errno::ECONNREFUSED, ApplicationConnectionError]
17
+ [Errno::ECONNREFUSED, AppConnectionError]
18
18
  end
19
19
 
20
20
  private
21
21
 
22
22
  def connection_error(code)
23
- raise ApplicationConnectionError,
24
- I18n.t('orchestration.application.connection_error', code: code)
23
+ raise AppConnectionError,
24
+ I18n.t('orchestration.app.connection_error', code: code)
25
25
  end
26
26
 
27
27
  def connection_error?(code)
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orchestration
4
+ module Services
5
+ module App
6
+ end
7
+ end
8
+ end
9
+
10
+ require 'net/http'
11
+
12
+ require 'orchestration/services/app/configuration'
13
+ require 'orchestration/services/app/healthcheck'
@@ -32,7 +32,9 @@ module Orchestration
32
32
  end
33
33
 
34
34
  def local_port
35
- key = @service_name == 'application' ? 'nginx-proxy' : @service_name
35
+ key = @service_name == 'app' ? 'nginx_proxy' : @service_name
36
+
37
+ return ENV.fetch('LISTEN_PORT', '3000').to_i if key == 'nginx_proxy'
36
38
 
37
39
  @env.docker_compose_config
38
40
  .fetch('services')
@@ -5,6 +5,14 @@ module Orchestration
5
5
  module Database
6
6
  module Adapters
7
7
  class Mysql2
8
+ def name
9
+ 'mysql2'
10
+ end
11
+
12
+ def image
13
+ 'library/mysql'
14
+ end
15
+
8
16
  def credentials
9
17
  {
10
18
  'username' => 'root',
@@ -20,6 +28,17 @@ module Orchestration
20
28
  def default_port
21
29
  3306
22
30
  end
31
+
32
+ def environment
33
+ {
34
+ 'MYSQL_ROOT_PASSWORD' => 'password',
35
+ 'MYSQL_TCP_PORT' => DockerCompose::DatabaseService::PORT.to_s
36
+ }
37
+ end
38
+
39
+ def data_dir
40
+ '/var/lib/mysql'
41
+ end
23
42
  end
24
43
  end
25
44
  end
@@ -5,6 +5,14 @@ module Orchestration
5
5
  module Database
6
6
  module Adapters
7
7
  class Postgresql
8
+ def name
9
+ 'postgresql'
10
+ end
11
+
12
+ def image
13
+ 'library/postgres'
14
+ end
15
+
8
16
  def credentials
9
17
  {
10
18
  'username' => 'postgres',
@@ -20,6 +28,18 @@ module Orchestration
20
28
  def default_port
21
29
  5432
22
30
  end
31
+
32
+ def environment
33
+ {
34
+ 'PGPORT' => DockerCompose::DatabaseService::PORT.to_s,
35
+ 'POSTGRES_PASSWORD' => 'password',
36
+ 'PGDATA' => data_dir
37
+ }
38
+ end
39
+
40
+ def data_dir
41
+ '/var/pgdata'
42
+ end
23
43
  end
24
44
  end
25
45
  end
@@ -5,6 +5,10 @@ module Orchestration
5
5
  module Database
6
6
  module Adapters
7
7
  class Sqlite3
8
+ def name
9
+ 'sqlite3'
10
+ end
11
+
8
12
  def credentials
9
13
  {
10
14
  'username' => '',
@@ -22,24 +22,28 @@ module Orchestration
22
22
  end
23
23
 
24
24
  def friendly_config
25
- adapter = @settings.fetch('adapter')
26
- return "[#{adapter}]" if adapter == 'sqlite3'
25
+ return "[#{@adapter.name}]" if @adapter.name == 'sqlite3'
27
26
 
28
- "[#{adapter}] #{host}:#{local_port}"
27
+ "[#{@adapter.name}] #{host}:#{local_port}"
29
28
  end
30
29
 
31
30
  private
32
31
 
33
32
  def setup
34
- @adapter = adapter_object(base['adapter'])
35
- @settings = base.merge(@adapter.credentials)
36
- .merge(
37
- 'scheme' => base['adapter'],
38
- 'port' => DockerCompose::DatabaseService::PORT
39
- )
33
+ @adapter = adapter_for(base['adapter'])
34
+ @settings = merged_settings
35
+ return if @adapter.name == 'sqlite3'
36
+ return unless %w[test development].include?(@env.environment)
37
+
40
38
  @settings.merge!('port' => local_port) if @env.docker_compose_config?
41
39
  end
42
40
 
41
+ def merged_settings
42
+ base.merge(@adapter.credentials)
43
+ .merge('scheme' => base['adapter'],
44
+ 'port' => DockerCompose::DatabaseService::PORT)
45
+ end
46
+
43
47
  def parse(content)
44
48
  yaml(erb(content))
45
49
  end
@@ -52,7 +56,7 @@ module Orchestration
52
56
  YAML.safe_load(content, [], [], true) # true: Allow aliases
53
57
  end
54
58
 
55
- def adapter_object(name)
59
+ def adapter_for(name)
56
60
  {
57
61
  'mysql2' => adapters::Mysql2,
58
62
  'postgresql' => adapters::Postgresql,
@@ -61,7 +65,13 @@ module Orchestration
61
65
  end
62
66
 
63
67
  def environment
64
- @environments[@env.environment]
68
+ @environments.fetch(@env.environment)
69
+ rescue KeyError
70
+ raise UnknownEnvironmentError,
71
+ I18n.t(
72
+ 'orchestration.database.unknown_environment',
73
+ environment: @env.environment
74
+ )
65
75
  end
66
76
 
67
77
  def base
@@ -69,7 +79,7 @@ module Orchestration
69
79
  end
70
80
 
71
81
  def host
72
- return nil if @adapter.is_a?(adapters::Sqlite3)
82
+ return nil if @adapter&.name == 'sqlite3'
73
83
 
74
84
  super
75
85
  end
@@ -79,7 +89,7 @@ module Orchestration
79
89
  end
80
90
 
81
91
  def default_port
82
- return {} if @adapter.is_a?(adapters::Sqlite3)
92
+ return {} if @adapter.name == 'sqlite3'
83
93
 
84
94
  { 'port' => @adapter.default_port }
85
95
  end
@@ -15,7 +15,7 @@ module Orchestration
15
15
  exit_on_error = options.fetch(:exit_on_error, true)
16
16
  options.delete(:exit_on_error)
17
17
  env ||= Environment.new
18
- terminal ||= Terminal.new
18
+ terminal ||= Terminal.new(env.settings)
19
19
  name = options.delete(:service_name)
20
20
  check = ServiceCheck.new(new(env, name), terminal, options)
21
21
 
@@ -6,10 +6,15 @@ module Orchestration
6
6
  class Configuration
7
7
  include ConfigurationBase
8
8
 
9
- self.service_name = 'nginx-proxy'
9
+ self.service_name = 'nginx_proxy'
10
+
11
+ def initialize(env, service_name = nil)
12
+ super
13
+ @settings = {}
14
+ end
10
15
 
11
16
  def friendly_config
12
- "[nginx-proxy] #{host}:#{local_port}"
17
+ "[nginx_proxy] #{host}:#{local_port}"
13
18
  end
14
19
  end
15
20
  end
@@ -8,7 +8,7 @@ end
8
8
  require 'orchestration/services/configuration_base'
9
9
  require 'orchestration/services/healthcheck_base'
10
10
 
11
- require 'orchestration/services/application'
11
+ require 'orchestration/services/app'
12
12
  require 'orchestration/services/database'
13
13
  require 'orchestration/services/listener'
14
14
  require 'orchestration/services/mongo'
@@ -1,86 +1,145 @@
1
- .PHONY: start stop migrate docker build push start logs compose config <%= wait_commands %>
1
+ .PHONY: start stop migrate bundle docker build push start logs compose config test-setup <%= wait_commands.join(' ') %>
2
2
 
3
- ### Container management commands ###
3
+ ### Environment setup ###
4
+
5
+ docker_username:=$(shell bash ./<%= env.orchestration_dir_name %>/yaml.bash docker_username)
6
+ docker_repository:=$(shell bash ./<%= env.orchestration_dir_name %>/yaml.bash docker_repository)
7
+
8
+ compose_base:=HOST_UID=$(shell id -u) \
9
+ DOCKER_USERNAME=${docker_username} \
10
+ DOCKER_REPOSITORY=${docker_repository} \
11
+ docker-compose \
12
+ -p ${docker_repository} \
13
+ -f <%= env.orchestration_dir_name %>/docker-compose.yml
14
+
15
+ git_branch:=$(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD))
16
+ git_version:=$(shell git rev-parse --short --verify ${git_branch})
4
17
 
5
- DOCKER_USERNAME:=$(shell bash ./<%= env.orchestration_dir_name %>/yaml.bash docker_username)
6
- DOCKER_REPOSITORY:=$(shell bash ./<%= env.orchestration_dir_name %>/yaml.bash docker_repository)
7
- COMPOSE:=HOST_UID=$(shell id -u) DOCKER_USERNAME=${DOCKER_USERNAME} DOCKER_REPOSITORY=${DOCKER_REPOSITORY} docker-compose -p $(shell bash ./<%= env.orchestration_dir_name %>/yaml.bash docker_repository) -f orchestration/docker-compose.yml
18
+ -include .env
19
+ export
20
+
21
+ ifneq (,$(RAILS_ENV))
22
+ env:=$(RAILS_ENV)
23
+ else ifneq (,$(RACK_ENV))
24
+ env:=$(RACK_ENV)
25
+ else ifeq (,$(env))
26
+ env:=development
27
+ endif
28
+
29
+ compose:=${compose_base} -f <%= env.orchestration_dir_name %>/docker-compose.${env}.yml -f <%= env.orchestration_dir_name %>/docker-compose.override.yml
30
+ rake:=RACK_ENV=${env} RAILS_ENV=${env} bin/rake
31
+
32
+ ### Container management commands ###
8
33
 
9
34
  start:
10
35
  @echo "Starting containers..."
11
- @${COMPOSE} up -d --scale application=$${INSTANCES:-1}
12
- @make wait
36
+ ifeq (${env},$(filter ${env},test development))
37
+ @${compose} up -d
38
+ else
39
+ @${compose} up -d --scale app=$${INSTANCES:-1}
40
+ endif
41
+ @$(MAKE) wait
13
42
 
14
43
  stop:
15
44
  @echo "Stopping containers..."
16
- @${COMPOSE} down
45
+ @${compose} down
17
46
  @echo "All containers stopped."
18
47
 
19
- start-application:
20
- @echo "Starting containers..."
21
- @${COMPOSE} up -d --scale application=$${INSTANCES:-1} nginx-proxy application
22
- @make wait-nginx-proxy wait-application
23
- @echo "Application started."
24
-
25
48
  logs:
26
- @${COMPOSE} logs
49
+ @${compose} logs -f
27
50
 
28
51
  config:
29
- @${COMPOSE} config
52
+ @${compose} config
30
53
 
31
54
  compose:
32
- @${COMPOSE} $$cmd
55
+ @${compose} $$cmd
56
+
57
+ test-setup:
58
+ @$(MAKE) start wait migrate env=test
59
+
60
+ ### Deployment utility commands ###
61
+
62
+ bundle:
63
+ @echo 'Building deployment bundle...'
64
+ @rm -rf <%= env.orchestration_dir_name %>/.deploy/
65
+ @mkdir -p <%= env.orchestration_dir_name %>/.deploy/${docker_repository}/
66
+ @sed -e "s/%%VERSION%%/${git_version}/g" \
67
+ -e "s/%%REPOSITORY%%/${docker_repository}/g" \
68
+ -e "s/%%USERNAME%%/${docker_username}/g" \
69
+ <%= env.orchestration_dir_name %>/deploy.mk > \
70
+ <%= env.orchestration_dir_name %>/.deploy/${docker_repository}/Makefile
71
+ @cp <%= env.orchestration_dir_name %>/docker-compose.yml \
72
+ <%= env.orchestration_dir_name %>/docker-compose.production.yml \
73
+ <%= env.orchestration_dir_name %>/docker-compose.override.yml \
74
+ <%= env.orchestration_dir_name %>/.deploy/${docker_repository}/
75
+ @tar -C <%= env.orchestration_dir_name %>/.deploy -cf ./deploy.tar ./${docker_repository}
76
+ @echo 'Deployment bundle written to ./deploy.tar'
33
77
 
34
78
  ### Database utility commands ###
35
79
 
36
- migrate: wait-database
80
+ migrate:
37
81
  @echo "Running migrations..."
38
- @${COMPOSE} run application bundle exec rake db:migrate
82
+ ifeq (${env},$(filter ${env},test development))
83
+ @${rake} db:migrate
84
+ else
85
+ @${compose} run --rm app bin/rake db:migrate RAILS_ENV=${env}
86
+ endif
39
87
  @echo "Migrations complete."
40
88
 
41
89
  ### Service healthcheck commands ###
42
90
 
43
- wait: <%= wait_commands %>
91
+ wait: <%= wait_commands.join(' ') %>
44
92
  @echo "All Containers ready."
45
93
 
46
- wait-application:
47
- @bin/rake orchestration:application:wait
94
+ ## Test/development wait commands
48
95
 
49
96
  wait-database:
50
- @bin/rake orchestration:database:wait
97
+ ifeq (${env},$(filter ${env},test development))
98
+ @${rake} orchestration:database:wait
99
+ endif
51
100
 
52
101
  wait-mongo:
53
- @bin/rake orchestration:mongo:wait
54
-
55
- wait-nginx-proxy:
56
- @bin/rake orchestration:nginx_proxy:wait
102
+ ifeq (${env},$(filter ${env},test development))
103
+ @${rake} orchestration:mongo:wait
104
+ endif
57
105
 
58
106
  wait-rabbitmq:
59
- @bin/rake orchestration:rabbitmq:wait
107
+ ifeq (${env},$(filter ${env},test development))
108
+ @${rake} orchestration:rabbitmq:wait
109
+ endif
110
+
111
+ ## Production wait commands
112
+
113
+ wait-nginx_proxy:
114
+ ifneq (${env},$(filter ${env},test development))
115
+ @${rake} orchestration:nginx_proxy:wait LISTEN_PORT=${LISTEN_PORT}
116
+ endif
117
+
118
+ wait-app:
119
+ ifneq (${env},$(filter ${env},test development))
120
+ @${rake} orchestration:app:wait LISTEN_PORT=${LISTEN_PORT}
121
+ endif
60
122
 
61
123
  ### Docker build commands ###
62
124
 
63
125
  docker: build push
64
126
 
65
- GIT_BRANCH:=$(if $(BRANCH),$(BRANCH),$(shell git rev-parse --abbrev-ref HEAD))
66
-
67
127
  build:
68
- @echo "Preparing build from ${GIT_BRANCH}"
128
+ @echo "Preparing build from ${git_branch}"
69
129
  @mkdir -p ./<%= env.orchestration_dir_name %>/.build
70
- @git show ${GIT_BRANCH}:./Gemfile > ./<%= env.orchestration_dir_name %>/.build/Gemfile
71
- @git show ${GIT_BRANCH}:./Gemfile.lock > ./<%= env.orchestration_dir_name %>/.build/Gemfile.lock
72
- <% if defined?(Webpacker) %>@git show ${GIT_BRANCH}:./package.json > ./<%= env.orchestration_dir_name %>/.build/package.json<% end %>
73
- <% if defined?(Webpacker) %>@git show ${GIT_BRANCH}:./yarn.lock > ./<%= env.orchestration_dir_name %>/.build/yarn.lock<% end %>
130
+ @git show ${git_branch}:./Gemfile > ./<%= env.orchestration_dir_name %>/.build/Gemfile
131
+ @git show ${git_branch}:./Gemfile.lock > ./<%= env.orchestration_dir_name %>/.build/Gemfile.lock
132
+ <% if defined?(Webpacker) %>@git show ${git_branch}:./package.json > ./<%= env.orchestration_dir_name %>/.build/package.json<% end %>
133
+ <% if defined?(Webpacker) %>@git show ${git_branch}:./yarn.lock > ./<%= env.orchestration_dir_name %>/.build/yarn.lock<% end %>
74
134
  @echo "Building..."
75
- @git archive --format tar.gz -o ./<%= env.orchestration_dir_name %>/.build/context.tar.gz ${GIT_BRANCH}
135
+ @git archive --format tar.gz -o ./<%= env.orchestration_dir_name %>/.build/context.tar.gz ${git_branch}
76
136
  @docker build \
77
137
  --build-arg BUNDLE_GITHUB__COM \
78
138
  --build-arg BUNDLE_BITBUCKET__ORG \
79
- -t ${DOCKER_USERNAME}/${DOCKER_REPOSITORY} \
80
- -t ${DOCKER_USERNAME}/${DOCKER_REPOSITORY}:$(shell git rev-parse --short --verify ${GIT_BRANCH}) \
139
+ -t ${docker_username}/${docker_repository} \
140
+ -t ${docker_username}/${docker_repository}:${git_version} \
81
141
  ./<%= env.orchestration_dir_name %>/
82
142
  @echo "Build complete."
83
143
 
84
- push: VERSION := $(shell git rev-parse --short --verify ${GIT_BRANCH})
85
144
  push:
86
- docker push ${DOCKER_USERNAME}/${DOCKER_REPOSITORY}:${VERSION}
145
+ docker push ${docker_username}/${docker_repository}:${git_version}
@@ -0,0 +1,14 @@
1
+ #
2
+ # Example test command
3
+ #
4
+ # This command will call `test-setup` before running your usual test pipeline.
5
+ #
6
+ # `test-setup` starts all containers specified in `docker-compose.test.yml`,
7
+ # waits for them to be ready, and runs DB migrations.
8
+ #
9
+ # In your CI environment, simply run `make test`.
10
+ #
11
+ .PHONY: test
12
+ test: test-setup
13
+ bundle exec rspec
14
+ bundle exec rubocop
@@ -0,0 +1,34 @@
1
+ .PHONY: deploy stop start config pull logs migrate
2
+
3
+ COMPOSE_BASE:=HOST_UID=$(shell id -u) \
4
+ DOCKER_USERNAME=%%USERNAME%% \
5
+ DOCKER_REPOSITORY=%%REPOSITORY%%:%%VERSION%% \
6
+ docker-compose \
7
+ -p %%REPOSITORY%% \
8
+ -f docker-compose.yml
9
+
10
+ COMPOSE:=${COMPOSE_BASE} -f docker-compose.production.yml -f docker-compose.override.yml
11
+
12
+ deploy:
13
+ @echo "Deploying application to Docker swarm..."
14
+ @${COMPOSE} config | docker stack deploy -c - %%REPOSITORY%%
15
+
16
+ stop:
17
+ @echo "Stopping containers..."
18
+ @${COMPOSE} down
19
+
20
+ start:
21
+ @echo "Launching application..."
22
+ @${COMPOSE} up -d
23
+
24
+ config:
25
+ @${COMPOSE} config
26
+
27
+ pull:
28
+ @${COMPOSE} pull
29
+
30
+ logs:
31
+ @${COMPOSE} logs -f
32
+
33
+ migrate:
34
+ @${COMPOSE} run --rm app bundle exec rake db:migrate
@@ -0,0 +1 @@
1
+ version: <%= env.docker_api_version.to_json %>