orchestration 0.3.3 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
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 %>