errorstudio_capistrano_recipes 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/errorstudio_capistrano_recipes.gemspec +34 -0
- data/lib/capistrano/errorstudio.rb +5 -0
- data/lib/capistrano/errorstudio/composer.rb +3 -0
- data/lib/capistrano/errorstudio/cron.rb +2 -0
- data/lib/capistrano/errorstudio/nginx.rb +2 -0
- data/lib/capistrano/errorstudio/ownership.rb +1 -0
- data/lib/capistrano/errorstudio/passenger.rb +2 -0
- data/lib/capistrano/errorstudio/prompts.rb +1 -0
- data/lib/capistrano/errorstudio/rails.rb +13 -0
- data/lib/capistrano/errorstudio/rvm.rb +4 -0
- data/lib/capistrano/errorstudio/static.rb +4 -0
- data/lib/capistrano/errorstudio/tasks/composer.rake +12 -0
- data/lib/capistrano/errorstudio/tasks/cron.rake +15 -0
- data/lib/capistrano/errorstudio/tasks/nginx.rake +198 -0
- data/lib/capistrano/errorstudio/tasks/ownership.rake +11 -0
- data/lib/capistrano/errorstudio/tasks/passenger.rake +76 -0
- data/lib/capistrano/errorstudio/tasks/prompts.rake +18 -0
- data/lib/capistrano/errorstudio/tasks/rails.rake +80 -0
- data/lib/capistrano/errorstudio/tasks/rvm.rake +49 -0
- data/lib/capistrano/errorstudio/tasks/static.rake +0 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/basic_auth.erb +8 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/cloudflare_real_ips.erb +4 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/cors.erb +34 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/custom_aliases.erb +5 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/custom_rules.erb +3 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/location_proxy_cache.erb +6 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/nginx_vhost.conf.erb +84 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/path_redirects.erb +5 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/php.erb +27 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/proxy_cache_path.erb +1 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/redirects.erb +10 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/rewrites.erb +7 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/ssl_settings.erb +24 -0
- data/lib/capistrano/errorstudio/tasks/templates/nginx/upstream_proxy.erb +11 -0
- data/lib/capistrano/errorstudio/tasks/templates/passenger/passenger_init.erb +27 -0
- data/lib/capistrano/errorstudio/tasks/templates/rails/database.yml.erb +8 -0
- data/lib/capistrano/errorstudio/tasks/templates/rails/secrets.yml.erb +5 -0
- data/lib/capistrano/errorstudio/tasks/templates/wordpress/env.erb +23 -0
- data/lib/capistrano/errorstudio/tasks/wordpress.rake +158 -0
- data/lib/capistrano/errorstudio/wordpress.rb +12 -0
- data/lib/version.rb +3 -0
- metadata +209 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: de0bf29b0aca35349c3f21c4c3c4346803091736
|
4
|
+
data.tar.gz: 61af7fe8e700af6b21a4d1aa508191f3a9e186d1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 91dd4b9af5f213cd8837db5c02d175928ee2156dcabe907dad6982e3a59616d1d7c06570cd42a67863fab539803772f517dd076575849a4ef17a385b6ac0e1a6
|
7
|
+
data.tar.gz: 082ffe378aa0e9c197152749fa3bf8327e225a43422d264256a9d19c1b1f8df9b6fa0a6e33d816174331d65b093d0d33e8834d7fdf21c8a533450fcda2d9ed85
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
errorstudio-capistrano-recipes
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.0
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Error Ltd
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Error Studio Capistrano Recipes
|
2
|
+
|
3
|
+
At [Error](https://error.agency) we like to deploy things with Capistrano. This is a selection of our scripts for deploying:
|
4
|
+
|
5
|
+
* Rails
|
6
|
+
* Wordpress (using the [Bedrock](https://roots.io/bedrock/) approach and composer)
|
7
|
+
* Static sites
|
8
|
+
|
9
|
+
There are some optional parts too:
|
10
|
+
|
11
|
+
* Nginx config with SSL
|
12
|
+
* RVM setup
|
13
|
+
* Phusion Passenger configuration
|
14
|
+
* Cron jobs
|
15
|
+
|
16
|
+
|
17
|
+
# Warning / Disclaimer
|
18
|
+
This is mostly an internal tool - you'll have to spelunk through the code to get a handle on all the options. In due course we'll document everything.
|
19
|
+
|
20
|
+
# Prerequisites
|
21
|
+
On the machine you're deploying from, you'll need:
|
22
|
+
|
23
|
+
* Ruby
|
24
|
+
* GPG 2 (for decrypting secret SSL keys locally)
|
25
|
+
|
26
|
+
# License
|
27
|
+
MIT - see LICENSE.txt
|
28
|
+
|
29
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "capistrano/errorstudio"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "errorstudio_capistrano_recipes"
|
8
|
+
spec.version = ErrorstudioCapistranoRecipes::VERSION
|
9
|
+
spec.authors = ["Ed Jones", "Paul Hendrick"]
|
10
|
+
spec.email = ["ed@error.agency", "paul@error.agency"]
|
11
|
+
|
12
|
+
spec.summary = %q{Error's cap recipes}
|
13
|
+
spec.description = %q{Cap recipes we use to deploy our websites.}
|
14
|
+
spec.homepage = "https://github.com/errorstudio/errorstudio_capistrano_recipes"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
|
26
|
+
#production deps
|
27
|
+
spec.add_dependency 'capistrano', '~>3.11.0'
|
28
|
+
spec.add_dependency 'capistrano-composer', '>=0.0.6'
|
29
|
+
spec.add_dependency 'capistrano-bundler'
|
30
|
+
spec.add_dependency 'capistrano-rails'
|
31
|
+
# spec.add_dependency 'capistrano-rvm'
|
32
|
+
spec.add_dependency 'rvm1-capistrano3'
|
33
|
+
spec.add_dependency 'capistrano-passenger'
|
34
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path("../tasks/ownership.rake", __FILE__)
|
@@ -0,0 +1 @@
|
|
1
|
+
load File.expand_path("../tasks/prompts.rake", __FILE__)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'capistrano/errorstudio'
|
2
|
+
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')
|
3
|
+
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/secrets.yml')
|
4
|
+
set :upstream_proxy_required, true
|
5
|
+
set :upstream_proxy_port, -> {fetch(:passenger_port)}
|
6
|
+
set :upstream_proxy_cache, fetch(:upstream_proxy_cache, true)
|
7
|
+
require 'capistrano/rails'
|
8
|
+
require 'capistrano/rails/assets'
|
9
|
+
# require 'capistrano/rails/migrations'
|
10
|
+
require 'capistrano/errorstudio/nginx'
|
11
|
+
require 'capistrano/errorstudio/passenger'
|
12
|
+
require 'capistrano/errorstudio/rvm'
|
13
|
+
load File.expand_path("../tasks/rails.rake", __FILE__)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
namespace :composer do
|
2
|
+
desc "Set paths for composer and invoke the installation of the composer executable"
|
3
|
+
task :set_paths_and_install do
|
4
|
+
set :composer_working_dir, ->{ File.join(release_path,"public")}
|
5
|
+
set :composer_install_flags, '--no-interaction --optimize-autoloader'
|
6
|
+
SSHKit.config.command_map[:composer] = "php #{shared_path.join("composer.phar")}"
|
7
|
+
invoke "composer:install_executable"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
after "deploy:starting", 'composer:set_paths_and_install'
|
12
|
+
after "deploy:updated", "composer:install"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
namespace :cron do
|
2
|
+
desc "Generate cron scripts"
|
3
|
+
task :generate_cron_scripts do
|
4
|
+
on roles(:web) do
|
5
|
+
fetch(:cron_scripts).each do |cron_time, files|
|
6
|
+
files.each do |cron_template|
|
7
|
+
buffer = ERB.new(File.read(cron_template)).result(binding)+"\n"
|
8
|
+
cron_filename = File.basename(cron_template).gsub(/\.sh\.erb$/, '')
|
9
|
+
upload! StringIO.new(buffer), "#{shared_path}/#{cron_time}.#{File.basename(cron_template)}"
|
10
|
+
execute "sudo mv -f #{shared_path}/#{cron_time}.#{File.basename(cron_template)} /etc/cron.#{cron_time}/#{cron_filename} && sudo chown root:root /etc/cron.#{cron_time}/#{cron_filename} && sudo chmod +x /etc/cron.#{cron_time}/#{cron_filename}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
set :nginx_configuration, fetch(:nginx_configuration, {})
|
2
|
+
set :base_domain, ->{fetch(:base_domain,ask(:base_domain,nil))}
|
3
|
+
set :prelaunch_domain, ->{fetch(:prelaunch_domain,ask(:prelaunch_domain,nil))}
|
4
|
+
set :site_domains, ->{fetch(:site_domains,ask(:site_domains,nil))}
|
5
|
+
set :basic_auth_required, fetch(:basic_auth_required, false)
|
6
|
+
set :ssl_required, fetch(:ssl_required, false)
|
7
|
+
set :deploy_domain, ->{fetch(:deploy_domain,ask(:deploy_domain,nil))}
|
8
|
+
|
9
|
+
namespace :nginx do
|
10
|
+
desc "Check the config exists, and generate if it doesn't"
|
11
|
+
task :check_config do
|
12
|
+
set :nginx_sites_available, "/etc/nginx/sites-available/#{fetch(:deploy_domain)}"
|
13
|
+
set :nginx_sites_enabled, "/etc/nginx/sites-enabled/#{fetch(:deploy_domain)}"
|
14
|
+
on roles(:web) do
|
15
|
+
unless test("[ -f #{"/etc/nginx/sites-enabled/#{fetch(:deploy_domain)}"} ]")
|
16
|
+
invoke "nginx:generate_config"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Generate an Nginx config from a template, with a few prerequisite tasks"
|
22
|
+
task :generate_config => [
|
23
|
+
:generate_ssl,
|
24
|
+
:generate_cloudflare_real_ips,
|
25
|
+
:generate_php,
|
26
|
+
:generate_upstream_proxy,
|
27
|
+
:generate_redirects,
|
28
|
+
:add_basic_auth,
|
29
|
+
:generate_rewrites,
|
30
|
+
:generate_custom_rules,
|
31
|
+
:generate_custom_aliases,
|
32
|
+
:generate_cors,
|
33
|
+
:generate_path_redirects,
|
34
|
+
:generate_proxy_cache
|
35
|
+
] do
|
36
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "nginx_vhost.conf.erb")
|
37
|
+
|
38
|
+
buffer = ERB.new(File.read(file)).result(binding)
|
39
|
+
on roles(:web) do
|
40
|
+
upload! StringIO.new(buffer), "#{shared_path}/#{fetch(:deploy_domain)}"
|
41
|
+
execute "mv #{shared_path}/#{fetch(:deploy_domain)} #{"/etc/nginx/sites-available/#{fetch(:deploy_domain)}"}"
|
42
|
+
execute "ln -nfs #{"/etc/nginx/sites-available/#{fetch(:deploy_domain)}"} #{"/etc/nginx/sites-enabled/#{fetch(:deploy_domain)}"}"
|
43
|
+
invoke 'nginx:reload'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Add basic auth to the nginx config"
|
48
|
+
task :add_basic_auth do
|
49
|
+
#set up the basic auth if the vars are defined
|
50
|
+
if fetch(:basic_auth_required, false)
|
51
|
+
set :basic_auth_realm, "Your username and password are required"
|
52
|
+
# set :basic_auth_username, ->{fetch(:basic_auth_username,ask(:basic_auth_username,nil))}
|
53
|
+
# set :basic_auth_password, ->{fetch(:basic_auth_password,ask(:basic_auth_password,nil))}
|
54
|
+
on roles :web do
|
55
|
+
encrypted_password = `openssl passwd -apr1 #{fetch(:basic_auth_password)}`
|
56
|
+
execute :echo, "'#{fetch(:basic_auth_username)}:#{encrypted_password.chomp}'", "> #{shared_path}/.htpasswd"
|
57
|
+
end
|
58
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "basic_auth.erb")
|
59
|
+
basic_auth = {basic_auth: ERB.new(File.read(file)).result(binding)}
|
60
|
+
set :nginx_configuration, fetch(:nginx_configuration).merge(basic_auth)
|
61
|
+
invoke "deploy:set_ownership"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Reload Nginx"
|
66
|
+
task :reload do
|
67
|
+
on roles(:web) do
|
68
|
+
sudo "/usr/sbin/invoke-rc.d nginx reload"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Generate CORS headers for nginx"
|
73
|
+
task :generate_cors do
|
74
|
+
if fetch(:include_nginx_cors, false)
|
75
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "cors.erb")
|
76
|
+
# generate a hash which is the content of the nginx redirects, with a key
|
77
|
+
cors = {cors: ERB.new(File.read(file)).result(binding)}
|
78
|
+
set :nginx_configuration, fetch(:nginx_configuration).merge(cors)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "Generate custom rules from a hash of rules. NB this is inside the main server block"
|
83
|
+
task :generate_custom_rules do
|
84
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "custom_rules.erb")
|
85
|
+
# generate a hash which is the content of the nginx redirects, with a key
|
86
|
+
rules = {custom_rules: ERB.new(File.read(file)).result(binding)}
|
87
|
+
set :nginx_configuration, fetch(:nginx_configuration).merge(rules)
|
88
|
+
end
|
89
|
+
|
90
|
+
desc "Generate custom aliases from a hash. NB this is inside the main server block"
|
91
|
+
task :generate_custom_aliases do
|
92
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "custom_aliases.erb")
|
93
|
+
# generate a hash which is the content of the nginx redirects, with a key
|
94
|
+
aliases = {custom_aliases: ERB.new(File.read(file)).result(binding)}
|
95
|
+
set :nginx_configuration, fetch(:nginx_configuration).merge(aliases)
|
96
|
+
end
|
97
|
+
|
98
|
+
desc "Generate 301 path redirects from a hash. NB this is inside the main server block"
|
99
|
+
task :generate_path_redirects do
|
100
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "path_redirects.erb")
|
101
|
+
# generate a hash which is the content of the nginx redirects, with a key
|
102
|
+
aliases = {path_redirects: ERB.new(File.read(file)).result(binding)}
|
103
|
+
set :nginx_configuration, fetch(:nginx_configuration).merge(aliases)
|
104
|
+
end
|
105
|
+
|
106
|
+
desc "Generate PHP-FPM proxy and headers"
|
107
|
+
task :generate_php => :generate_ssl do
|
108
|
+
if fetch(:php_required, false)
|
109
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "php.erb")
|
110
|
+
php = {php: ERB.new(File.read(file)).result(binding)}
|
111
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(php)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Generate upstream proxy and headers"
|
116
|
+
task :generate_upstream_proxy => :generate_ssl do
|
117
|
+
if fetch(:upstream_proxy_required, false)
|
118
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "upstream_proxy.erb")
|
119
|
+
upstream = {upstream: ERB.new(File.read(file)).result(binding)}
|
120
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(upstream)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
desc "Generate proxy cache settings"
|
125
|
+
task :generate_proxy_cache => :generate_upstream_proxy do
|
126
|
+
if fetch(:upstream_proxy_cache, false)
|
127
|
+
set :cache_zone, "#{fetch(:application)}_#{fetch(:stage)}"
|
128
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "proxy_cache_path.erb")
|
129
|
+
cache_path = {proxy_cache_path: ERB.new(File.read(file)).result(binding)}
|
130
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(cache_path)
|
131
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "location_proxy_cache.erb")
|
132
|
+
location_proxy_cache = {location_proxy_cache: ERB.new(File.read(file)).result(binding)}
|
133
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(location_proxy_cache)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
desc "Generate redirects in separate server blocks"
|
138
|
+
task :generate_redirects => :generate_ssl do
|
139
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "redirects.erb")
|
140
|
+
# generate a hash which is the content of the nginx redirects, with a key
|
141
|
+
redirects = {domain_redirects: ERB.new(File.read(file)).result(binding)}
|
142
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(redirects)
|
143
|
+
end
|
144
|
+
|
145
|
+
desc "Generate rewrites"
|
146
|
+
task :generate_rewrites do
|
147
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "rewrites.erb")
|
148
|
+
rewrites = {url_rewrites: ERB.new(File.read(file)).result(binding)}
|
149
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(rewrites)
|
150
|
+
end
|
151
|
+
|
152
|
+
desc "Generate SSL settings from files in a specified location"
|
153
|
+
task :generate_ssl do
|
154
|
+
if fetch(:ssl_required, false)
|
155
|
+
set :ip_address, ->{fetch(:ip_address, ask(:ip_address,nil))}
|
156
|
+
set :ssl_cert_path, File.join(fetch(:ssl_dir), fetch(:ssl_cert))
|
157
|
+
set :ssl_key_path, File.join(fetch(:ssl_dir), fetch(:ssl_key))
|
158
|
+
set :ssl_dh_path, File.join(fetch(:ssl_dir), fetch(:ssl_dh))
|
159
|
+
|
160
|
+
unless File.exists?(fetch(:ssl_cert_path)) && File.exists?(fetch(:ssl_key_path)) & File.exists?(fetch(:ssl_dh_path))
|
161
|
+
puts "You need to put your SSL GPG-encrypted key, DH params and cert in the locations you've specified"
|
162
|
+
exit
|
163
|
+
end
|
164
|
+
|
165
|
+
set :gpg_phrase, ask("GPG passphrase for SSL key and DH:",nil)
|
166
|
+
set :ssl_path, "/etc/nginx/ssl"
|
167
|
+
key = `echo #{fetch(:gpg_phrase)} | gpg -d -q --batch --passphrase-fd 0 --no-mdc-warning #{fetch(:ssl_key_path)}`
|
168
|
+
dh = `echo #{fetch(:gpg_phrase)} | gpg -d -q --batch --passphrase-fd 0 --no-mdc-warning #{fetch(:ssl_dh_path)}`
|
169
|
+
set :certificate_sha256, `openssl x509 -in #{fetch(:ssl_cert_path)} -pubkey -noout | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -binary | openssl enc -base64`
|
170
|
+
if $?.success?
|
171
|
+
on roles(:web) do
|
172
|
+
upload! fetch(:ssl_cert_path), "#{fetch(:ssl_path)}/#{fetch(:deploy_domain)}.crt"
|
173
|
+
upload! StringIO.new(key), "#{fetch(:ssl_path)}/#{fetch(:deploy_domain)}.key"
|
174
|
+
upload! StringIO.new(dh), "#{fetch(:ssl_path)}/#{fetch(:deploy_domain)}.pem"
|
175
|
+
end
|
176
|
+
else
|
177
|
+
puts "Incorrect GPG passphrase"
|
178
|
+
exit
|
179
|
+
end
|
180
|
+
|
181
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "ssl_settings.erb")
|
182
|
+
ssl_settings = {ssl_settings: ERB.new(File.read(file)).result(binding)}
|
183
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(ssl_settings)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
desc "Get a list of Cloudflare IPs, and set real ip from the header"
|
188
|
+
task :generate_cloudflare_real_ips do
|
189
|
+
ips = open("https://www.cloudflare.com/ips-v4/").read
|
190
|
+
set :cloudflare_real_ips, ips.gsub(/\<.*>/,"").split("\n")
|
191
|
+
file = File.join(File.dirname(__FILE__), "templates","nginx", "cloudflare_real_ips.erb")
|
192
|
+
cloudflare_ips = {cloudflare_real_ips: ERB.new(File.read(file)).result(binding)}
|
193
|
+
set :nginx_configuration, fetch(:nginx_configuration,{}).merge(cloudflare_ips)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
after "deploy:check", "nginx:check_config"
|
198
|
+
after "nginx:generate_config", "nginx:reload"
|