From 7e823972b95c4ab5c66a5ba4e23d2c2caf88bb44 Mon Sep 17 00:00:00 2001 From: whitestar Date: Tue, 25 Jul 2017 22:17:19 +0900 Subject: [PATCH] adds a reverse proxy (nginx) service to the `nexus-grid::docker-compose` recipe. --- cookbooks/nexus-grid/CHANGELOG.md | 5 + cookbooks/nexus-grid/README.md | 129 ++++++++++++++++++++- cookbooks/nexus-grid/attributes/default.rb | 32 +++-- cookbooks/nexus-grid/recipes/docker-compose.rb | 54 ++++++--- .../docker-compose/app/nexus/etc/nginx/nginx.conf | 39 +++++++ cookbooks/nexus-grid/version | 2 +- 6 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 cookbooks/nexus-grid/templates/default/opt/docker-compose/app/nexus/etc/nginx/nginx.conf diff --git a/cookbooks/nexus-grid/CHANGELOG.md b/cookbooks/nexus-grid/CHANGELOG.md index f16098e..3b5c429 100644 --- a/cookbooks/nexus-grid/CHANGELOG.md +++ b/cookbooks/nexus-grid/CHANGELOG.md @@ -1,5 +1,10 @@ # nexus-grid CHANGELOG +0.1.1 +----- +- adds a reverse proxy (nginx) service to the `nexus-grid::docker-compose` recipe. +- adds the SSL configuration feature by reverse proxy. + 0.1.0 ----- - Initial release of nexus-gird diff --git a/cookbooks/nexus-grid/README.md b/cookbooks/nexus-grid/README.md index 39dc92f..c5fffd6 100644 --- a/cookbooks/nexus-grid/README.md +++ b/cookbooks/nexus-grid/README.md @@ -15,6 +15,7 @@ This cookbook sets up a Sonatype Nexus Repository Manager by Docker Compose. - [nexus-grid::default](#nexus-griddefault) - [nexus-grid::docker-compose](#nexus-griddocker-compose) - [Role Examples](#role-examples) + - [SSL server keys and certificates management by ssl_cert cookbook](#ssl-server-keys-and-certificates-management-by-ssl_cert-cookbook) - [License and Authors](#license-and-authors) ## Requirements @@ -36,7 +37,10 @@ This cookbook sets up a Sonatype Nexus Repository Manager by Docker Compose. |Key|Type|Description, example|Default| |:--|:--|:--|:--| +|`['nexus-grid']['with_ssl_cert_cookbook']`|Boolean|Activates TLS configurations by the `ssl_cert` cookbook. See `attributes/default.rb`|`false`| +|`['nexus-grid']['ssl_cert']['common_name']`|String|Server common name for TLS|`node['fqdn']`| |`['nexus-grid']['docker-compose']['app_dir']`|String||`"#{node['docker-grid']['compose']['app_dir']}/nexus"`| +|`['nexus-grid']['docker-compose']['etc_dir']`|String||`"#{node['nexus-grid']['docker-compose']['app_dir']}/etc"`| |`['nexus-grid']['docker-compose']['data_dir']`|String|Path string or nil (unset).|`"#{node['nexus-grid']['docker-compose']['app_dir']}/data"`| |`['nexus-grid']['docker-compose']['config']`|Hash|`docker-compose.yml` configurations.|See `attributes/default.rb`| @@ -70,25 +74,91 @@ port = '8081' override_attributes( 'nexus-grid' => { - #'https_enabled' => true, # not supported yet. 'docker-compose' => { 'config' => { 'version' => '2', 'services' => { + 'reverseproxy' => { + 'ports' => [ + "#{port}:8081", + ], + 'volumes' => [ + # This volume will be set by the nexus-grid::docker-compose recipe automatically. + #"#{node['nexus-grid']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro", + ], + }, 'nexus' => { 'restart' => 'always', 'image' => image, + 'volumes' => [ + # This volume will be set by the nexus-grid::docker-compose recipe automatically. + #"#{node['nexus-grid']['docker-compose']['data_dir']}:/nexus-data", + ], + 'environment' => { + #'JAVA_MAX_HEAP' => '1200m', # passed as -Xmx. Defaults to 1200m. + #'JAVA_MIN_HEAP' => '1200m', # passed as -Xms. Defaults to 1200m. + #'EXTRA_JAVA_OPTS' => '', # Additional options can be passed to the JVM via this variable. + }, + }, + }, + }, + }, + }, +) +``` + +- `roles/nexus-with-ssl.rb` + +```ruby +name 'nexus-with-ssl' +description 'Nexus with SSL by reverse proxy (nginx)' + +run_list( + 'recipe[ssl_cert::server_key_pairs]', + 'role[docker]', + 'recipe[nexus-grid::docker-compose]', +) + +image = 'sonatype/nexus3' +port = '8081' +cn = 'nexus.io.example.com' + +override_attributes( + 'ssl_cert' => { + 'common_names' => [ + cn, + ], + }, + 'nexus-grid' => { + 'with_ssl_cert_cookbook' => true, + 'ssl_cert' => { + 'common_name' => cn, + }, + 'docker-compose' => { + 'config' => { + 'version' => '2', + 'services' => { + 'reverseproxy' => { 'ports' => [ "#{port}:8081", ], 'volumes' => [ + # These volumes will be set by the nexus-grid::docker-compose recipe automatically. + #"#{node['nexus-grid']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro", + # and server key pair volume conf. + ], + }, + 'nexus' => { + 'restart' => 'always', + 'image' => image, + 'volumes' => [ # This volume will be set by the nexus-grid::docker-compose recipe automatically. #"#{node['nexus-grid']['docker-compose']['data_dir']}:/nexus-data", ], 'environment' => { - #JAVA_MAX_HEAP => '1200m', # passed as -Xmx. Defaults to 1200m. - #JAVA_MIN_HEAP => '1200m', # passed as -Xms. Defaults to 1200m. - #EXTRA_JAVA_OPTS => '', # Additional options can be passed to the JVM via this variable. + #'JAVA_MAX_HEAP' => '1200m', # passed as -Xmx. Defaults to 1200m. + #'JAVA_MIN_HEAP' => '1200m', # passed as -Xms. Defaults to 1200m. + #'EXTRA_JAVA_OPTS' => '', # Additional options can be passed to the JVM via this variable. }, }, }, @@ -98,6 +168,57 @@ override_attributes( ) ``` +### SSL server keys and certificates management by the `ssl_cert` cookbook + +- create vault items. + +```text +$ ruby -rjson -e 'puts JSON.generate({"private" => File.read("nexus.io.example.com.prod.key")})' \ +> > ~/tmp/nexus.io.example.com.prod.key.json + +$ ruby -rjson -e 'puts JSON.generate({"public" => File.read("nexus.io.example.com.prod.crt")})' \ +> > ~/tmp/nexus.io.example.com.prod.crt.json + +$ cd $CHEF_REPO_PATH + +$ knife vault create ssl_server_keys nexus.io.example.com.prod \ +> --json ~/tmp/nexus.io.example.com.prod.key.json + +$ knife vault create ssl_server_certs nexus.io.example.com.prod \ +> --json ~/tmp/nexus.io.example.com.prod.crt.json +``` + +- grant reference permission to the Concourse host + +```text +$ knife vault update ssl_server_keys nexus.io.example.com.prod -S 'name:nexus-host.example.com' +$ knife vault update ssl_server_certs nexus.io.example.com.prod -S 'name:nexus-host.example.com' +``` + +- modify run_list and attributes + +```ruby +run_list( + 'recipe[ssl_cert::server_key_pairs]', + 'recipe[nexus-grid::docker-compose]', +) + +override_attributes( + 'ssl_cert' => { + 'common_names' => [ + 'nexus.io.example.com', + ], + }, + 'nexus-grid' => { + 'with_ssl_cert_cookbook' => true, + 'ssl_cert' => { + 'common_name' => 'nexus.io.example.com', + }, + # ... + }, +) +``` + ## License and Authors - Author:: whitestar at osdn.jp diff --git a/cookbooks/nexus-grid/attributes/default.rb b/cookbooks/nexus-grid/attributes/default.rb index 4a678cb..e156fc7 100644 --- a/cookbooks/nexus-grid/attributes/default.rb +++ b/cookbooks/nexus-grid/attributes/default.rb @@ -17,16 +17,14 @@ # limitations under the License. # -# Not supported yet. -force_override['nexus-grid']['https_enabled'] = false -force_override['nexus-grid']['with_ssl_cert_cookbook'] = false +default['nexus-grid']['with_ssl_cert_cookbook'] = false # If ['nexus-grid']['with_ssl_cert_cookbook'] is true, # node['nexus-grid']['docker-compose']['config'] # are overridden by the following 'common_name' attributes. -force_override['nexus-grid']['ssl_cert']['ca_names'] = [] -force_override['nexus-grid']['ssl_cert']['common_name'] = node['fqdn'] +default['nexus-grid']['ssl_cert']['common_name'] = node['fqdn'] default['nexus-grid']['docker-compose']['app_dir'] = "#{node['docker-grid']['compose']['app_dir']}/nexus" +default['nexus-grid']['docker-compose']['etc_dir'] = "#{node['nexus-grid']['docker-compose']['app_dir']}/etc" default['nexus-grid']['docker-compose']['data_dir'] = "#{node['nexus-grid']['docker-compose']['app_dir']}/data" force_override['nexus-grid']['docker-compose']['config_format_version'] = '2' @@ -34,10 +32,28 @@ version_2_config = { # Version 2 docker-compose format 'version' => '2', 'services' => { + 'reverseproxy' => { + 'depends_on' => [ + 'nexus', + ], + 'restart' => 'always', + 'image' => 'nginx:alpine', + 'expose' => [ + '8081', + ], + 'ports' => [ + #'8081:8081', # default + ], + 'volumes' => [ + # This volume will be set by the nexus-grid::docker-compose recipe automatically. + #"#{node['nexus-grid']['docker-compose']['etc_dir']}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro", + ], + }, 'nexus' => { 'restart' => 'always', 'image' => 'sonatype/nexus3', 'ports' => [ + # Do not expose! #'8081:8081', #'8443:8443', ], @@ -46,9 +62,9 @@ version_2_config = { #"#{node['nexus-grid']['docker-compose']['data_dir']}:/nexus-data", ], 'environment' => { - #JAVA_MAX_HEAP => '1200m', # passed as -Xmx. Defaults to 1200m. - #JAVA_MIN_HEAP => '1200m', # passed as -Xms. Defaults to 1200m. - #EXTRA_JAVA_OPTS => '', # Additional options can be passed to the JVM via this variable. + #'JAVA_MAX_HEAP' => '1200m', # passed as -Xmx. Defaults to 1200m. + #'JAVA_MIN_HEAP' => '1200m', # passed as -Xms. Defaults to 1200m. + #'EXTRA_JAVA_OPTS' => '', # Additional options can be passed to the JVM via this variable. }, }, }, diff --git a/cookbooks/nexus-grid/recipes/docker-compose.rb b/cookbooks/nexus-grid/recipes/docker-compose.rb index 2325b10..cf6b741 100644 --- a/cookbooks/nexus-grid/recipes/docker-compose.rb +++ b/cookbooks/nexus-grid/recipes/docker-compose.rb @@ -17,20 +17,18 @@ # limitations under the License. # -::Chef::Recipe.send(:include, SSLCert::Helper) - doc_url = 'https://hub.docker.com/r/sonatype/nexus3/' include_recipe 'platform_utils::kernel_user_namespace' include_recipe 'docker-grid::compose' app_dir = node['nexus-grid']['docker-compose']['app_dir'] +etc_dir = node['nexus-grid']['docker-compose']['etc_dir'] data_dir = node['nexus-grid']['docker-compose']['data_dir'] -#bin_dir = "#{app_dir}/bin" [ app_dir, - #bin_dir, + "#{etc_dir}/nginx", ].each {|dir| resources(directory: dir) rescue directory dir do owner 'root' @@ -43,9 +41,23 @@ data_dir = node['nexus-grid']['docker-compose']['data_dir'] config_srvs = node['nexus-grid']['docker-compose']['config']['services'] override_config_srvs = node.override['nexus-grid']['docker-compose']['config']['services'] #force_override_config_srvs = node.force_override['nexus-grid']['docker-compose']['config']['services'] -#envs_org = config_srvs['nexus']['environment'] -#envs = {} -vols = config_srvs['nexus']['volumes'].to_a +#nexus_envs_org = config_srvs['nexus']['environment'] +#nexus_envs = {} +rproxy_vols = config_srvs['reverseproxy']['volumes'].to_a +nexus_vols = config_srvs['nexus']['volumes'].to_a + +ports = config_srvs['reverseproxy']['ports'] +override_config_srvs['reverseproxy']['ports'] = ['8081:8081'] if ports.empty? + +template "#{etc_dir}/nginx/nginx.conf" do + source 'opt/docker-compose/app/nexus/etc/nginx/nginx.conf' + owner 'root' + group 'root' + mode '0644' + action :create +end + +rproxy_vols.push("#{etc_dir}/nginx/nginx.conf:/etc/nginx/nginx.conf:ro") # Data persistent resources(directory: data_dir) rescue directory data_dir do @@ -55,21 +67,28 @@ resources(directory: data_dir) rescue directory data_dir do recursive true end if !data_dir.nil? && !data_dir.empty? -vols.push("#{data_dir}:/nexus-data") if !data_dir.nil? && !data_dir.empty? +nexus_vols.push("#{data_dir}:/nexus-data") if !data_dir.nil? && !data_dir.empty? -ports = config_srvs['nexus']['ports'] -override_config_srvs['nexus']['ports'] = ['8081:8081'] if ports.empty? +if node['nexus-grid']['with_ssl_cert_cookbook'] + ::Chef::Recipe.send(:include, SSLCert::Helper) + cn = node['nexus-grid']['ssl_cert']['common_name'] + # Nginx parent process owner is root. + rproxy_vols.push("#{server_cert_path(cn)}:/root/server.crt:ro") + rproxy_vols.push("#{server_key_path(cn)}:/root/server.key:ro") +end +=begin if node['nexus-grid']['https_enabled'] - etc_dir = "#{data_dir}/etc" - resources(directory: etc_dir) rescue directory etc_dir do + # TODO: TLS conf. for built-in jetty + data_etc_dir = "#{data_dir}/etc" + resources(directory: data_etc_dir) rescue directory data_etc_dir do owner 200 group 200 mode '0755' recursive true end - template "#{etc_dir}/nexus.properties" do + template "#{data_etc_dir}/nexus.properties" do source 'opt/docker-compose/app/nexus/data/etc/nexus.properties' owner 200 group 200 @@ -77,13 +96,16 @@ if node['nexus-grid']['https_enabled'] action :create end - override_config_srvs['nexus']['ports'] = ['8443:8443'] if ports.empty? + nexus_ports = config_srvs['nexus']['ports'] + override_config_srvs['nexus']['ports'] = ['8443:8443'] if nexus_ports.empty? end +=end # merge environment hash -#force_override_config_srvs['nexus']['environment'] = envs unless envs.empty? +#force_override_config_srvs['nexus']['environment'] = nexus_envs unless nexus_envs.empty? # reset vlumes array. -override_config_srvs['nexus']['volumes'] = vols unless vols.empty? +override_config_srvs['reverseproxy']['volumes'] = rproxy_vols unless rproxy_vols.empty? +override_config_srvs['nexus']['volumes'] = nexus_vols unless nexus_vols.empty? config_file = "#{app_dir}/docker-compose.yml" template config_file do diff --git a/cookbooks/nexus-grid/templates/default/opt/docker-compose/app/nexus/etc/nginx/nginx.conf b/cookbooks/nexus-grid/templates/default/opt/docker-compose/app/nexus/etc/nginx/nginx.conf new file mode 100644 index 0000000..8f0908d --- /dev/null +++ b/cookbooks/nexus-grid/templates/default/opt/docker-compose/app/nexus/etc/nginx/nginx.conf @@ -0,0 +1,39 @@ +<% +ssl_enabled = node['nexus-grid']['with_ssl_cert_cookbook'] +-%> +worker_processes 1; + +events { + worker_connections 1024; +} + +http { + sendfile on; + + upstream docker-nexus { + server nexus:8081; + } + + server { +<% if ssl_enabled %> + listen 8081 default ssl; + ssl on; + ssl_certificate /root/server.crt; + ssl_certificate_key /root/server.key; +<% else %> + listen 8081; +<% end %> + + location / { + proxy_pass http://docker-nexus; + proxy_redirect off; + proxy_set_header Host $http_host; # $host does not include the port number. + proxy_set_header X-Real-IP $remote_addr; +<% if ssl_enabled %> + proxy_set_header X-Forwarded-Proto https; +<% end %> + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $server_name; + } + } +} diff --git a/cookbooks/nexus-grid/version b/cookbooks/nexus-grid/version index 6e8bf73..17e51c3 100644 --- a/cookbooks/nexus-grid/version +++ b/cookbooks/nexus-grid/version @@ -1 +1 @@ -0.1.0 +0.1.1 -- 2.11.0