orchestration 0.3.17 → 0.4.0
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/.gitignore +4 -0
- data/LICENSE +7 -0
- data/MANIFEST +76 -0
- data/Makefile +3 -3
- data/README.md +162 -137
- data/Rakefile +2 -2
- data/config/locales/en.yml +3 -1
- data/lib/orchestration/docker_compose/app_service.rb +84 -13
- data/lib/orchestration/docker_compose/compose_configuration.rb +69 -0
- data/lib/orchestration/docker_compose/database_service.rb +15 -13
- data/lib/orchestration/docker_compose/install_generator.rb +3 -2
- data/lib/orchestration/docker_compose/mongo_service.rb +5 -5
- data/lib/orchestration/docker_compose/rabbitmq_service.rb +2 -3
- data/lib/orchestration/docker_compose.rb +1 -0
- data/lib/orchestration/environment.rb +19 -6
- data/lib/orchestration/errors.rb +1 -1
- data/lib/orchestration/file_helpers.rb +27 -4
- data/lib/orchestration/install_generator.rb +85 -20
- data/lib/orchestration/services/app/configuration.rb +9 -5
- data/lib/orchestration/services/app/healthcheck.rb +1 -22
- data/lib/orchestration/services/database/adapters/mysql2.rb +13 -2
- data/lib/orchestration/services/database/adapters/postgresql.rb +0 -1
- data/lib/orchestration/services/database/configuration.rb +68 -75
- data/lib/orchestration/services/database/healthcheck.rb +10 -1
- data/lib/orchestration/services/listener/configuration.rb +1 -1
- data/lib/orchestration/services/listener/healthcheck.rb +2 -2
- data/lib/orchestration/services/{configuration_base.rb → mixins/configuration_base.rb} +15 -13
- data/lib/orchestration/services/{healthcheck_base.rb → mixins/healthcheck_base.rb} +3 -2
- data/lib/orchestration/services/mixins/http_healthcheck.rb +38 -0
- data/lib/orchestration/services/mongo/configuration.rb +37 -63
- data/lib/orchestration/services/mongo/healthcheck.rb +3 -32
- data/lib/orchestration/services/rabbitmq/configuration.rb +11 -22
- data/lib/orchestration/services/rabbitmq/healthcheck.rb +2 -2
- data/lib/orchestration/services.rb +3 -2
- data/lib/orchestration/templates/Dockerfile.erb +8 -4
- data/lib/orchestration/templates/database.yml.erb +32 -0
- data/lib/orchestration/templates/deploy.mk.erb +2 -2
- data/lib/orchestration/templates/entrypoint.sh.erb +13 -4
- data/lib/orchestration/templates/env.erb +10 -2
- data/lib/orchestration/templates/healthcheck.rb.erb +56 -0
- data/lib/orchestration/templates/makefile_macros.mk.erb +108 -0
- data/lib/orchestration/templates/mongoid.yml.erb +18 -0
- data/lib/orchestration/templates/orchestration.mk.erb +242 -120
- data/lib/orchestration/templates/puma.rb.erb +19 -0
- data/lib/orchestration/templates/rabbitmq.yml.erb +12 -0
- data/lib/orchestration/templates/unicorn.rb.erb +5 -5
- data/lib/orchestration/terminal.rb +13 -15
- data/lib/orchestration/version.rb +1 -1
- data/lib/orchestration.rb +20 -2
- data/lib/tasks/orchestration.rake +3 -1
- data/orchestration.gemspec +3 -5
- metadata +23 -13
@@ -1,66 +1,107 @@
|
|
1
1
|
### Environment setup ###
|
2
|
-
|
3
2
|
SHELL:=/bin/bash
|
4
3
|
|
5
|
-
|
4
|
+
<%= macros %>
|
5
|
+
|
6
|
+
ifdef env_file
|
7
|
+
-include ${env_file}
|
8
|
+
else
|
9
|
+
-include .env
|
10
|
+
endif
|
11
|
+
|
6
12
|
export
|
7
13
|
|
8
14
|
ifneq (,$(env))
|
9
|
-
env
|
15
|
+
# `env` set by current shell.
|
10
16
|
else ifneq (,$(RAILS_ENV))
|
11
|
-
env
|
17
|
+
env=$(RAILS_ENV)
|
12
18
|
else ifneq (,$(RACK_ENV))
|
13
|
-
env
|
19
|
+
env=$(RACK_ENV)
|
14
20
|
else
|
15
|
-
env
|
21
|
+
env=development
|
16
22
|
endif
|
17
23
|
|
18
|
-
|
19
|
-
|
24
|
+
DOCKER_TAG ?= latest
|
25
|
+
|
26
|
+
ifneq (,$(wildcard ./bin/rake))
|
27
|
+
rake=RACK_ENV=${env} RAILS_ENV=${env} bin/rake
|
28
|
+
else ifneq (,$(wildcard ./Gemfile))
|
29
|
+
rake=RACK_ENV=${env} RAILS_ENV=${env} bundle exec rake
|
20
30
|
else
|
21
|
-
rake
|
31
|
+
rake=RACK_ENV=${env} RAILS_ENV=${env} rake
|
22
32
|
endif
|
23
33
|
|
24
|
-
|
25
|
-
|
34
|
+
ifneq (,$(wildcard ${env_file}))
|
35
|
+
rake=. ${env_file} && ${rake}
|
36
|
+
endif
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
DOCKER_REPOSITORY=${docker_repository} \
|
30
|
-
docker-compose \
|
31
|
-
-p ${docker_repository}_${env} \
|
32
|
-
-f <%= env.orchestration_dir_name %>/docker-compose.yml \
|
38
|
+
docker_organization=$(shell bash ${orchestration_dir}/yaml.bash docker_organization)
|
39
|
+
docker_repository=$(shell bash ${orchestration_dir}/yaml.bash docker_repository)
|
33
40
|
|
34
|
-
|
35
|
-
|
41
|
+
compose_base=env HOST_UID=$(shell id -u) \
|
42
|
+
DOCKER_ORGANIZATION="${docker_organization}" \
|
43
|
+
DOCKER_REPOSITORY="${docker_repository}" \
|
44
|
+
docker-compose \
|
45
|
+
-p "${docker_repository}_${env}" \
|
46
|
+
-f "${orchestration_dir}/docker-compose.yml"
|
36
47
|
|
37
|
-
|
48
|
+
git_branch ?= $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD))
|
49
|
+
git_version ?= $(shell git rev-parse --short --verify ${git_branch})
|
50
|
+
docker_image=${docker_organization}/${docker_repository}:${git_version}
|
38
51
|
|
39
|
-
|
40
|
-
|
52
|
+
compose=${compose_base} -f ${orchestration_dir}/docker-compose.${env}.yml -f ${orchestration_dir}/docker-compose.override.yml
|
53
|
+
random_str=cat /dev/urandom | LC_ALL=C tr -dc 'a-z' | head -c $1
|
54
|
+
|
55
|
+
ifneq (,$(wildcard ${orchestration_dir}/docker-compose.local.yml))
|
56
|
+
compose:=${compose} -f ${orchestration_dir}/docker-compose.local.yml
|
41
57
|
endif
|
42
58
|
|
59
|
+
all: build
|
60
|
+
|
43
61
|
### Container management commands ###
|
44
62
|
|
45
63
|
.PHONY: start
|
46
|
-
start:
|
47
|
-
|
64
|
+
start: _clean-logs
|
65
|
+
@$(call print,'${yellow}Starting containers${reset} ...')
|
48
66
|
ifeq (${env},$(filter ${env},test development))
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
67
|
+
@${compose} up -d --force-recreate ${services} ${log_progress} || ${fail}
|
68
|
+
@[ '${is_container}' == '1' ] && \
|
69
|
+
( \
|
70
|
+
docker network connect '${network}' '$(shell hostname)' ${log} \
|
71
|
+
|| \
|
72
|
+
$(call println,'${yellow}Warning${reset}: Unable to join network: "${yellow}${network}${reset}". Container will not be able to connect to dependency services.') \
|
73
|
+
) \
|
74
|
+
|| ( [ '${is_container}' == '0' ] || ${fail} )
|
53
75
|
else
|
54
|
-
@${compose} up -d --scale app=$${instances:-1}
|
76
|
+
@${compose} up -d --scale app=$${instances:-1} ${services} ${log_progress} || ${fail}
|
55
77
|
endif
|
56
|
-
@$(
|
78
|
+
@$(call printrawln,' ${green}started${reset} ${tick}')
|
79
|
+
@$(call println,'${yellow}Waiting for services to become available${reset} ...')
|
80
|
+
ifdef services
|
81
|
+
@$(call make,wait services='${services}') 2>${stderr} || ${fail}
|
82
|
+
else
|
83
|
+
@$(call make,wait) 2>${stderr} || ${fail}
|
84
|
+
endif
|
85
|
+
|
86
|
+
<% services.each do |service| %>
|
87
|
+
.PHONY: start-<%= service %>
|
88
|
+
start-<%= service %>:
|
89
|
+
@$(call make,start services='<%= service %>')
|
90
|
+
|
91
|
+
<% end %>
|
57
92
|
|
58
93
|
.PHONY: stop
|
59
|
-
stop:
|
60
|
-
|
61
|
-
@
|
62
|
-
|
63
|
-
|
94
|
+
stop: _clean-logs
|
95
|
+
@$(call print,'${yellow}Stopping containers${reset} ...')
|
96
|
+
@if docker ps --format "{{.ID}}" | grep -q $(shell hostname) ; \
|
97
|
+
then \
|
98
|
+
( ${compose} down ${log_progress} || ${fail} ) \
|
99
|
+
&& \
|
100
|
+
( docker network connect ${docker_repository}_${env}_default $(shell hostname) ${log} || : ) ; \
|
101
|
+
else \
|
102
|
+
${compose} down ${log_progress} || ${fail} ; \
|
103
|
+
fi
|
104
|
+
@$(call printrawln,' ${green}stopped${reset}. ${tick}')
|
64
105
|
|
65
106
|
.PHONY: logs
|
66
107
|
logs:
|
@@ -74,78 +115,135 @@ config:
|
|
74
115
|
compose:
|
75
116
|
@echo ${compose}
|
76
117
|
|
118
|
+
### Development/Test Utility Commands
|
119
|
+
|
120
|
+
.PHONY: serve
|
121
|
+
serve: env_file ?= ./.env
|
122
|
+
serve: rails = RAILS_ENV='${env}' bundle exec rails server ${server}
|
123
|
+
serve: _verify_env
|
124
|
+
@if [ "${custom_env_file}" == "1" ] && [ ! -f "${env_file}" ] ; \
|
125
|
+
then \
|
126
|
+
$(call println_error,'${red}Error${reset}: Environment file "${yellow}${env_file}${reset}" not found. ${cross}') ; \
|
127
|
+
${fail} ; \
|
128
|
+
fi
|
129
|
+
@if [ -f "${env_file}" ] ; \
|
130
|
+
then ( \
|
131
|
+
$(call println,'${yellow}Environment${reset}: ${green}${env_file}${reset}') && \
|
132
|
+
cat '${env_file}' | ${format_env} && \
|
133
|
+
$(call println,'') && \
|
134
|
+
set -a && . '${env_file}' && set +a && \
|
135
|
+
${rails} \
|
136
|
+
) ; \
|
137
|
+
else ${rails} ; \
|
138
|
+
fi
|
139
|
+
|
77
140
|
.PHONY: test-setup
|
141
|
+
test-setup: env := test
|
78
142
|
test-setup:
|
79
|
-
@$(
|
143
|
+
@$(call make,start env=test)
|
144
|
+
ifneq (,$(wildcard config/database.yml))
|
145
|
+
${rake} db:create || :
|
146
|
+
ifneq (,$(wildcard db/structure.sql))
|
147
|
+
${rake} db:structure:load
|
148
|
+
else ifneq (,$(wildcard db/schema.rb))
|
149
|
+
${rake} db:schema:load
|
150
|
+
endif
|
151
|
+
|
152
|
+
${rake} db:migrate
|
153
|
+
endif
|
154
|
+
|
155
|
+
.PHONY: dump
|
156
|
+
dump:
|
157
|
+
@$(call println)
|
158
|
+
@$(call println,'${yellow}Captured${reset} ${green}stdout${reset} ${yellow}and${reset} ${red}stderr${reset} ${yellow}log data${reset}:')
|
159
|
+
@$(call println)
|
160
|
+
@echo
|
161
|
+
@test -f '${stdout}' && ( \
|
162
|
+
$(call hr,${green}) ; \
|
163
|
+
$(call println,'${gray}${stdout}${reset}') ; \
|
164
|
+
$(call hr,${green}) ; \
|
165
|
+
echo ; cat '${stdout}' ; echo ; \
|
166
|
+
$(call hr,${green}) ; \
|
167
|
+
)
|
168
|
+
|
169
|
+
@test -f '${stdout}' && ( \
|
170
|
+
echo ; \
|
171
|
+
$(call hr,${red}) ; \
|
172
|
+
$(call println,'${gray}${stderr}${reset}') ; \
|
173
|
+
$(call hr,${red}) ; \
|
174
|
+
echo ; cat '${stderr}' ; echo ; \
|
175
|
+
$(call hr,${red}) ; \
|
176
|
+
)
|
177
|
+
|
178
|
+
.PHONY: image
|
179
|
+
image:
|
180
|
+
@echo ${docker_image}
|
80
181
|
|
81
182
|
### Deployment utility commands ###
|
82
183
|
|
83
184
|
.PHONY: bundle
|
84
185
|
bundle:
|
85
|
-
|
86
|
-
|
87
|
-
|
186
|
+
ifndef path
|
187
|
+
@$(warning Missing `path` parameter; using `./bundle.tar`. Set a custom path with `make bundle path=/tmp/bundle.tar`)
|
188
|
+
endif
|
189
|
+
@rm -rf ${orchestration_dir}/.deploy/
|
190
|
+
@mkdir -p ${orchestration_dir}/.deploy/${docker_repository}/
|
88
191
|
@sed -e "s/%%VERSION%%/${git_version}/g" \
|
89
192
|
-e "s/%%REPOSITORY%%/${docker_repository}/g" \
|
90
193
|
-e "s/%%ORGANIZATION%%/${docker_organization}/g" \
|
91
|
-
|
92
|
-
|
93
|
-
@cp
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
@tar -C
|
98
|
-
@echo 'Deployment bundle written to ./deploy.tar'
|
194
|
+
${orchestration_dir}/deploy.mk > \
|
195
|
+
${orchestration_dir}/.deploy/${docker_repository}/Makefile
|
196
|
+
@cp ${orchestration_dir}/docker-compose.yml \
|
197
|
+
${orchestration_dir}/docker-compose.production.yml \
|
198
|
+
${orchestration_dir}/docker-compose.override.yml \
|
199
|
+
${orchestration_dir}/.deploy/${docker_repository}/
|
200
|
+
@bundle_path="${path}" ; tar -C '${orchestration_dir}/.deploy' -cf "$${bundle_path:-./bundle.tar}" ./${docker_repository}
|
99
201
|
|
100
202
|
.PHONY: deploy
|
101
|
-
deploy:
|
102
203
|
ifndef manager
|
103
|
-
@$(
|
104
|
-
else
|
105
|
-
@echo 'Deploying stack via ${manager}...'
|
106
|
-
endif
|
107
|
-
|
108
|
-
ifndef env_file
|
109
|
-
$(MAKE) bundle \
|
110
|
-
&& workdir=$$(mktemp -d) \
|
111
|
-
&& mv deploy.tar $${workdir}/ \
|
112
|
-
&& cd $${workdir} \
|
113
|
-
&& tar xf deploy.tar \
|
114
|
-
&& cd ${docker_repository} \
|
115
|
-
&& tar -cf - . | ssh ${manager} 'cd $$(mktemp -d) && chmod 0700 . && cat - | tar -x && make deploy-stack && rm -r $$(pwd)'
|
116
|
-
else
|
117
|
-
$(MAKE) bundle \
|
118
|
-
&& workdir=$$(mktemp -d) \
|
119
|
-
&& mv deploy.tar $${workdir}/ \
|
120
|
-
&& cd $${workdir} \
|
121
|
-
&& tar xf deploy.tar \
|
122
|
-
&& cd ${docker_repository} \
|
123
|
-
&& cp "${env_file}" ./.env \
|
124
|
-
&& tar -cf - . | ssh ${manager} 'cd $$(mktemp -d) && chmod 0700 . && cat - | tar -x && make deploy-stack && rm -r $$(pwd)'
|
125
|
-
endif
|
126
|
-
|
127
|
-
### Database utility commands ###
|
128
|
-
|
129
|
-
.PHONY: migrate
|
130
|
-
migrate:
|
131
|
-
@echo "Running migrations..."
|
132
|
-
@(${rake} db:create && ${rake} db:migrate) || ${rake} db:migrate
|
133
|
-
@echo "Migrations complete."
|
134
|
-
|
135
|
-
.PHONY: migrate-container
|
136
|
-
migrate-container:
|
137
|
-
@echo "[app] Running migrations..."
|
138
|
-
ifdef env_file
|
139
|
-
@cp ${env_file} ./.env
|
204
|
+
@$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.cor`')
|
140
205
|
endif
|
141
|
-
|
142
|
-
|
206
|
+
deploy: env := production
|
207
|
+
deploy: project_name = ${docker_repository}_${env}
|
208
|
+
deploy: path = $(shell mktemp -d)
|
209
|
+
deploy: RAILS_ENV = ${env}
|
210
|
+
deploy: RACK_ENV = ${env}
|
211
|
+
deploy: DOCKER_TAG = ${git_version}
|
212
|
+
deploy:
|
213
|
+
@$(call println,'${yellow}Deploying stack via${reset} ${green}${manager}${reset} ...') && \
|
214
|
+
( \
|
215
|
+
$(call make,_verify_compose env_file=${env_file} env=${env}) && \
|
216
|
+
$(call make,bundle path='${path}/bundle.tar') ${log} && \
|
217
|
+
cd '${path}' ${log} && \
|
218
|
+
tar xf './bundle.tar' ${log} && \
|
219
|
+
cd '${docker_repository}' ${log} && \
|
220
|
+
( [ -z '${env_file}' ] || cp '${env_file}' './.env' ${log} ) && \
|
221
|
+
$(call println,'${yellow}Deployment environment${reset}:') && \
|
222
|
+
( test -f '.env' && cat '.env' | ${format_env} || : ) && \
|
223
|
+
echo 'DOCKER_ORGANIZATION=${docker_organization}' >> './.env' && \
|
224
|
+
echo 'DOCKER_REPOSITORY=${docker_repository}' >> './.env' && \
|
225
|
+
echo 'DOCKER_TAG=${git_version}' >> ./.env && \
|
226
|
+
$(call println,'') && \
|
227
|
+
$(call println,'${yellow}Application image${reset}: ${cyan}${docker_image}${reset}') && \
|
228
|
+
${compose} config 2>${stderr} | ssh "${manager}" 'docker stack deploy --prune --with-registry-auth -c - "${project_name}"' ${log} && \
|
229
|
+
( [ -z "${path}" ] || rm -rf "${path}" ${log} ) \
|
230
|
+
) \
|
231
|
+
|| ${fail}
|
232
|
+
|
233
|
+
@$(call println,'${yellow}Deployment${reset} ${green}complete${reset}. ${tick}')
|
143
234
|
|
144
235
|
### Service healthcheck commands ###
|
145
236
|
|
146
237
|
.PHONY: wait
|
147
|
-
|
148
|
-
|
238
|
+
<% services.each do |service| %>
|
239
|
+
ifneq (,$(findstring <%= service %>,${services}))
|
240
|
+
wait: wait-<%= service %>
|
241
|
+
endif
|
242
|
+
<% end %>
|
243
|
+
ifndef services
|
244
|
+
wait: <%= services.map { |command| "wait-#{command}" }.join(' ') %>
|
245
|
+
endif
|
246
|
+
@$(call println,'${yellow}All services${reset} ${green}ready${reset}. ${tick}')
|
149
247
|
|
150
248
|
## Generic Listener healthcheck for TCP services ##
|
151
249
|
|
@@ -154,23 +252,13 @@ wait-listener:
|
|
154
252
|
|
155
253
|
## Test/development wait commands
|
156
254
|
|
157
|
-
.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
255
|
+
<% services.each do |service| %>
|
256
|
+
<% next if service.to_sym == :app %>
|
257
|
+
.PHONY: wait-<%= service %>
|
258
|
+
wait-<%= service %>:
|
259
|
+
@${rake} orchestration:<%= service %>:wait
|
162
260
|
|
163
|
-
|
164
|
-
wait-mongo:
|
165
|
-
ifeq (${env},$(filter ${env},test development))
|
166
|
-
@${rake} orchestration:mongo:wait
|
167
|
-
endif
|
168
|
-
|
169
|
-
.PHONY: wait-rabbitmq
|
170
|
-
wait-rabbitmq:
|
171
|
-
ifeq (${env},$(filter ${env},test development))
|
172
|
-
@${rake} orchestration:rabbitmq:wait
|
173
|
-
endif
|
261
|
+
<% end %>
|
174
262
|
|
175
263
|
.PHONY: wait-app
|
176
264
|
wait-app:
|
@@ -179,23 +267,57 @@ wait-app:
|
|
179
267
|
### Docker build commands ###
|
180
268
|
|
181
269
|
.PHONY: build
|
270
|
+
build: context = ${orchestration_dir}/.build/context.tar
|
182
271
|
build:
|
183
|
-
|
184
|
-
@mkdir -p
|
185
|
-
@git show ${git_branch}:./Gemfile >
|
186
|
-
@git show ${git_branch}:./Gemfile.lock >
|
187
|
-
<% if defined?(Webpacker) %> @git show ${git_branch}:./package.json >
|
188
|
-
<% if defined?(Webpacker) %> @git show ${git_branch}:./yarn.lock >
|
189
|
-
@
|
190
|
-
@
|
272
|
+
@$(call print,'${yellow}Preparing build context from${reset} ${cyan}${git_branch}:${git_version}${reset} ... ')
|
273
|
+
@mkdir -p ${orchestration_dir}/.build ${log} || ${fail}
|
274
|
+
@git show ${git_branch}:./Gemfile > ${orchestration_dir}/.build/Gemfile 2>${stderr} || ${fail}
|
275
|
+
@git show ${git_branch}:./Gemfile.lock > ${orchestration_dir}/.build/Gemfile.lock 2>${stderr} || ${fail}
|
276
|
+
<% if defined?(Webpacker) %> @git show ${git_branch}:./package.json > ${orchestration_dir}/.build/package.json 2>${stderr} || ${fail}<% end %>
|
277
|
+
<% if defined?(Webpacker) %> @git show ${git_branch}:./yarn.lock > ${orchestration_dir}/.build/yarn.lock 2>${stderr} || ${fail}<% end %>
|
278
|
+
@git archive --format 'tar' -o '${context}' '${git_branch}' ${log} || ${fail}
|
279
|
+
@temp=$$(mktemp -d) ; ( cd "$${temp}" && touch './.orchestration_container_flag' && tar -uvf '${context}' . ) ${log} || ${fail}
|
280
|
+
@$(call printrawln,'${green}complete.${reset} ${tick}')
|
281
|
+
@$(call print,'${yellow}Building image${reset} ...')
|
191
282
|
@docker build \
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
283
|
+
--build-arg BUNDLE_GITHUB__COM \
|
284
|
+
--build-arg BUNDLE_BITBUCKET__ORG \
|
285
|
+
-t ${docker_organization}/${docker_repository} \
|
286
|
+
-t ${docker_organization}/${docker_repository}:${git_version} \
|
287
|
+
${orchestration_dir}/ ${log_progress} || ${fail}
|
288
|
+
@$(call printrawln,' ${green}complete${reset}. ${tick}')
|
289
|
+
@$(call println,'[${green}tag${reset}] ${cyan}${docker_organization}/${docker_repository}${reset}')
|
290
|
+
@$(call println,'[${green}tag${reset}] ${cyan}${docker_organization}/${docker_repository}:${git_version}${reset}')
|
198
291
|
|
199
292
|
.PHONY: push
|
200
293
|
push:
|
201
|
-
|
294
|
+
@$(call print,'${yellow}Pushing${reset} ${cyan}${docker_image}${reset} ...')
|
295
|
+
@docker push ${docker_image} ${log_progress} || ${fail}
|
296
|
+
@$(call printrawln,' ${green}complete${reset}. ${tick}')
|
297
|
+
|
298
|
+
### Internal Commands ###
|
299
|
+
#
|
300
|
+
.PHONY: _verify_app_image
|
301
|
+
_verify_app_image:
|
302
|
+
@docker inspect '${docker_image}'
|
303
|
+
|
304
|
+
.PHONY: _verify_compose
|
305
|
+
_verify_compose: _verify_env
|
306
|
+
@$(call print,'${yellow}Verifying compose file(s)${reset} ... ')
|
307
|
+
@${replace_env}
|
308
|
+
@${compose} config ${log} || ${fail}
|
309
|
+
@${restore_env}
|
310
|
+
@$(call printrawln,'${green}success${reset}. ${tick}')
|
311
|
+
|
312
|
+
.PHONY: _verify_env
|
313
|
+
_verify_env:
|
314
|
+
@if [ "${custom_env_file}" == "1" ] && [ ! -f "${env_file}" ] ; \
|
315
|
+
then \
|
316
|
+
$(call print_error,'${red}Error${reset}: Environment file "${yellow}${env_file}${reset}" not found. ${cross}') ; \
|
317
|
+
exit 1 ; \
|
318
|
+
fi
|
319
|
+
|
320
|
+
.PHONY: _clean-logs
|
321
|
+
_clean-logs:
|
322
|
+
@rm -f '${stdout}' '${stderr}'
|
323
|
+
@touch '${stdout}' '${stderr}'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
environment ENV.fetch('RAILS_ENV') { 'development' }
|
2
|
+
|
3
|
+
port ENV.fetch('WEB_PORT') { 3000 }
|
4
|
+
workers ENV.fetch('WEB_CONCURRENCY') { 4 }
|
5
|
+
threads_count = ENV.fetch('RAILS_MAX_THREADS') { 8 }
|
6
|
+
|
7
|
+
pidfile './tmp/pids/server.pid'
|
8
|
+
threads threads_count, threads_count
|
9
|
+
|
10
|
+
preload_app! if ENV.key?('WEB_PRELOAD_APP')
|
11
|
+
|
12
|
+
before_fork do
|
13
|
+
ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
|
14
|
+
end
|
15
|
+
|
16
|
+
on_worker_boot do
|
17
|
+
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% if compose.call('development').services.key?('rabbitmq') %>
|
2
|
+
development:
|
3
|
+
url: amqp://127.0.0.1:<%= compose.call('development').local_port('rabbitmq') %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<% if compose.call('test').services.key?('rabbitmq') %>
|
7
|
+
test:
|
8
|
+
url: amqp://127.0.0.1:<%= compose.call('test').local_port('rabbitmq') %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
production:
|
12
|
+
url: <%%= ENV['RABBITMQ_URL'] %>
|
@@ -1,12 +1,12 @@
|
|
1
|
-
listen
|
1
|
+
listen "0.0.0.0:#{ENV.fetch('WEB_PORT', '8080')}", tcp_nopush: true
|
2
2
|
|
3
|
-
pid '/app/tmp/pids/
|
3
|
+
pid '/app/tmp/pids/server.pid'
|
4
4
|
|
5
|
-
preload_app ENV.
|
5
|
+
preload_app ENV.key?('WEB_PRELOAD_APP')
|
6
6
|
|
7
|
-
timeout ENV.fetch('
|
7
|
+
timeout ENV.fetch('WEB_TIMEOUT', 60).to_i
|
8
8
|
|
9
|
-
worker_processes ENV.fetch('
|
9
|
+
worker_processes ENV.fetch('WEB_CONCURRENCY', 8).to_i
|
10
10
|
|
11
11
|
before_fork do |_server, _worker|
|
12
12
|
ActiveRecord::Base.connection.disconnect! if defined?(ActiveRecord)
|
@@ -2,16 +2,17 @@
|
|
2
2
|
|
3
3
|
module Orchestration
|
4
4
|
COLOR_MAP = {
|
5
|
-
failure:
|
6
|
-
error:
|
7
|
-
waiting:
|
8
|
-
ready:
|
9
|
-
create:
|
10
|
-
update:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
5
|
+
failure: %i[red bright],
|
6
|
+
error: %i[red],
|
7
|
+
waiting: %i[yellow],
|
8
|
+
ready: %i[green],
|
9
|
+
create: %i[green],
|
10
|
+
update: %i[yellow],
|
11
|
+
backup: %i[blue],
|
12
|
+
status: %i[blue],
|
13
|
+
setup: %i[blue],
|
14
|
+
input: %i[red],
|
15
|
+
skip: %i[yellow bright]
|
15
16
|
}.freeze
|
16
17
|
|
17
18
|
class Terminal
|
@@ -55,11 +56,8 @@ module Orchestration
|
|
55
56
|
else
|
56
57
|
COLOR_MAP.fetch(color_name)
|
57
58
|
end
|
58
|
-
|
59
|
-
|
60
|
-
.rjust(15)
|
61
|
-
.colorize(mode: :default, color: color)
|
62
|
-
.concat(' ' + message)
|
59
|
+
|
60
|
+
Paint[desc.to_s.rjust(15), *color] + ' ' + message
|
63
61
|
end
|
64
62
|
|
65
63
|
def t(key)
|
data/lib/orchestration.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'erb'
|
4
|
+
require 'pathname'
|
5
|
+
require 'socket'
|
6
|
+
|
7
|
+
require 'database_url'
|
4
8
|
require 'erubis'
|
5
9
|
require 'i18n'
|
10
|
+
require 'paint'
|
6
11
|
begin
|
7
12
|
require 'rails'
|
8
13
|
rescue LoadError
|
9
|
-
STDERR.puts('Rails not detected;
|
14
|
+
STDERR.puts('[orchestration] Rails not detected; skipping.')
|
10
15
|
end
|
11
16
|
|
12
17
|
I18n.load_path += Dir[File.join(File.expand_path('..', __dir__),
|
@@ -33,4 +38,17 @@ module Orchestration
|
|
33
38
|
def self.rakefile
|
34
39
|
root.join('lib', 'Rakefile')
|
35
40
|
end
|
41
|
+
|
42
|
+
def self.error(key, options = {})
|
43
|
+
STDERR.puts('# Orchestration Error')
|
44
|
+
STDERR.puts('# ' + I18n.t("orchestration.#{key}", options))
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.random_local_port
|
48
|
+
socket = Socket.new(:INET, :STREAM, 0)
|
49
|
+
socket.bind(Addrinfo.tcp('127.0.0.1', 0))
|
50
|
+
port = socket.local_address.ip_port
|
51
|
+
socket.close
|
52
|
+
port
|
53
|
+
end
|
36
54
|
end
|
@@ -18,7 +18,9 @@ namespace :orchestration do
|
|
18
18
|
namespace :database do
|
19
19
|
desc I18n.t('orchestration.rake.database.wait')
|
20
20
|
task :wait do
|
21
|
-
Orchestration::Services::Database::Healthcheck.start
|
21
|
+
Orchestration::Services::Database::Healthcheck.start(
|
22
|
+
nil, nil, init: ENV.key?('init')
|
23
|
+
)
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
data/orchestration.gemspec
CHANGED
@@ -16,19 +16,17 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.homepage = url
|
17
17
|
|
18
18
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
|
-
|
20
|
-
f.match(%r{^(test|spec|features)/})
|
21
|
-
end
|
19
|
+
File.readlines('MANIFEST').map(&:chomp)
|
22
20
|
end
|
23
21
|
spec.bindir = 'bin'
|
24
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
23
|
spec.require_paths = ['lib']
|
26
24
|
|
27
|
-
spec.add_runtime_dependency '
|
25
|
+
spec.add_runtime_dependency 'database_url', '~> 0.1.2'
|
28
26
|
spec.add_runtime_dependency 'erubis', '~> 2.7'
|
29
27
|
spec.add_runtime_dependency 'i18n', '>= 0.5'
|
28
|
+
spec.add_runtime_dependency 'paint', '~> 2.0'
|
30
29
|
spec.add_runtime_dependency 'thor', '~> 0.20.0'
|
31
|
-
spec.add_runtime_dependency 'unicorn', '~> 5.4'
|
32
30
|
|
33
31
|
spec.add_development_dependency 'activerecord', '~> 5.2'
|
34
32
|
spec.add_development_dependency 'betterp', '~> 0.1.3'
|