orchestration 0.3.17 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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'
|