orchestration 0.3.8 → 0.3.9

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: 8569b93a7b22313b5633bb0d396a31c8a718f24eaa09f7968a8facd20a749934
4
- data.tar.gz: 14c9f928ebb9e19d4d5d437aa6e72c65d7c1cc3bfa56ff69ab42a81e23ce71c4
3
+ metadata.gz: 48a584dcfdfa1f9ef091d686a4ac83dac0fa56beea18a57fcd932e0e0afa4bab
4
+ data.tar.gz: 0fbb58d5067366eb986978285abc1f910c898f33eba18a7647a08455a583d226
5
5
  SHA512:
6
- metadata.gz: 9297540aa796b86d44bb62f4e34c94a44bc24463f66dd01d2f744e016eb0598085a80cf5393c7c4932293918db9e3f6110cfa6150eb989432c01d5cf907df72a
7
- data.tar.gz: affd54e64411b8f4f3be7096fc0525f25c50a1b46b4b3f01ae1588032cfe4c7e640fdc2c49890b1b63979da4fd3a8be5ed832af37760dbb5b774e0c28a994460
6
+ metadata.gz: 58e95bf102d2895a83eab7d14850a119492e17b427e81e05d373eeeda4459cabd1ed09038ba796140886399a750da2ef6bc7f2bf684ece9cca18a2e7f0a63219
7
+ data.tar.gz: 27d28ed0408efe5e88c323793b3feda57a5c29d9076aa6b28f78ee6da84e9fa609609e7e9cebee0e97ad309037b011434805b1b5670954eacda1031fb97bbeea
data/.gitignore CHANGED
@@ -25,3 +25,5 @@ spec/dummy/config/unicorn.rb
25
25
  orchestration-*.gem
26
26
 
27
27
  .byebug_history
28
+
29
+ TODO
data/README.md CHANGED
@@ -11,7 +11,7 @@ _Orchestration_ is a toolkit for testing, building, and deploying _Ruby_ (includ
11
11
  Add _Orchestration_ to your Gemfile:
12
12
 
13
13
  ```ruby
14
- gem 'orchestration', '~> 0.3.8'
14
+ gem 'orchestration', '~> 0.3.9'
15
15
  ```
16
16
 
17
17
  Install:
@@ -18,9 +18,9 @@ en:
18
18
  ready: "Mongo is ready."
19
19
  bad_config: "Unable to parse Mongo config: %{path}. Expected section for one of: %{expected}"
20
20
 
21
- nginx_proxy:
22
- waiting: "Waiting for Nginx proxy: %{config}"
23
- ready: "Nginx proxy is ready."
21
+ haproxy:
22
+ waiting: "Waiting for HAProxy: %{config}"
23
+ ready: "HAProxy is ready."
24
24
 
25
25
  rabbitmq:
26
26
  waiting: "Waiting for RabbitMQ: %{config}"
@@ -53,8 +53,8 @@ en:
53
53
  mongo:
54
54
  wait: "Wait for Mongo to become available"
55
55
 
56
- nginx_proxy:
57
- wait: "Wait for Nginx proxy to become available"
56
+ haproxy:
57
+ wait: "Wait for HAProxy to become available"
58
58
 
59
59
  rabbitmq:
60
60
  wait: "Wait for RabbitMQ to become available"
@@ -11,11 +11,7 @@ module Orchestration
11
11
  def definition
12
12
  {
13
13
  'image' => '${DOCKER_ORGANIZATION}/${DOCKER_REPOSITORY}',
14
- 'environment' => environment,
15
- 'expose' => [8080],
16
- 'volumes' => [
17
- "#{@config.env.public_volume}:/app/public/:ro"
18
- ]
14
+ 'environment' => environment
19
15
  }
20
16
  end
21
17
 
@@ -23,17 +19,18 @@ module Orchestration
23
19
 
24
20
  def environment
25
21
  {
26
- 'DATABASE_URL' => @config.database_url,
27
22
  'RAILS_LOG_TO_STDOUT' => '1',
23
+ 'RAILS_SERVE_STATIC_FILES' => '1',
28
24
  'UNICORN_PRELOAD_APP' => '1',
29
25
  'UNICORN_TIMEOUT' => '60',
30
26
  'UNICORN_WORKER_PROCESSES' => '8',
31
- 'VIRTUAL_PORT' => '8080'
27
+ 'SERVICE_PORTS' => '8080'
32
28
  }.merge(inherited_environment)
33
29
  end
34
30
 
35
31
  def inherited_environment
36
32
  {
33
+ 'DATABASE_URL' => nil,
37
34
  'HOST_UID' => nil,
38
35
  'RAILS_ENV' => nil,
39
36
  'SECRET_KEY_BASE' => nil,
@@ -18,7 +18,7 @@ module Orchestration
18
18
  end
19
19
 
20
20
  def volumes
21
- public_volume.merge(database_volume).merge(mongo_volume)
21
+ {}.merge(database_volume).merge(mongo_volume)
22
22
  end
23
23
 
24
24
  private
@@ -29,7 +29,7 @@ module Orchestration
29
29
  database: DatabaseService,
30
30
  mongo: MongoService,
31
31
  rabbitmq: RabbitMQService,
32
- nginx_proxy: NginxProxyService
32
+ haproxy: HAProxyService
33
33
  }
34
34
  end
35
35
 
@@ -42,10 +42,6 @@ module Orchestration
42
42
  end.compact
43
43
  end
44
44
 
45
- def public_volume
46
- { @env.public_volume => {} }
47
- end
48
-
49
45
  def database_volume
50
46
  return {} unless services.key?('database')
51
47
 
@@ -35,7 +35,7 @@ module Orchestration
35
35
  end
36
36
 
37
37
  def volumes
38
- return {} if @environment == :test
38
+ return {} unless @environment == :development
39
39
 
40
40
  { 'volumes' => ["#{volume}:#{@config.adapter.data_dir}"] }
41
41
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Orchestration
4
4
  module DockerCompose
5
- class NginxProxyService
5
+ class HAProxyService
6
6
  def initialize(config, environment)
7
7
  @environment = environment
8
8
  @config = config
@@ -10,11 +10,13 @@ module Orchestration
10
10
 
11
11
  def definition
12
12
  {
13
- 'image' => 'rubyorchestration/nginx-proxy',
13
+ 'deploy' => {
14
+ 'placement' => { 'constraints' => ['node.role == manager'] }
15
+ },
16
+ 'image' => 'dockercloud/haproxy',
14
17
  'ports' => %w[${LISTEN_PORT}:80],
15
18
  'volumes' => [
16
- '/var/run/docker.sock:/tmp/docker.sock:ro',
17
- "#{@config.env.public_volume}:/var/www/public/:ro"
19
+ '/var/run/docker.sock:/var/run/docker.sock:ro'
18
20
  ]
19
21
  }
20
22
  end
@@ -53,7 +53,7 @@ module Orchestration
53
53
  {
54
54
  'version' => compose_config(environment).version,
55
55
  'services' => services(environment)
56
- }.merge('volumes' => volumes(environment))
56
+ }
57
57
  end
58
58
 
59
59
  def services(environment)
@@ -79,7 +79,7 @@ module Orchestration
79
79
  when :test, :development
80
80
  %i[database mongo rabbitmq]
81
81
  when :production
82
- %i[nginx_proxy app database mongo rabbitmq]
82
+ %i[haproxy app database mongo rabbitmq]
83
83
  when nil
84
84
  []
85
85
  else
@@ -99,7 +99,7 @@ module Orchestration
99
99
  database: Orchestration::Services::Database::Configuration,
100
100
  mongo: Orchestration::Services::Mongo::Configuration,
101
101
  rabbitmq: Orchestration::Services::RabbitMQ::Configuration,
102
- nginx_proxy: Orchestration::Services::NginxProxy::Configuration
102
+ haproxy: Orchestration::Services::HAProxy::Configuration
103
103
  }.fetch(service).new(@env)
104
104
  end
105
105
 
@@ -11,5 +11,5 @@ require 'orchestration/docker_compose/configuration'
11
11
  require 'orchestration/docker_compose/app_service'
12
12
  require 'orchestration/docker_compose/database_service'
13
13
  require 'orchestration/docker_compose/mongo_service'
14
- require 'orchestration/docker_compose/nginx_proxy_service'
14
+ require 'orchestration/docker_compose/haproxy_service'
15
15
  require 'orchestration/docker_compose/rabbitmq_service'
@@ -32,9 +32,9 @@ module Orchestration
32
32
  end
33
33
 
34
34
  def local_port
35
- key = @service_name == 'app' ? 'nginx_proxy' : @service_name
35
+ key = @service_name == 'app' ? 'haproxy' : @service_name
36
36
 
37
- return ENV.fetch('LISTEN_PORT', '3000').to_i if key == 'nginx_proxy'
37
+ return ENV.fetch('LISTEN_PORT', '3000').to_i if key == 'haproxy'
38
38
 
39
39
  @env.docker_compose_config
40
40
  .fetch('services')
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Orchestration
4
4
  module Services
5
- module NginxProxy
5
+ module HAProxy
6
6
  class Configuration
7
7
  include ConfigurationBase
8
8
 
9
- self.service_name = 'nginx_proxy'
9
+ self.service_name = 'haproxy'
10
10
 
11
11
  def initialize(env, service_name = nil)
12
12
  super
@@ -14,7 +14,7 @@ module Orchestration
14
14
  end
15
15
 
16
16
  def friendly_config
17
- "[nginx_proxy] #{host}:#{local_port}"
17
+ "[haproxy] #{host}:#{local_port}"
18
18
  end
19
19
  end
20
20
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Orchestration
4
4
  module Services
5
- module NginxProxy
5
+ module HAProxy
6
6
  class Healthcheck
7
7
  include HealthcheckBase
8
8
 
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Orchestration
4
+ module Services
5
+ module HAProxy
6
+ end
7
+ end
8
+ end
9
+
10
+ require 'orchestration/services/haproxy/configuration'
11
+ require 'orchestration/services/haproxy/healthcheck'
@@ -12,5 +12,5 @@ require 'orchestration/services/app'
12
12
  require 'orchestration/services/database'
13
13
  require 'orchestration/services/listener'
14
14
  require 'orchestration/services/mongo'
15
- require 'orchestration/services/nginx_proxy'
15
+ require 'orchestration/services/haproxy'
16
16
  require 'orchestration/services/rabbitmq'
@@ -9,40 +9,45 @@ endif
9
9
 
10
10
  verify-environment:
11
11
  ifndef VIRTUAL_HOST
12
- @$(error `VIRTUAL_HOST` must be defined in environment)
12
+ @$(error `VIRTUAL_HOST` must be defined in environment)
13
13
  endif
14
14
 
15
15
  ifndef LISTEN_PORT
16
- @$(error `LISTEN_PORT` must be defined in environment)
16
+ @$(error `LISTEN_PORT` must be defined in environment)
17
17
  endif
18
18
 
19
19
  ifndef env
20
- @$(error Either `env`, `RACK_ENV` or `RAILS_ENV` must be defined in environment)
20
+ @$(error Either `env`, `RACK_ENV` or `RAILS_ENV` must be defined in environment)
21
21
  endif
22
22
 
23
+ project_name:=%%REPOSITORY%%_${env}
23
24
  compose_base:=env HOST_UID=$(shell id -u) \
24
25
  DOCKER_ORGANIZATION=%%ORGANIZATION%% \
25
26
  DOCKER_REPOSITORY=%%REPOSITORY%%:%%VERSION%% \
26
27
  docker-compose \
27
- -p %%REPOSITORY%%_${env} \
28
+ -p ${project_name} \
28
29
  -f docker-compose.yml
29
30
 
30
31
  compose:=${compose_base} -f docker-compose.production.yml -f docker-compose.override.yml
31
32
 
32
33
  .PHONY: deploy
33
34
  deploy:
34
- @echo "Deploying application to Docker swarm..."
35
- @${compose} config | docker stack deploy -c - %%REPOSITORY%%_${env}
35
+ ifndef manager
36
+ @$(error Missing `manager` parameter: `make deploy manager=swarm-manager.example.com`)
37
+ else
38
+ @tar -cf - . | ssh ${manager} 'cd $$(mktemp -d) ; chmod 0700 . ; cat - | tar -x ; make deploy-stack ; rm -r $$(pwd)'
39
+ endif
36
40
 
37
- .PHONY: stop
38
- stop:
39
- @echo "Stopping containers..."
40
- @${compose} down
41
+ .PHONY: deploy-stack
42
+ deploy-stack:
43
+ @${compose} config | docker stack deploy --prune --with-registry-auth -c - ${project_name}
41
44
 
42
- .PHONY: start
43
- start:
44
- @echo "Launching application..."
45
- @${compose} up -d --scale app=$${instances:-1}
45
+ .PHONY: console
46
+ service := app
47
+ command := /bin/bash
48
+ console:
49
+ @echo "Creating temporary container..."
50
+ @${compose} run --rm ${service} ${command}
46
51
 
47
52
  .PHONY: config
48
53
  config:
@@ -53,8 +58,13 @@ pull:
53
58
  @${compose} pull
54
59
 
55
60
  .PHONY: logs
61
+ service := app
56
62
  logs:
57
- @${compose} logs -f
63
+ ifndef manager
64
+ @$(error Missing `manager` parameter: `make logs manager=swarm-manager.example.com`)
65
+ else
66
+ ssh ${manager} "docker service logs -f ${project_name}_${service}"
67
+ endif
58
68
 
59
69
  .PHONY: migrate
60
70
  migrate:
@@ -1,6 +1,5 @@
1
- # Set VIRTUAL_HOST to whatever host(s) your application will be available on.
2
- # See https://github.com/jwilder/nginx-proxy for more details on this variable.
3
- VIRTUAL_HOST=localhost
4
-
5
- # Set the port your application will be available on (via Nginx proxy)
1
+ # Your application will be available on this port when deployed to the Swarm:
6
2
  LISTEN_PORT=3000
3
+
4
+ # Comma-separated list of hostnames your application will be available on:
5
+ VIRTUAL_HOST=localhost
@@ -5,11 +5,13 @@ SHELL:=/bin/bash
5
5
  -include .env
6
6
  export
7
7
 
8
- ifneq (,$(RAILS_ENV))
8
+ ifneq (,$(env))
9
+ env:=$(env)
10
+ else ifneq (,$(RAILS_ENV))
9
11
  env:=$(RAILS_ENV)
10
12
  else ifneq (,$(RACK_ENV))
11
13
  env:=$(RACK_ENV)
12
- else ifeq (,$(env))
14
+ else
13
15
  env:=development
14
16
  endif
15
17
 
@@ -92,13 +94,15 @@ bundle:
92
94
  .PHONY: migrate
93
95
  migrate:
94
96
  @echo "Running migrations..."
95
- ifeq (${env},$(filter ${env},test development))
96
97
  @(${rake} db:create && ${rake} db:migrate) || ${rake} db:migrate
97
- else
98
- @${compose} run --rm app bin/rake db:migrate RAILS_ENV=${env}
99
- endif
100
98
  @echo "Migrations complete."
101
99
 
100
+ .PHONY: migrate-container
101
+ migrate-container:
102
+ @echo "[app] Running migrations..."
103
+ @${compose} run --rm app make migrate env=${env}
104
+ @echo "[app] Migrations complete."
105
+
102
106
  ### Service healthcheck commands ###
103
107
 
104
108
  .PHONY: wait
@@ -132,10 +136,10 @@ endif
132
136
 
133
137
  ## Production wait commands
134
138
 
135
- .PHONY: wait-nginx_proxy
136
- wait-nginx_proxy:
139
+ .PHONY: wait-haproxy
140
+ wait-haproxy:
137
141
  ifneq (${env},$(filter ${env},test development))
138
- @${rake} orchestration:nginx_proxy:wait LISTEN_PORT=${LISTEN_PORT}
142
+ @${rake} orchestration:haproxy:wait LISTEN_PORT=${LISTEN_PORT}
139
143
  endif
140
144
 
141
145
  .PHONY: wait-app
@@ -22,6 +22,7 @@ module Orchestration
22
22
  def write(desc, message, color_name = nil, newline = true)
23
23
  output = newline ? "#{message}\n" : message.to_s
24
24
  STDOUT.print colorize(desc, output, color_name)
25
+ STDOUT.flush
25
26
  end
26
27
 
27
28
  def read(message, default = nil)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Orchestration
4
- VERSION = '0.3.8'
4
+ VERSION = '0.3.9'
5
5
  end
@@ -29,10 +29,10 @@ namespace :orchestration do
29
29
  end
30
30
  end
31
31
 
32
- namespace :nginx_proxy do
33
- desc I18n.t('orchestration.rake.nginx_proxy.wait')
32
+ namespace :haproxy do
33
+ desc I18n.t('orchestration.rake.haproxy.wait')
34
34
  task :wait do
35
- Orchestration::Services::NginxProxy::Healthcheck.start
35
+ Orchestration::Services::HAProxy::Healthcheck.start
36
36
  end
37
37
  end
38
38
 
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.3.8
4
+ version: 0.3.9
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-01-17 00:00:00.000000000 Z
11
+ date: 2019-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -325,7 +325,6 @@ files:
325
325
  - Makefile
326
326
  - README.md
327
327
  - Rakefile
328
- - TODO
329
328
  - bin/console
330
329
  - bin/rspec
331
330
  - bin/rubocop
@@ -338,9 +337,9 @@ files:
338
337
  - lib/orchestration/docker_compose/app_service.rb
339
338
  - lib/orchestration/docker_compose/configuration.rb
340
339
  - lib/orchestration/docker_compose/database_service.rb
340
+ - lib/orchestration/docker_compose/haproxy_service.rb
341
341
  - lib/orchestration/docker_compose/install_generator.rb
342
342
  - lib/orchestration/docker_compose/mongo_service.rb
343
- - lib/orchestration/docker_compose/nginx_proxy_service.rb
344
343
  - lib/orchestration/docker_compose/rabbitmq_service.rb
345
344
  - lib/orchestration/environment.rb
346
345
  - lib/orchestration/errors.rb
@@ -360,6 +359,9 @@ files:
360
359
  - lib/orchestration/services/database/adapters/sqlite3.rb
361
360
  - lib/orchestration/services/database/configuration.rb
362
361
  - lib/orchestration/services/database/healthcheck.rb
362
+ - lib/orchestration/services/haproxy.rb
363
+ - lib/orchestration/services/haproxy/configuration.rb
364
+ - lib/orchestration/services/haproxy/healthcheck.rb
363
365
  - lib/orchestration/services/healthcheck_base.rb
364
366
  - lib/orchestration/services/listener.rb
365
367
  - lib/orchestration/services/listener/configuration.rb
@@ -367,9 +369,6 @@ files:
367
369
  - lib/orchestration/services/mongo.rb
368
370
  - lib/orchestration/services/mongo/configuration.rb
369
371
  - lib/orchestration/services/mongo/healthcheck.rb
370
- - lib/orchestration/services/nginx_proxy.rb
371
- - lib/orchestration/services/nginx_proxy/configuration.rb
372
- - lib/orchestration/services/nginx_proxy/healthcheck.rb
373
372
  - lib/orchestration/services/rabbitmq.rb
374
373
  - lib/orchestration/services/rabbitmq/configuration.rb
375
374
  - lib/orchestration/services/rabbitmq/healthcheck.rb
@@ -380,7 +379,6 @@ files:
380
379
  - lib/orchestration/templates/docker-compose.override.yml.erb
381
380
  - lib/orchestration/templates/entrypoint.sh.erb
382
381
  - lib/orchestration/templates/env.erb
383
- - lib/orchestration/templates/nginx.tmpl.erb
384
382
  - lib/orchestration/templates/orchestration.mk.erb
385
383
  - lib/orchestration/templates/unicorn.rb.erb
386
384
  - lib/orchestration/templates/yaml.bash.erb
data/TODO DELETED
@@ -1,24 +0,0 @@
1
- Refactor docker-compose services - these really belong in
2
- lib/orchestration/services/<service-name>/docker_compose.rb
3
-
4
- Add default logging section to each service ?
5
-
6
- Redis support
7
-
8
- Use `Paint` instead of `Colorize` for colouring output - better licensing and no
9
- monkeypatching `String` etc.
10
-
11
- Make unicorn `config.rb` resilient to database connectivity failures
12
-
13
- Group healthcheck rake tasks - run all at once in the same process. Create a
14
- master process that generates config files and calls each healthcheck in batch.
15
-
16
- Provide a way of declaratively configuring bespoke healthchecks.
17
-
18
- Auto-healthcheck any services with a local port bind using the Listener
19
- healthcheck.
20
-
21
- Add remote Docker swarm management.
22
- https://github.com/mikejmoore/docker-swarm-sdk
23
-
24
- Add scp and ssh execution of docker-compose bundle to servers.
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Orchestration
4
- module Services
5
- module NginxProxy
6
- end
7
- end
8
- end
9
-
10
- require 'orchestration/services/nginx_proxy/configuration'
11
- require 'orchestration/services/nginx_proxy/healthcheck'
@@ -1,364 +0,0 @@
1
- {{ $CurrentContainer := where $ "ID" .Docker.CurrentContainerID | first }}
2
-
3
- {{ define "upstream" }}
4
- {{ if .Address }}
5
- {{/* If we got the containers from swarm and this container's port is published to host, use host IP:PORT */}}
6
- {{ if and .Container.Node.ID .Address.HostPort }}
7
- # {{ .Container.Node.Name }}/{{ .Container.Name }}
8
- server {{ .Container.Node.Address.IP }}:{{ .Address.HostPort }};
9
- {{/* If there is no swarm node or the port is not published on host, use container's IP:PORT */}}
10
- {{ else if .Network }}
11
- # {{ .Container.Name }}
12
- server {{ .Network.IP }}:{{ .Address.Port }};
13
- {{ end }}
14
- {{ else if .Network }}
15
- # {{ .Container.Name }}
16
- {{ if .Network.IP }}
17
- server {{ .Network.IP }} down;
18
- {{ else }}
19
- server 127.0.0.1 down;
20
- {{ end }}
21
- {{ end }}
22
-
23
- {{ end }}
24
-
25
- # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
26
- # scheme used to connect to this server
27
- map $http_x_forwarded_proto $proxy_x_forwarded_proto {
28
- default $http_x_forwarded_proto;
29
- '' $scheme;
30
- }
31
-
32
- # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
33
- # server port the client connected to
34
- map $http_x_forwarded_port $proxy_x_forwarded_port {
35
- default $http_x_forwarded_port;
36
- '' $server_port;
37
- }
38
-
39
- # If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
40
- # Connection header that may have been passed to this server
41
- map $http_upgrade $proxy_connection {
42
- default upgrade;
43
- '' close;
44
- }
45
-
46
- # Apply fix for very long server names
47
- server_names_hash_bucket_size 128;
48
-
49
- # Default dhparam
50
- {{ if (exists "/etc/nginx/dhparam/dhparam.pem") }}
51
- ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
52
- {{ end }}
53
-
54
- # Set appropriate X-Forwarded-Ssl header
55
- map $scheme $proxy_x_forwarded_ssl {
56
- default off;
57
- https on;
58
- }
59
-
60
- gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
61
-
62
- log_format vhost '$host $remote_addr - $remote_user [$time_local] '
63
- '"$request" $status $body_bytes_sent '
64
- '"$http_referer" "$http_user_agent"';
65
-
66
- access_log off;
67
-
68
- {{ if $.Env.RESOLVERS }}
69
- resolver {{ $.Env.RESOLVERS }};
70
- {{ end }}
71
-
72
- {{ if (exists "/etc/nginx/proxy.conf") }}
73
- include /etc/nginx/proxy.conf;
74
- {{ else }}
75
- # HTTP 1.1 support
76
- proxy_http_version 1.1;
77
- proxy_buffering off;
78
- proxy_set_header Host $http_host;
79
- proxy_set_header Upgrade $http_upgrade;
80
- proxy_set_header Connection $proxy_connection;
81
- proxy_set_header X-Real-IP $remote_addr;
82
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
83
- proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
84
- proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
85
- proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
86
-
87
- # Mitigate httpoxy attack (see README for details)
88
- proxy_set_header Proxy "";
89
- {{ end }}
90
-
91
- {{ $enable_ipv6 := eq (or ($.Env.ENABLE_IPV6) "") "true" }}
92
- server {
93
- server_name _; # This is just an invalid value which will never trigger on a real hostname.
94
- listen 80;
95
- {{ if $enable_ipv6 }}
96
- listen [::]:80;
97
- {{ end }}
98
- access_log /var/log/nginx/access.log vhost;
99
- return 503;
100
- }
101
-
102
- {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
103
- server {
104
- server_name _; # This is just an invalid value which will never trigger on a real hostname.
105
- listen 443 ssl http2;
106
- {{ if $enable_ipv6 }}
107
- listen [::]:443 ssl http2;
108
- {{ end }}
109
- access_log /var/log/nginx/access.log vhost;
110
- return 503;
111
-
112
- ssl_session_tickets off;
113
- ssl_certificate /etc/nginx/certs/default.crt;
114
- ssl_certificate_key /etc/nginx/certs/default.key;
115
- }
116
- {{ end }}
117
-
118
- {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }}
119
-
120
- {{ $host := trim $host }}
121
- {{ $is_regexp := hasPrefix "~" $host }}
122
- {{ $upstream_name := when $is_regexp (sha1 $host) $host }}
123
-
124
- # {{ $host }}
125
- upstream {{ $upstream_name }} {
126
-
127
- {{ range $container := $containers }}
128
- {{ $addrLen := len $container.Addresses }}
129
-
130
- {{ range $knownNetwork := $CurrentContainer.Networks }}
131
- {{ range $containerNetwork := $container.Networks }}
132
- {{ if (and (ne $containerNetwork.Name "ingress") (or (eq $knownNetwork.Name $containerNetwork.Name) (eq $knownNetwork.Name "host"))) }}
133
- ## Can be connected with "{{ $containerNetwork.Name }}" network
134
-
135
- {{/* If only 1 port exposed, use that */}}
136
- {{ if eq $addrLen 1 }}
137
- {{ $address := index $container.Addresses 0 }}
138
- {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
139
- {{/* If more than one port exposed, use the one matching VIRTUAL_PORT env var, falling back to standard web port 80 */}}
140
- {{ else }}
141
- {{ $port := coalesce $container.Env.VIRTUAL_PORT "80" }}
142
- {{ $address := where $container.Addresses "Port" $port | first }}
143
- {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
144
- {{ end }}
145
- {{ else }}
146
- # Cannot connect to network of this container
147
- server 127.0.0.1 down;
148
- {{ end }}
149
- {{ end }}
150
- {{ end }}
151
- {{ end }}
152
- }
153
-
154
- {{ $default_host := or ($.Env.DEFAULT_HOST) "" }}
155
- {{ $default_server := index (dict $host "" $default_host "default_server") $host }}
156
-
157
- {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
158
- {{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }}
159
-
160
- {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
161
- {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }}
162
-
163
- {{/* Get the HTTPS_METHOD defined by containers w/ the same vhost, falling back to "redirect" */}}
164
- {{ $https_method := or (first (groupByKeys $containers "Env.HTTPS_METHOD")) "redirect" }}
165
-
166
- {{/* Get the SSL_POLICY defined by containers w/ the same vhost, falling back to "Mozilla-Intermediate" */}}
167
- {{ $ssl_policy := or (first (groupByKeys $containers "Env.SSL_POLICY")) "Mozilla-Intermediate" }}
168
-
169
- {{/* Get the HSTS defined by containers w/ the same vhost, falling back to "max-age=31536000" */}}
170
- {{ $hsts := or (first (groupByKeys $containers "Env.HSTS")) "max-age=31536000" }}
171
-
172
- {{/* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}}
173
- {{ $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }}
174
-
175
-
176
- {{/* Get the first cert name defined by containers w/ the same vhost */}}
177
- {{ $certName := (first (groupByKeys $containers "Env.CERT_NAME")) }}
178
-
179
- {{/* Get the best matching cert by name for the vhost. */}}
180
- {{ $vhostCert := (closest (dir "/etc/nginx/certs") (printf "%s.crt" $host))}}
181
-
182
- {{/* vhostCert is actually a filename so remove any suffixes since they are added later */}}
183
- {{ $vhostCert := trimSuffix ".crt" $vhostCert }}
184
- {{ $vhostCert := trimSuffix ".key" $vhostCert }}
185
-
186
- {{/* Use the cert specified on the container or fallback to the best vhost match */}}
187
- {{ $cert := (coalesce $certName $vhostCert) }}
188
-
189
- {{ $is_https := (and (ne $https_method "nohttps") (ne $cert "") (exists (printf "/etc/nginx/certs/%s.crt" $cert)) (exists (printf "/etc/nginx/certs/%s.key" $cert))) }}
190
-
191
- {{ if $is_https }}
192
-
193
- {{ if eq $https_method "redirect" }}
194
- server {
195
- server_name {{ $host }};
196
- listen 80 {{ $default_server }};
197
- {{ if $enable_ipv6 }}
198
- listen [::]:80 {{ $default_server }};
199
- {{ end }}
200
- access_log /var/log/nginx/access.log vhost;
201
- return 301 https://$host$request_uri;
202
- }
203
- {{ end }}
204
-
205
- server {
206
- server_name {{ $host }};
207
- listen 443 ssl http2 {{ $default_server }};
208
- {{ if $enable_ipv6 }}
209
- listen [::]:443 ssl http2 {{ $default_server }};
210
- {{ end }}
211
- access_log /var/log/nginx/access.log vhost;
212
-
213
- {{ if eq $network_tag "internal" }}
214
- # Only allow traffic from internal clients
215
- include /etc/nginx/network_internal.conf;
216
- {{ end }}
217
-
218
- {{ if eq $ssl_policy "Mozilla-Modern" }}
219
- ssl_protocols TLSv1.2 TLSv1.3;
220
- ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
221
- {{ else if eq $ssl_policy "Mozilla-Intermediate" }}
222
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
223
- ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';
224
- {{ else if eq $ssl_policy "Mozilla-Old" }}
225
- ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
226
- ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP';
227
- {{ else if eq $ssl_policy "AWS-TLS-1-2-2017-01" }}
228
- ssl_protocols TLSv1.2 TLSv1.3;
229
- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:AES128-GCM-SHA256:AES128-SHA256:AES256-GCM-SHA384:AES256-SHA256';
230
- {{ else if eq $ssl_policy "AWS-TLS-1-1-2017-01" }}
231
- ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
232
- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
233
- {{ else if eq $ssl_policy "AWS-2016-08" }}
234
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
235
- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA';
236
- {{ else if eq $ssl_policy "AWS-2015-05" }}
237
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
238
- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DES-CBC3-SHA';
239
- {{ else if eq $ssl_policy "AWS-2015-03" }}
240
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
241
- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA';
242
- {{ else if eq $ssl_policy "AWS-2015-02" }}
243
- ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
244
- ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:DHE-DSS-AES128-SHA';
245
- {{ end }}
246
-
247
- ssl_prefer_server_ciphers on;
248
- ssl_session_timeout 5m;
249
- ssl_session_cache shared:SSL:50m;
250
- ssl_session_tickets off;
251
-
252
- ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }};
253
- ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }};
254
-
255
- {{ if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }}
256
- ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }};
257
- {{ end }}
258
-
259
- {{ if (exists (printf "/etc/nginx/certs/%s.chain.pem" $cert)) }}
260
- ssl_stapling on;
261
- ssl_stapling_verify on;
262
- ssl_trusted_certificate {{ printf "/etc/nginx/certs/%s.chain.pem" $cert }};
263
- {{ end }}
264
-
265
- {{ if (and (ne $https_method "noredirect") (ne $hsts "off")) }}
266
- add_header Strict-Transport-Security "{{ trim $hsts }}" always;
267
- {{ end }}
268
-
269
- {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
270
- include {{ printf "/etc/nginx/vhost.d/%s" $host }};
271
- {{ else if (exists "/etc/nginx/vhost.d/default") }}
272
- include /etc/nginx/vhost.d/default;
273
- {{ end }}
274
-
275
- root /var/www/public;
276
- try_files $uri @application;
277
-
278
- location @application {
279
- {{ if eq $proto "uwsgi" }}
280
- include uwsgi_params;
281
- uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }};
282
- {{ else if eq $proto "fastcgi" }}
283
- root {{ trim $vhost_root }};
284
- include fastcgi.conf;
285
- fastcgi_pass {{ trim $upstream_name }};
286
- {{ else }}
287
- proxy_pass {{ trim $proto }}://{{ trim $upstream_name }};
288
- {{ end }}
289
-
290
- {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
291
- auth_basic "Restricted {{ $host }}";
292
- auth_basic_user_file {{ (printf "/etc/nginx/htpasswd/%s" $host) }};
293
- {{ end }}
294
- {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
295
- include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
296
- {{ else if (exists "/etc/nginx/vhost.d/default_location") }}
297
- include /etc/nginx/vhost.d/default_location;
298
- {{ end }}
299
- }
300
- }
301
-
302
- {{ end }}
303
-
304
- {{ if or (not $is_https) (eq $https_method "noredirect") }}
305
-
306
- server {
307
- server_name {{ $host }};
308
- listen 80 {{ $default_server }};
309
- {{ if $enable_ipv6 }}
310
- listen [::]:80 {{ $default_server }};
311
- {{ end }}
312
- access_log /var/log/nginx/access.log vhost;
313
-
314
- {{ if eq $network_tag "internal" }}
315
- # Only allow traffic from internal clients
316
- include /etc/nginx/network_internal.conf;
317
- {{ end }}
318
-
319
- {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
320
- include {{ printf "/etc/nginx/vhost.d/%s" $host }};
321
- {{ else if (exists "/etc/nginx/vhost.d/default") }}
322
- include /etc/nginx/vhost.d/default;
323
- {{ end }}
324
-
325
- root /var/www/public;
326
- try_files $uri @application;
327
-
328
- location @application {
329
- {{ if eq $proto "uwsgi" }}
330
- include uwsgi_params;
331
- uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }};
332
- {{ else if eq $proto "fastcgi" }}
333
- root {{ trim $vhost_root }};
334
- include fastcgi.conf;
335
- fastcgi_pass {{ trim $upstream_name }};
336
- {{ else }}
337
- proxy_pass {{ trim $proto }}://{{ trim $upstream_name }};
338
- {{ end }}
339
-
340
- {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
341
- include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
342
- {{ else if (exists "/etc/nginx/vhost.d/default_location") }}
343
- include /etc/nginx/vhost.d/default_location;
344
- {{ end }}
345
- }
346
- }
347
-
348
- {{ if (and (not $is_https) (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }}
349
- server {
350
- server_name {{ $host }};
351
- listen 443 ssl http2 {{ $default_server }};
352
- {{ if $enable_ipv6 }}
353
- listen [::]:443 ssl http2 {{ $default_server }};
354
- {{ end }}
355
- access_log /var/log/nginx/access.log vhost;
356
- return 500;
357
-
358
- ssl_certificate /etc/nginx/certs/default.crt;
359
- ssl_certificate_key /etc/nginx/certs/default.key;
360
- }
361
- {{ end }}
362
-
363
- {{ end }}
364
- {{ end }}