orchestration 0.4.2 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d589d50ab6d3d03c9822ba9b93ef34cf5ff8da72cf533fda977ff4636b02971f
4
- data.tar.gz: fa76ff6d543d6b1b9163ae65eec399485afa6cd6c64e197075f63061cb9bc048
3
+ metadata.gz: 1de40b0bbbef8c548aa941a18486aa43c7ba6fe8433c9a14acd8cde13fc9e62b
4
+ data.tar.gz: b7b5cc3303a38971aabdd77217be5cb58ffa9519841724234ed8062854850de7
5
5
  SHA512:
6
- metadata.gz: c628f61477317a5d0f59a74f20edf79f7f2f30558afcb39cd4a31d545b41b142873f8346fdf1fc20012d1fd77a7ac02261a3e3657372f48ed390355f73c02842
7
- data.tar.gz: 1bd874621d3b9bac7f06d771c8f1c77fbeaafb0646a073f39e08b2262d4e1db22bfa57b80ac3312c32cbb59381959e217e39c8a9789d82e61e82b2a230c6c417
6
+ metadata.gz: fb4c23106ebec66f5eff4d2400a33e7370adffbd201800b4c4a9bda3eea0c5292b97d7011d0e5cf309f23f2ed6a5b4d599010062ee08327dc50d5b99e5a25c1d
7
+ data.tar.gz: 2fa9e0131222a6b368c321d9dcd314503c96e57ef639551847a17a04c4a624fa5606347ed4fdc80e3fc4535303f4fd93b65d1b241a45879423e137e9865848ad
data/README.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Orchestration
2
2
 
3
+ ```
4
+ I've got two tickets to the game
5
+ It'd be great if I could take you to it this Sunday
6
+ --Nickelback
7
+ ```
8
+
3
9
  ## Overview
4
10
 
5
11
  _Orchestration_ aims to provide a convenient and consistent process for working with _Rails_ and _Docker_ without obscuring underlying components.
@@ -29,7 +35,7 @@ The below screenshot demonstrates _Orchestration_ being installed in a brand new
29
35
  Add _Orchestration_ to your Gemfile:
30
36
 
31
37
  ```ruby
32
- gem 'orchestration', '~> 0.4.2'
38
+ gem 'orchestration', '~> 0.4.7'
33
39
  ```
34
40
 
35
41
  Install:
@@ -144,7 +150,7 @@ make push
144
150
 
145
151
  ### Development
146
152
 
147
- An [`.env`](https://docs.docker.com/compose/env-file/) is created automatically in your project root. This file is _not_ stored in version control. Set all application environment variables in this file.
153
+ An [`.env` file](https://docs.docker.com/compose/env-file/) is created automatically in your project root. This file is _not_ stored in version control. Set all application environment variables in this file.
148
154
 
149
155
  #### Launching a development server
150
156
 
@@ -176,16 +182,59 @@ make test
176
182
 
177
183
  Note that _Orchestration_ will wait for all services to become fully available (i.e. running and providing valid responses) before attempting to run tests. This is specifically intended to facilitate testing in continuous integration environments.
178
184
 
185
+ _(See [sidecar containers](#sidecar-containers) if you are running your test/development server inside _Docker_)_.
186
+
187
+ Dependencies will be launched and then tested for readiness. The retry limit and interval time for readiness tests can be controlled by the following environment variables:
188
+
189
+ ```
190
+ ORCHESTRATION_RETRY_LIMIT # default: 10
191
+ ORCHESTRATION_RETRY_INTERVAL # default: 5 [seconds]
192
+ ```
193
+
194
+ ### (Local) Production
195
+
196
+ Run a production environment locally to simulate your deployment platform:
197
+
198
+ ```
199
+ make start env=production
200
+ ```
201
+
179
202
  ### Deployment to Docker Swarm
180
203
 
181
- To deploy your application to _Docker Swarm_:
204
+ To deploy your application to a local _Docker Swarm_ use:
205
+ ```
206
+ make deploy
207
+ ```
208
+
209
+ #### Deploy to a remote swarm
210
+
211
+ To connect via _SSH_ to a remote swarm and deploy, pass the `manager` parameter:
182
212
  ```
183
213
  make deploy manager=user@manager.swarm.example.com
184
214
  ```
185
215
 
186
- To use a custom `.env` file:
216
+ #### Use a custom stack name
217
+
218
+ The [_Docker_ stack](https://docs.docker.com/engine/reference/commandline/stack/) name defaults to the name of your repository (as defined in `.orchesration.yml`) and the _Rails_ environment, e.g. `anvil_production`.
219
+
220
+ To override this default, pass the `project_name` parameter:
221
+ ```
222
+ make deploy project_name=acme_anvil_production
223
+ ```
224
+
225
+ This variable will also be available as `COMPOSE_PROJECT_NAME` for use within your `docker-compose.yml`. e.g. to explicitly name a network after the project name:
226
+
227
+ ```yaml
228
+ networks:
229
+ myapp:
230
+ name: "${COMPOSE_PROJECT_NAME}"
231
+ ```
232
+
233
+ #### Use a custom `.env` file
234
+
235
+ Specify a path to a local `.env` file (see [Docker Compose documentation](https://docs.docker.com/compose/environment-variables/#the-env-file)):
187
236
  ```
188
- make deploy env_file=/path/to/.env manager=user@manager.swarm.example.com
237
+ make deploy env_file=/path/to/.env
189
238
  ```
190
239
 
191
240
  Note that the following two variables _must_ be set in the relevant `.env` file (will look in the current working directory if no path provided):
@@ -268,6 +317,17 @@ An [entrypoint](https://docs.docker.com/engine/reference/builder/#entrypoint) sc
268
317
  * Adds a route `host.docker.internal` to the host machine running the container (mimicking the same route provided by _Docker_ itself on _Windows_ and _OS
269
318
  X_).
270
319
 
320
+ <a name="sidecar-containers"></a>
321
+ ## Sidecar Containers
322
+
323
+ If you need to start dependency services (databases, etc.) and connect to them from a _Docker_ container (an example use case of this would be running tests in _Jenkins_ using its _Docker_ agent) then the container that runs your tests must join the same _Docker_ network as your dependency services.
324
+
325
+ To do this automatically, pass the `sidecar` parameter to the `start` or `test` targets:
326
+
327
+ ```bash
328
+ make test sidecar=1
329
+ ```
330
+
271
331
  <a name="rabbitmq-configuration"></a>
272
332
  ## RabbitMQ Configuration
273
333
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Orchestration
4
4
  class ServiceCheck
5
- ATTEMPT_LIMIT = 10
6
- RETRY_INTERVAL = 3 # seconds
5
+ ATTEMPT_LIMIT = ENV.fetch('ORCHESTRATION_RETRY_LIMIT', '10').to_i
6
+ RETRY_INTERVAL = ENV.fetch('ORCHESTRATION_RETRY_INTERVAL', '5').to_i
7
7
 
8
8
  def initialize(service, terminal, options = {})
9
9
  @service = service
@@ -16,6 +16,8 @@ module Orchestration
16
16
  end
17
17
 
18
18
  def run
19
+ return echo_missing unless @service.configuration.configured?
20
+
19
21
  echo_start
20
22
  success = attempt_connection
21
23
  echo_ready if success
@@ -37,6 +39,14 @@ module Orchestration
37
39
  false
38
40
  end
39
41
 
42
+ def echo_missing
43
+ @terminal.write(
44
+ @service_name.to_sym,
45
+ "#{@service.configuration.error} (skipping)",
46
+ :error
47
+ )
48
+ end
49
+
40
50
  def echo_start
41
51
  @terminal.write(@service_name.to_sym, '', :status)
42
52
  end
@@ -3,7 +3,7 @@
3
3
  module Orchestration
4
4
  module Services
5
5
  module ConfigurationBase
6
- attr_reader :service_name, :env
6
+ attr_reader :service_name, :env, :error
7
7
 
8
8
  def self.included(base)
9
9
  base.extend(ClassMethods)
@@ -33,6 +33,14 @@ module Orchestration
33
33
  @service_name
34
34
  end
35
35
 
36
+ def configured?
37
+ port
38
+ true
39
+ rescue KeyError => error
40
+ @error = error
41
+ false
42
+ end
43
+
36
44
  def port
37
45
  return @env.app_port if @service_name == 'app'
38
46
 
@@ -1,8 +1,12 @@
1
1
  FROM ruby:<%= ruby_version %>
2
2
  ARG BUNDLE_BITBUCKET__ORG
3
3
  ARG BUNDLE_GITHUB__COM
4
- RUN apt-get update \
5
- && apt-get install -y node.js gosu sendmail \
4
+ RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
5
+ && apt-get update \
6
+ && DEBIAN_FRONTEND=noninteractive apt-get install -y \
7
+ nodejs \
8
+ gosu \
9
+ sendmail \
6
10
  && rm -rf /var/lib/apt/lists/* \
7
11
  && gem install bundler \
8
12
  && mkdir /app<%if defined?(Webpacker) %> \
@@ -1,7 +1,6 @@
1
1
  #!/bin/sh
2
- set -ue
3
- echo "Host user ID: ${HOST_UID}"
4
- set +u
2
+ HOST_UID=${HOST_UID:-$(id -u)}
3
+ set -e
5
4
  id owner >/dev/null 2>&1 || useradd -u ${HOST_UID} -m -o owner
6
5
  mkdir -p /app/tmp/pids
7
6
  chown -Rf owner:owner /app/tmp /app/log /app/db
@@ -1,4 +1,3 @@
1
- is_container:=$(shell [ -f './.orchestration_container_flag' ] && echo -n '1' || echo -n '0')
2
1
  TERM ?= 'dumb'
3
2
  pwd:=$(shell pwd)
4
3
  ifdef mounted_orchestration
@@ -1,16 +1,12 @@
1
1
  development:
2
2
  clients:
3
3
  default:
4
- hosts:
5
- - 127.0.0.1:<%= compose.call('development').local_port('mongo') %>
6
- database: development_db
4
+ uri: <%= "#{'<' + '%' + '='} ENV.fetch('MONGO_URL', 'mongodb://127.0.0.1:#{compose.call('development').local_port('mongo')}/development_db') #{'%' + '>'}" %>
7
5
 
8
6
  test:
9
7
  clients:
10
8
  default:
11
- hosts:
12
- - 127.0.0.1:<%= compose.call('test').local_port('mongo') %>
13
- database: test_db
9
+ uri: <%= "#{'<' + '%' + '='} ENV.fetch('MONGO_URL', 'mongodb://127.0.0.1:#{compose.call('test').local_port('mongo')}/test_db') #{'%' + '>'}" %>
14
10
 
15
11
  production:
16
12
  clients:
@@ -32,17 +32,22 @@ else
32
32
  endif
33
33
 
34
34
  ifneq (,$(wildcard ${env_file}))
35
- rake=. ${env_file} && ${rake}
35
+ rake_cmd:=${rake}
36
+ rake=. ${env_file} && ${rake_cmd}
36
37
  endif
37
38
 
38
39
  docker_organization=$(shell bash ${orchestration_dir}/yaml.bash docker_organization)
39
40
  docker_repository=$(shell bash ${orchestration_dir}/yaml.bash docker_repository)
40
41
 
42
+ ifeq (,$(project_name))
43
+ project_name = ${docker_repository}_${env}
44
+ endif
45
+
41
46
  compose_base=env HOST_UID=$(shell id -u) \
42
47
  DOCKER_ORGANIZATION="${docker_organization}" \
43
48
  DOCKER_REPOSITORY="${docker_repository}" \
49
+ COMPOSE_PROJECT_NAME="${project_name}" \
44
50
  docker-compose \
45
- -p "${docker_repository}_${env}" \
46
51
  -f "${orchestration_dir}/docker-compose.yml"
47
52
 
48
53
  git_branch ?= $(if $(branch),$(branch),$(shell git rev-parse --abbrev-ref HEAD))
@@ -61,19 +66,22 @@ all: build
61
66
  ### Container management commands ###
62
67
 
63
68
  .PHONY: start
69
+ ifndef network
70
+ start: network := ${docker_repository}_${env}_default
71
+ endif
64
72
  start: _clean-logs
65
73
  @$(call print,'${yellow}Starting containers${reset} ...')
66
74
  ifeq (${env},$(filter ${env},test development))
67
- @${compose} up -d --force-recreate ${services} ${log} || ${fail}
68
- @[ '${is_container}' == '1' ] && \
75
+ @${compose} up --detach --force-recreate --renew-anon-volumes ${services} ${log} || ${fail}
76
+ @[ -n '${sidecar}' ] && \
69
77
  ( \
70
78
  docker network connect '${network}' '$(shell hostname)' ${log} \
71
79
  || \
72
80
  $(call println,'${yellow}Warning${reset}: Unable to join network: "${yellow}${network}${reset}". Container will not be able to connect to dependency services.') \
73
81
  ) \
74
- || ( [ '${is_container}' == '0' ] || ${fail} )
82
+ || ( [ -z '${sidecar}' ] || ${fail} )
75
83
  else
76
- @${compose} up -d --scale app=$${instances:-1} ${services} ${log} || ${fail}
84
+ @${compose} up --detach --scale app=$${instances:-1} ${services} ${log} || ${fail}
77
85
  endif
78
86
  @$(call printrawln,' ${green}started${reset} ${tick}')
79
87
  @$(call println,'${yellow}Waiting for services to become available${reset} ...')
@@ -201,13 +209,11 @@ endif
201
209
 
202
210
  .PHONY: deploy
203
211
  ifndef manager
204
- @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.cor`')
212
+ @$(call println_error,'Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`')
205
213
  endif
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}
214
+ deploy: path := $(shell mktemp -d)
215
+ deploy: RAILS_ENV := ${env}
216
+ deploy: RACK_ENV := ${env}
211
217
  deploy: DOCKER_TAG = ${git_version}
212
218
  deploy:
213
219
  @$(call println,'${yellow}Deploying stack via${reset} ${green}${manager}${reset} ...') && \
@@ -215,7 +221,7 @@ deploy:
215
221
  $(call make,_verify_compose env_file=${env_file} env=${env}) && \
216
222
  $(call make,bundle path='${path}/bundle.tar') ${log} && \
217
223
  cd '${path}' ${log} && \
218
- tar xf './bundle.tar' ${log} && \
224
+ tar xf 'bundle.tar' ${log} && \
219
225
  cd '${docker_repository}' ${log} && \
220
226
  ( [ -z '${env_file}' ] || cp '${env_file}' './.env' ${log} ) && \
221
227
  $(call println,'${yellow}Deployment environment${reset}:') && \
@@ -276,7 +282,7 @@ build:
276
282
  <% if defined?(Webpacker) %> @git show ${git_branch}:./package.json > ${orchestration_dir}/.build/package.json 2>${stderr} || ${fail}<% end %>
277
283
  <% if defined?(Webpacker) %> @git show ${git_branch}:./yarn.lock > ${orchestration_dir}/.build/yarn.lock 2>${stderr} || ${fail}<% end %>
278
284
  @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}
285
+ @temp=$$(mktemp -d) ; ( cd "$${temp}" && tar -uvf '${context}' . ) ${log} || ${fail}
280
286
  @$(call printrawln,'${green}complete.${reset} ${tick}')
281
287
  @$(call print,'${yellow}Building image${reset} ...')
282
288
  @docker build \
@@ -1,11 +1,11 @@
1
1
  <% if compose.call('development').services.key?('rabbitmq') %>
2
2
  development:
3
- url: amqp://127.0.0.1:<%= compose.call('development').local_port('rabbitmq') %>
3
+ url: <%= "#{'<' + '%' + '='} ENV.fetch('RABBITMQ_URL', 'amqp://127.0.0.1:#{compose.call('development').local_port('rabbitmq')}') #{'%' + '>'}" %>
4
4
  <% end %>
5
5
 
6
6
  <% if compose.call('test').services.key?('rabbitmq') %>
7
7
  test:
8
- url: amqp://127.0.0.1:<%= compose.call('test').local_port('rabbitmq') %>
8
+ url: <%= "#{'<' + '%' + '='} ENV.fetch('RABBITMQ_URL', 'amqp://127.0.0.1:#{compose.call('test').local_port('rabbitmq')}') #{'%' + '>'}" %>
9
9
  <% end %>
10
10
 
11
11
  production:
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orchestration
4
- VERSION = '0.4.2'
4
+ VERSION = '0.4.7'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orchestration
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-27 00:00:00.000000000 Z
11
+ date: 2019-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: database_url