capistrano-bolt 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +2 -0
- data/capistrano-bolt.gemspec +25 -0
- data/lib/capistrano/bolt/version.rb +5 -0
- data/lib/capistrano/bolt.rb +4 -0
- data/lib/capistrano/tasks/install.rake +39 -0
- data/lib/capistrano/tasks/nginx/nginx.rake +105 -0
- data/lib/capistrano/tasks/postgresql/postgresql.rake +41 -0
- data/lib/capistrano/tasks/puma/puma.rake +147 -0
- data/lib/capistrano/tasks/setup.rake +43 -0
- data/lib/capistrano/templates/dotenv.erb +4 -0
- data/lib/capistrano/templates/nginx/nginx.conf.erb +57 -0
- data/lib/capistrano/templates/postgresql/database.yml.erb +10 -0
- data/lib/capistrano/templates/puma/puma.rb.erb +38 -0
- metadata +106 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6dc82010cdfbbe60dfc1ac1fa897b096298bea39
|
4
|
+
data.tar.gz: 26e247c7189aa4b34bdb821d36049c93d80f8563
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 062cee3c5bbb675ed06487e6f1a4d1ef006eeee7ffd124247bf4a04b85732329d8aeb73df8a7ab7f72d9b3b738c9d48fc11a7f292f924b6c11639ab9e1a01ae0
|
7
|
+
data.tar.gz: f819c70367a14f331cbaf12e67034bf4eda040b959e82c520e647ee9582105b867157dc39988be3c891a395c3bd394548b5f86d20f118c41099feb774d230212
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Shankar Dhanasekaran
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Heroku-like easy deployment for Rails 4 with Capistrano 3, Puma, Nginx and Postgresql.
|
2
|
+
|
3
|
+
As the title says, this gem provides a super simple way to deploy your rails app.
|
4
|
+
I created this after I got tired of trying numerous capistrano receipes and gem. While I learned a lot from these gems and respect their authors for the knowledge shared with the community to the core of my heart, none of the existing gems that I tried simplified the deployment process as I wanted. Here is the workflow that I ever wanted.
|
5
|
+
|
6
|
+
### Prerequisites
|
7
|
+
A server that has postgresql, nginx and ruby installed.
|
8
|
+
|
9
|
+
### Step 1
|
10
|
+
Install a gem on my rails app and issue a command like below
|
11
|
+
|
12
|
+
```
|
13
|
+
cap production setup:all
|
14
|
+
cap production deploy
|
15
|
+
```
|
16
|
+
|
17
|
+
### Step 2
|
18
|
+
|
19
|
+
NO Step 2. No need to login to the server to create nginx vhost file or postgres database or to create environment variables. All these are already taken care by Step 1.
|
20
|
+
|
21
|
+
---
|
22
|
+
|
23
|
+
If you are like me and want a simple deployment process like above then this gem is for you.
|
24
|
+
|
25
|
+
### This gem does the following:
|
26
|
+
1. configuring Nginx for your app by creating vhost file and restarting nginx
|
27
|
+
2. creating postgresql user with a random secure password and granting access to a database
|
28
|
+
3. creates a `.env` file for managing your app's secrets.
|
29
|
+
3. configuring puma app server with the created Nginx vhost file
|
30
|
+
|
31
|
+
---
|
32
|
+
Documentation for using this gem will be shortly updated.
|
33
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'capistrano/bolt/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "capistrano-bolt"
|
8
|
+
spec.version = Capistrano::Bolt::VERSION
|
9
|
+
spec.authors = ["Shankar Dhanasekaran"]
|
10
|
+
spec.email = ["shankar@opendrops.com"]
|
11
|
+
spec.summary = %q{Heroku-like easy deployment for Rails 4 with Capistrano 3, Puma, Nginx and Postgresql.}
|
12
|
+
spec.description = %q{Heroku-like easy deployment for Rails 4 with Capistrano 3, Puma, Nginx and Postgresql.}
|
13
|
+
spec.homepage = "https://github.com/opendrops/capistrano-bolt"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'capistrano', '~> 3.0'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#TODO incomplete task
|
2
|
+
desc 'Install Capistrano, cap install STAGES=staging,production'
|
3
|
+
task :install do
|
4
|
+
clear_actions
|
5
|
+
envs = ENV['STAGES'] || 'staging,production'
|
6
|
+
|
7
|
+
tasks_dir = Pathname.new('lib/capistrano/tasks')
|
8
|
+
config_dir = Pathname.new('config')
|
9
|
+
deploy_dir = config_dir.join('deploy')
|
10
|
+
|
11
|
+
deploy_rb = File.expand_path("../../templates/deploy.rb.erb", __FILE__)
|
12
|
+
stage_rb = File.expand_path("../../templates/stage.rb.erb", __FILE__)
|
13
|
+
capfile = File.expand_path("../../templates/Capfile", __FILE__)
|
14
|
+
|
15
|
+
mkdir_p deploy_dir
|
16
|
+
|
17
|
+
template = File.read(deploy_rb)
|
18
|
+
file = config_dir.join('deploy.rb')
|
19
|
+
File.open(file, 'w+') do |f|
|
20
|
+
f.write(ERB.new(template).result(binding))
|
21
|
+
puts I18n.t(:written_file, scope: :capistrano, file: file)
|
22
|
+
end
|
23
|
+
|
24
|
+
template = File.read(stage_rb)
|
25
|
+
envs.split(',').each do |stage|
|
26
|
+
file = deploy_dir.join("#{stage}.rb")
|
27
|
+
File.open(file, 'w+') do |f|
|
28
|
+
f.write(ERB.new(template).result(binding))
|
29
|
+
puts I18n.t(:written_file, scope: :capistrano, file: file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
mkdir_p tasks_dir
|
34
|
+
|
35
|
+
FileUtils.cp(capfile, 'Capfile')
|
36
|
+
|
37
|
+
|
38
|
+
puts I18n.t :capified, scope: :capistrano
|
39
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :nginx_service_path, -> { 'service nginx' }
|
4
|
+
set :nginx_roles, -> { :web }
|
5
|
+
set :nginx_log_path, -> { "#{shared_path}/log" }
|
6
|
+
set :nginx_root_path, -> { "/etc/nginx" }
|
7
|
+
set :nginx_static_dir, -> { "public" }
|
8
|
+
set :nginx_sites_enabled, -> { "sites-enabled" }
|
9
|
+
set :nginx_sites_available, -> { "sites-available" }
|
10
|
+
set :nginx_template, -> { :default }
|
11
|
+
set :nginx_use_ssl, -> { false }
|
12
|
+
set :app_server, -> { true }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
namespace :nginx do
|
17
|
+
task :load_vars do
|
18
|
+
set :sites_available, -> { File.join(fetch(:nginx_root_path), fetch(:nginx_sites_available)) }
|
19
|
+
set :sites_enabled, -> { File.join(fetch(:nginx_root_path), fetch(:nginx_sites_enabled)) }
|
20
|
+
set :enabled_application, -> { File.join(fetch(:sites_enabled), fetch(:application)) }
|
21
|
+
set :available_application, -> { File.join(fetch(:sites_available), fetch(:application)) }
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "Remove default Nginx Virtual Host"
|
25
|
+
task "remove_default_vhost" do
|
26
|
+
on roles(:app) do
|
27
|
+
if test("[ -f /etc/nginx/sites-enabled/default ]")
|
28
|
+
sudo "rm /etc/nginx/sites-enabled/default"
|
29
|
+
puts "removed default Nginx Virtualhost"
|
30
|
+
else
|
31
|
+
puts "No default Nginx Virtualhost to remove"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
%w[start stop restart reload].each do |command|
|
37
|
+
desc "#{command.capitalize} nginx service"
|
38
|
+
task command do
|
39
|
+
nginx_service = fetch(:nginx_service_path)
|
40
|
+
on release_roles fetch(:nginx_roles) do
|
41
|
+
if command === 'stop' || (test "[ $(sudo #{nginx_service} configtest | grep -c 'fail') -eq 0 ]")
|
42
|
+
execute :sudo, "#{nginx_service} #{command}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
after 'deploy:check', nil do
|
49
|
+
on release_roles fetch(:nginx_roles) do
|
50
|
+
execute :mkdir, '-pv', fetch(:nginx_log_path)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
namespace :site do
|
56
|
+
desc 'Creates the site configuration and upload it to the available folder'
|
57
|
+
task :add => ['nginx:load_vars'] do
|
58
|
+
on release_roles fetch(:nginx_roles) do
|
59
|
+
within fetch(:sites_available) do
|
60
|
+
config_file = fetch(:nginx_template)
|
61
|
+
if config_file == :default
|
62
|
+
config_file = File.expand_path('../../../templates/nginx/nginx.conf.erb', __FILE__)
|
63
|
+
end
|
64
|
+
config = ERB.new(File.read(config_file)).result(binding)
|
65
|
+
upload! StringIO.new(config), '/tmp/nginx.conf'
|
66
|
+
|
67
|
+
execute :sudo, :mv, '/tmp/nginx.conf', fetch(:application)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
desc 'Enables the site creating a symbolic link into the enabled folder'
|
73
|
+
task :enable => ['nginx:load_vars'] do
|
74
|
+
on release_roles fetch(:nginx_roles) do
|
75
|
+
if test "! [ -h #{fetch(:enabled_application)} ]"
|
76
|
+
within fetch(:sites_enabled) do
|
77
|
+
execute :sudo, :ln, '-nfs', fetch(:available_application), fetch(:enabled_application)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
desc 'Disables the site removing the symbolic link located in the enabled folder'
|
84
|
+
task :disable => ['nginx:load_vars'] do
|
85
|
+
on release_roles fetch(:nginx_roles) do
|
86
|
+
if test "[ -f #{fetch(:enabled_application)} ]"
|
87
|
+
within fetch(:sites_enabled) do
|
88
|
+
execute :sudo, :rm, '-f', fetch(:application)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'Removes the site removing the configuration file from the available folder'
|
95
|
+
task :remove => ['nginx:load_vars'] do
|
96
|
+
on release_roles fetch(:nginx_roles) do
|
97
|
+
if test "[ -f #{fetch(:available_application)} ]"
|
98
|
+
within fetch(:sites_available) do
|
99
|
+
execute :sudo, :rm, fetch(:application)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :postgresql_admin, "postgres"
|
4
|
+
set :postgresql_host, "localhost"
|
5
|
+
set :postgresql_user, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
|
6
|
+
set :postgresql_password, SecureRandom.hex(40)
|
7
|
+
set :postgresql_database, -> { "#{fetch(:application)}_#{fetch(:stage)}" }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
namespace :postgresql do
|
12
|
+
|
13
|
+
desc "Create the database role for this application"
|
14
|
+
task :create_role do
|
15
|
+
on primary(:db) do
|
16
|
+
output = capture "sudo -u #{fetch(:postgresql_admin)} psql postgres -tAc \"SELECT 1 FROM pg_roles WHERE rolname='#{fetch(:postgresql_user)}'\""
|
17
|
+
if !output.empty?
|
18
|
+
abort "User already exists."
|
19
|
+
else
|
20
|
+
info "User does not exist. Creating a new one with password #{fetch(:postgresql_password)}"
|
21
|
+
execute %Q{sudo -u #{fetch(:postgresql_admin)} psql -c "create user #{fetch(:postgresql_user)} with password '#{fetch(:postgresql_password)}';"}
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Create the database for this application"
|
28
|
+
task :create_db do
|
29
|
+
on primary(:db) do
|
30
|
+
output = capture "sudo -u #{fetch(:postgresql_admin)} psql -tAc \"SELECT 1 FROM pg_database WHERE datname='#{fetch(:postgresql_database)}'\""
|
31
|
+
if !output.empty?
|
32
|
+
warn "Database already exists. Using the existing one."
|
33
|
+
else
|
34
|
+
info "Database does not exist. Creating a new one."
|
35
|
+
execute %Q{sudo -u #{fetch(:postgresql_admin)} createdb "#{fetch(:postgresql_database)}" -O "#{fetch(:postgresql_user)}"}
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
namespace :load do
|
2
|
+
task :defaults do
|
3
|
+
set :puma_role, :app
|
4
|
+
set :puma_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) }
|
5
|
+
# Configure "min" to be the minimum number of threads to use to answer
|
6
|
+
# requests and "max" the maximum.
|
7
|
+
set :puma_threads, [0, 16]
|
8
|
+
set :puma_workers, 0
|
9
|
+
set :puma_rackup, -> { File.join(current_path, 'config.ru') }
|
10
|
+
set :puma_state, -> { File.join(shared_path, 'tmp', 'pids', 'puma.state') }
|
11
|
+
set :puma_pid, -> { File.join(shared_path, 'tmp', 'pids', 'puma.pid') }
|
12
|
+
set :puma_bind, -> { File.join('unix://', shared_path, 'tmp', 'sockets', 'puma.sock') }
|
13
|
+
set :puma_conf, -> { File.join(shared_path, 'puma.rb') }
|
14
|
+
set :puma_access_log, -> { File.join(shared_path, 'log', 'puma_access.log') }
|
15
|
+
set :puma_error_log, -> { File.join(shared_path, 'log', 'puma_error.log') }
|
16
|
+
set :puma_init_active_record, false
|
17
|
+
set :puma_preload_app, true
|
18
|
+
|
19
|
+
# Rbenv and RVM integration
|
20
|
+
set :rbenv_map_bins, fetch(:rbenv_map_bins).to_a.concat(%w{ puma pumactl })
|
21
|
+
set :rvm_map_bins, fetch(:rvm_map_bins).to_a.concat(%w{ puma pumactl })
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
namespace :puma do
|
26
|
+
|
27
|
+
desc 'Setup Puma config file'
|
28
|
+
task :config do
|
29
|
+
on roles(fetch(:puma_role)) do |role|
|
30
|
+
template_puma 'puma', fetch(:puma_conf), role
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'Start puma'
|
35
|
+
task :start do
|
36
|
+
on roles (fetch(:puma_role)) do
|
37
|
+
within current_path do
|
38
|
+
with rack_env: fetch(:puma_env) do
|
39
|
+
|
40
|
+
execute :bundle, 'exec', :puma, "-C #{fetch(:puma_conf)}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
%w[halt stop status].map do |command|
|
47
|
+
desc "#{command} puma"
|
48
|
+
task command do
|
49
|
+
on roles (fetch(:puma_role)) do
|
50
|
+
within current_path do
|
51
|
+
with rack_env: fetch(:puma_env) do
|
52
|
+
if test "[ -f #{fetch(:puma_pid)} ]"
|
53
|
+
if test "kill -0 $( cat #{fetch(:puma_pid)} )"
|
54
|
+
execute :bundle, 'exec', :pumactl, "-S #{fetch(:puma_state)} #{command}"
|
55
|
+
else
|
56
|
+
# delete invalid pid file , process is not running.
|
57
|
+
execute :rm, fetch(:puma_pid)
|
58
|
+
end
|
59
|
+
else
|
60
|
+
#pid file not found, so puma is probably not running or it using another pidfile
|
61
|
+
warn 'Puma not running'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
%w[phased-restart restart].map do |command|
|
70
|
+
desc "#{command} puma"
|
71
|
+
task command do
|
72
|
+
on roles (fetch(:puma_role)) do
|
73
|
+
within current_path do
|
74
|
+
with rack_env: fetch(:puma_env) do
|
75
|
+
if test "[ -f #{fetch(:puma_pid)} ]" and test "kill -0 $( cat #{fetch(:puma_pid)} )"
|
76
|
+
# NOTE pid exist but state file is nonsense, so ignore that case
|
77
|
+
execute :bundle, 'exec', :pumactl, "-S #{fetch(:puma_state)} #{command}"
|
78
|
+
else
|
79
|
+
# Puma is not running or state file is not present : Run it
|
80
|
+
execute :bundle, 'exec', :puma, "-C #{fetch(:puma_conf)}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
task :check do
|
89
|
+
on roles (fetch(:puma_role)) do |role|
|
90
|
+
#Create puma.rb for new deployments
|
91
|
+
unless test "[ -f #{fetch(:puma_conf)} ]"
|
92
|
+
warn 'puma.rb NOT FOUND!'
|
93
|
+
#TODO DRY
|
94
|
+
template_puma 'puma', fetch(:puma_conf), role
|
95
|
+
info 'puma.rb generated'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
after 'deploy:check', 'puma:check'
|
100
|
+
|
101
|
+
task :smart_restart do
|
102
|
+
if puma_workers.to_i > 1
|
103
|
+
invoke 'puma:phased-restart'
|
104
|
+
else
|
105
|
+
invoke 'puma:restart'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
after 'deploy:finished', 'puma:smart_restart'
|
109
|
+
|
110
|
+
|
111
|
+
def puma_workers
|
112
|
+
fetch(:puma_workers) || 0
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
def puma_bind
|
118
|
+
case fetch(:puma_bind)
|
119
|
+
when Array
|
120
|
+
fetch(:puma_bind).collect do |bind|
|
121
|
+
"bind '#{bind}'"
|
122
|
+
end.join("\n")
|
123
|
+
else
|
124
|
+
"bind '#{fetch(:puma_bind)}'"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def template_puma(from, to, role)
|
129
|
+
[
|
130
|
+
"lib/capistrano/templates/puma/#{from}-#{role.hostname}-#{fetch(:stage)}.rb",
|
131
|
+
"lib/capistrano/templates/puma/#{from}-#{role.hostname}.rb",
|
132
|
+
"lib/capistrano/templates/puma/#{from}-#{fetch(:stage)}.rb",
|
133
|
+
"lib/capistrano/templates/puma/#{from}.rb.erb",
|
134
|
+
"lib/capistrano/templates/puma/#{from}.rb",
|
135
|
+
"lib/capistrano/templates/puma/#{from}.erb",
|
136
|
+
File.expand_path("../../../templates/puma/#{from}.rb.erb", __FILE__),
|
137
|
+
File.expand_path("../../../templates/puma/#{from}.erb", __FILE__)
|
138
|
+
].each do |path|
|
139
|
+
if File.file?(path)
|
140
|
+
erb = File.read(path)
|
141
|
+
upload! StringIO.new(ERB.new(erb).result(binding)), to
|
142
|
+
break
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# Setup all the necessary server side services for the first time
|
2
|
+
# when an app is being deployed
|
3
|
+
namespace :setup do
|
4
|
+
|
5
|
+
desc "Configure the database and role for this application"
|
6
|
+
task :postgresql do
|
7
|
+
invoke "postgresql:create_role"
|
8
|
+
invoke "postgresql:create_db"
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'add site, enable and reload nginx'
|
12
|
+
task :nginx do
|
13
|
+
invoke 'nginx:site:add'
|
14
|
+
invoke 'nginx:site:enable'
|
15
|
+
invoke 'nginx:restart'
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'create folders for deploy on server and configure nginx and postgres'
|
19
|
+
task :all do
|
20
|
+
on roles(:app) do
|
21
|
+
invoke 'deploy:check:directories'
|
22
|
+
invoke 'deploy:check:linked_dirs'
|
23
|
+
invoke 'setup:nginx'
|
24
|
+
invoke 'setup:postgresql'
|
25
|
+
invoke 'setup:dotenv'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'create a dotenv file for secure environment data'
|
30
|
+
task :dotenv do
|
31
|
+
on roles(:app) do
|
32
|
+
from = File.expand_path("../../templates/dotenv.erb", __FILE__)
|
33
|
+
to = File.join(shared_path, '.env')
|
34
|
+
upload_template(from, to)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def upload_template(from, to)
|
39
|
+
erb = File.read(from)
|
40
|
+
upload! StringIO.new(ERB.new(erb).result(binding)), to
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
upstream <%= fetch(:application) %>_puma {
|
2
|
+
server unix:<%= fetch(:deploy_to) %>/shared/tmp/sockets/puma.sock;
|
3
|
+
}
|
4
|
+
|
5
|
+
server {
|
6
|
+
server_name <%= fetch(:server_name) %>;
|
7
|
+
listen 80;
|
8
|
+
root <%= fetch(:deploy_to) %>/current/public;
|
9
|
+
|
10
|
+
location ^~ /assets/ {
|
11
|
+
gzip_static on;
|
12
|
+
expires max;
|
13
|
+
add_header Cache-Control public;
|
14
|
+
}
|
15
|
+
|
16
|
+
try_files $uri/index.html $uri @puma;
|
17
|
+
location @puma {
|
18
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
19
|
+
proxy_set_header Host $http_host;
|
20
|
+
proxy_redirect off;
|
21
|
+
proxy_pass http://<%= fetch(:application) %>_puma;
|
22
|
+
}
|
23
|
+
|
24
|
+
error_page 500 502 503 504 /500.html;
|
25
|
+
client_max_body_size 4G;
|
26
|
+
keepalive_timeout 10;
|
27
|
+
}
|
28
|
+
|
29
|
+
<% if fetch(:enable_ssl) %>
|
30
|
+
server {
|
31
|
+
server_name <%= fetch(:server_name) %>;
|
32
|
+
listen 443;
|
33
|
+
root <%= fetch(:deploy_to) %>/current/public;
|
34
|
+
|
35
|
+
location ^~ /assets/ {
|
36
|
+
gzip_static on;
|
37
|
+
expires max;
|
38
|
+
add_header Cache-Control public;
|
39
|
+
}
|
40
|
+
|
41
|
+
try_files $uri/index.html $uri @puma;
|
42
|
+
location @puma {
|
43
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
44
|
+
proxy_set_header X-Forwarded-Proto https;
|
45
|
+
proxy_set_header Host $http_host;
|
46
|
+
proxy_redirect off;
|
47
|
+
proxy_pass http://<%= fetch(:application) %>_puma;
|
48
|
+
}
|
49
|
+
|
50
|
+
error_page 500 502 503 504 /500.html;
|
51
|
+
client_max_body_size 4G;
|
52
|
+
keepalive_timeout 10;
|
53
|
+
ssl on;
|
54
|
+
ssl_certificate <%= fetch(:deploy_to) %>/shared/ssl_cert.crt;
|
55
|
+
ssl_certificate_key <%= fetch(:deploy_to) %>/shared/ssl_private_key.key;
|
56
|
+
}#
|
57
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= fetch(:stage) %>:
|
2
|
+
adapter: postgresql
|
3
|
+
timeout: 5000
|
4
|
+
encoding: utf8
|
5
|
+
reconnect: false
|
6
|
+
database: <%= "#{fetch(:postgresql_user)}" %>
|
7
|
+
pool: 5
|
8
|
+
username: <%= "#{fetch(:postgresql_database)}" %>
|
9
|
+
host: <%= "#{fetch(:postgresql_host)}" %>
|
10
|
+
port: 5432
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env puma
|
2
|
+
|
3
|
+
directory '<%= current_path %>'
|
4
|
+
rackup "<%=fetch(:puma_rackup)%>"
|
5
|
+
environment '<%= fetch(:puma_env) %>'
|
6
|
+
<% if fetch(:puma_tag) %>
|
7
|
+
tag '<%= fetch(:puma_tag)%>'
|
8
|
+
<% end %>
|
9
|
+
daemonize true
|
10
|
+
pidfile "<%=fetch(:puma_pid)%>"
|
11
|
+
state_path "<%=fetch(:puma_state)%>"
|
12
|
+
stdout_redirect '<%=fetch(:puma_access_log)%>', '<%=fetch(:puma_error_log)%>', true
|
13
|
+
|
14
|
+
|
15
|
+
threads <%=fetch(:puma_threads).join(',')%>
|
16
|
+
|
17
|
+
<%= puma_bind %>
|
18
|
+
workers <%= puma_workers %>
|
19
|
+
<% if fetch(:puma_worker_timeout) %>
|
20
|
+
worker_timeout <%= fetch(:puma_worker_timeout).to_i %>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% if fetch(:puma_preload_app) %>
|
24
|
+
preload_app!
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
on_restart do
|
28
|
+
puts 'Refreshing Gemfile'
|
29
|
+
ENV["BUNDLE_GEMFILE"] = "<%= fetch(:bundle_gemfile, "#{current_path}/Gemfile") %>"
|
30
|
+
end
|
31
|
+
|
32
|
+
<% if fetch(:puma_init_active_record) %>
|
33
|
+
on_worker_boot do
|
34
|
+
ActiveSupport.on_load(:active_record) do
|
35
|
+
ActiveRecord::Base.establish_connection
|
36
|
+
end
|
37
|
+
end
|
38
|
+
<% end %>
|
metadata
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-bolt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shankar Dhanasekaran
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capistrano
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Heroku-like easy deployment for Rails 4 with Capistrano 3, Puma, Nginx
|
56
|
+
and Postgresql.
|
57
|
+
email:
|
58
|
+
- shankar@opendrops.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- capistrano-bolt.gemspec
|
69
|
+
- lib/capistrano/bolt.rb
|
70
|
+
- lib/capistrano/bolt/version.rb
|
71
|
+
- lib/capistrano/tasks/install.rake
|
72
|
+
- lib/capistrano/tasks/nginx/nginx.rake
|
73
|
+
- lib/capistrano/tasks/postgresql/postgresql.rake
|
74
|
+
- lib/capistrano/tasks/puma/puma.rake
|
75
|
+
- lib/capistrano/tasks/setup.rake
|
76
|
+
- lib/capistrano/templates/dotenv.erb
|
77
|
+
- lib/capistrano/templates/nginx/nginx.conf.erb
|
78
|
+
- lib/capistrano/templates/postgresql/database.yml.erb
|
79
|
+
- lib/capistrano/templates/puma/puma.rb.erb
|
80
|
+
homepage: https://github.com/opendrops/capistrano-bolt
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.2.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Heroku-like easy deployment for Rails 4 with Capistrano 3, Puma, Nginx and
|
104
|
+
Postgresql.
|
105
|
+
test_files: []
|
106
|
+
has_rdoc:
|