capistrano-zen 0.0.2
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.
- data/.gitignore +17 -0
- data/Capfile-rails.sample +51 -0
- data/Capfile-static.sample +52 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +156 -0
- data/Rakefile +1 -0
- data/capistrano-zen.gemspec +24 -0
- data/lib/capistrano-zen/base.rb +15 -0
- data/lib/capistrano-zen/common.rb +10 -0
- data/lib/capistrano-zen/nginx.rb +40 -0
- data/lib/capistrano-zen/nodejs.rb +18 -0
- data/lib/capistrano-zen/postgresql.rb +81 -0
- data/lib/capistrano-zen/rbenv.rb +52 -0
- data/lib/capistrano-zen/tmpls/nginx_static.erb +12 -0
- data/lib/capistrano-zen/tmpls/nginx_unicorn.erb +33 -0
- data/lib/capistrano-zen/tmpls/postgresql.yml.erb +8 -0
- data/lib/capistrano-zen/tmpls/unicorn.rb.erb +89 -0
- data/lib/capistrano-zen/tmpls/unicorn_init.erb +84 -0
- data/lib/capistrano-zen/unicorn.rb +34 -0
- data/lib/capistrano-zen/utils.rb +35 -0
- data/lib/capistrano-zen/version.rb +5 -0
- metadata +84 -0
data/.gitignore
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# default capistrano tasks
|
|
2
|
+
load 'deploy'
|
|
3
|
+
load 'deploy/assets'
|
|
4
|
+
|
|
5
|
+
# the database.yml path
|
|
6
|
+
set :pg_config_path, File.expand_path(File.dirname(__FILE__), 'config')
|
|
7
|
+
|
|
8
|
+
# load the recipes
|
|
9
|
+
require 'capistrano-zen/utils'
|
|
10
|
+
require 'capistrano-zen/nginx'
|
|
11
|
+
require 'capistrano-zen/postgresql'
|
|
12
|
+
require 'capistrano-zen/rbenv'
|
|
13
|
+
require 'capistrano-zen/unicorn'
|
|
14
|
+
|
|
15
|
+
# Use Git as Version Control System
|
|
16
|
+
set :scm, :git
|
|
17
|
+
set :repository, "git@github.com:zenhacks/some_application.git"
|
|
18
|
+
set :branch, 'master'
|
|
19
|
+
|
|
20
|
+
# enable prompt for password
|
|
21
|
+
default_run_options[:pty] = true
|
|
22
|
+
|
|
23
|
+
# access github.com using as the local user
|
|
24
|
+
ssh_options[:forward_agent] = true
|
|
25
|
+
|
|
26
|
+
set :application, 'my_application'
|
|
27
|
+
|
|
28
|
+
set :domain, "domain.com"
|
|
29
|
+
|
|
30
|
+
server 'domain.com', :web, :app, :db, :primary => true
|
|
31
|
+
|
|
32
|
+
set :user, 'deploy'
|
|
33
|
+
set :group, 'deploy'
|
|
34
|
+
set :deploy_to, "/home/#{user}/repositories/#{application}-production"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## Deploy Dependencies
|
|
38
|
+
after "deploy:install",
|
|
39
|
+
"nginx:install",
|
|
40
|
+
"nodejs:install",
|
|
41
|
+
"rbenv:install",
|
|
42
|
+
"dev_lib:install",
|
|
43
|
+
"pg:install"
|
|
44
|
+
|
|
45
|
+
after "deploy:setup",
|
|
46
|
+
"nginx:setup",
|
|
47
|
+
"pg:setup",
|
|
48
|
+
"pg:init",
|
|
49
|
+
"unicorn:setup"
|
|
50
|
+
|
|
51
|
+
after "deploy:finalize_update", "pg:symlink"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'capistrano-zen/nginx'
|
|
2
|
+
|
|
3
|
+
# enable prompt for password
|
|
4
|
+
default_run_options[:pty] = true
|
|
5
|
+
|
|
6
|
+
# try_sudo will not use sudo by default
|
|
7
|
+
set :use_sudo, false
|
|
8
|
+
|
|
9
|
+
# access github.com using as the local user
|
|
10
|
+
ssh_options[:forward_agent] = true
|
|
11
|
+
|
|
12
|
+
set :application, "application name"
|
|
13
|
+
|
|
14
|
+
set :domain, "domain.com"
|
|
15
|
+
|
|
16
|
+
# maxwell - 42.121.82.106, aliyun,hangzhou
|
|
17
|
+
server 'server_name', :web, :app, :db, :primary => true
|
|
18
|
+
|
|
19
|
+
set :user, 'deploy'
|
|
20
|
+
set :deploy_to, "/home/#{user}/sites/#{application}-production"
|
|
21
|
+
|
|
22
|
+
namespace :deploy do
|
|
23
|
+
desc "Deploys your project. This calls both `update' and `nginx.restart'. "
|
|
24
|
+
task :default, roles: :app do
|
|
25
|
+
update
|
|
26
|
+
nginx.restart
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "Setup the directory for the application."
|
|
30
|
+
task :setup, roles: :app do
|
|
31
|
+
dirs = [deploy_to]
|
|
32
|
+
run "mkdir -p #{dirs.join(' ')}"
|
|
33
|
+
run "chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
desc "Update the dest code for this application."
|
|
37
|
+
task :update, roles: :app do
|
|
38
|
+
# your own deploy logic
|
|
39
|
+
|
|
40
|
+
# sample for a middleman site
|
|
41
|
+
# system('bundle exec middleman build --clean')
|
|
42
|
+
# roles[:app].servers.each do |server|
|
|
43
|
+
# system("rsync -cuavz build/* #{user}@#{server}:#{deploy_to}")
|
|
44
|
+
# end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
after "deploy:install",
|
|
49
|
+
"nginx:install"
|
|
50
|
+
|
|
51
|
+
after "deploy:setup",
|
|
52
|
+
"nginx:setup:static"
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2012 Steven Yang
|
|
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,156 @@
|
|
|
1
|
+
## What Capistrano::Zen Is?
|
|
2
|
+
`Capistrano-zen` is **a collection of capistrano recipes** to install and manage various services on production machine powered by Ubuntu. The current tested environment is Ubuntu 12.04LTS.
|
|
3
|
+
|
|
4
|
+
It provides installation and management recipes for the following service:
|
|
5
|
+
- nginx
|
|
6
|
+
- with config templates for rails app
|
|
7
|
+
- nodejs
|
|
8
|
+
- postgresql
|
|
9
|
+
- unicorn (integrated with a nginx/railsapp)
|
|
10
|
+
- rbenv
|
|
11
|
+
|
|
12
|
+
The upcoming recipes include:
|
|
13
|
+
- nginx
|
|
14
|
+
- global config template
|
|
15
|
+
- static website template
|
|
16
|
+
- shorewall
|
|
17
|
+
- vsftp
|
|
18
|
+
- php-fpm
|
|
19
|
+
- mysql
|
|
20
|
+
- mongodb
|
|
21
|
+
- redis
|
|
22
|
+
|
|
23
|
+
`capistrano-zen` is extracted from the deployment procedure at [zenhacks.org](zenhacks.org) for a Rails application so it is designed to work with the structure of a rails application. But most recipes are independent and future development will detach general recipes from a rails application.
|
|
24
|
+
|
|
25
|
+
## What Capistrano::Zen isn't?
|
|
26
|
+
`capistrano-zen` only provides recipes of tasks, it doesn't handle:
|
|
27
|
+
|
|
28
|
+
- the application dependencies
|
|
29
|
+
- the logic of deployment logic
|
|
30
|
+
- the server settings and configuration
|
|
31
|
+
|
|
32
|
+
You will need to declare those in your own capistrano config file such as `Capfile` or `config/deploy.rb`.
|
|
33
|
+
|
|
34
|
+
The gem includes some sample files to start with `Capfile-rails.sample`.
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
Add this line to your application's Gemfile:
|
|
39
|
+
|
|
40
|
+
gem 'capistrano-zen'
|
|
41
|
+
|
|
42
|
+
And then execute:
|
|
43
|
+
|
|
44
|
+
$ bundle
|
|
45
|
+
|
|
46
|
+
Or install it yourself as:
|
|
47
|
+
|
|
48
|
+
$ gem install capistrano-zen
|
|
49
|
+
|
|
50
|
+
## Dependencies
|
|
51
|
+
`capistrano-zen` uses `python-software-properties` to ease ppa source addition. You could install it with use `python-software-properties` to ease ppa source addition. You could install it from your local machine with
|
|
52
|
+
|
|
53
|
+
cap deploy:install
|
|
54
|
+
|
|
55
|
+
Or install it mannually with
|
|
56
|
+
|
|
57
|
+
sudo apt-get install python-software-properties
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
To load a set of recipes, require them in your `Capfile` with:
|
|
62
|
+
|
|
63
|
+
require 'capistrano-zen/nginx'
|
|
64
|
+
|
|
65
|
+
You could verify the load is successful with:
|
|
66
|
+
|
|
67
|
+
cap -T
|
|
68
|
+
|
|
69
|
+
## Recipes
|
|
70
|
+
Here is the recipes included in this gem:
|
|
71
|
+
|
|
72
|
+
- nginx
|
|
73
|
+
- with config templates for rails app
|
|
74
|
+
- nodejs
|
|
75
|
+
- postgresql
|
|
76
|
+
- unicorn (integrated with a nginx/railsapp)
|
|
77
|
+
- rbenv
|
|
78
|
+
|
|
79
|
+
### Nginx
|
|
80
|
+
Default role: `web`
|
|
81
|
+
|
|
82
|
+
Configuration variables: none
|
|
83
|
+
|
|
84
|
+
Tasks:
|
|
85
|
+
- `nginx:install` installs the lastest release from the ppa `ppa:nginx/stable`.
|
|
86
|
+
- `nginx:start/stop/reload` maps to `sudo service nginx start/stop/reload` on the remote machine.
|
|
87
|
+
- `nginx:setup` generates a nginx site configuration for a rails app runs with `unicorn` through unix socket.
|
|
88
|
+
|
|
89
|
+
### NodeJS
|
|
90
|
+
Default role: `app`
|
|
91
|
+
|
|
92
|
+
Configuration variables: none
|
|
93
|
+
|
|
94
|
+
Tasks:
|
|
95
|
+
- `nodejs:install` installs `node` and `npm` from the `ppa:chris-lea/node.js`.
|
|
96
|
+
|
|
97
|
+
The ppa comes from [official wiki](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager).
|
|
98
|
+
|
|
99
|
+
### Rbenv
|
|
100
|
+
It uses the [rbenv installer](https://github.com/fesplugas/rbenv-installer) to create a `ruby` environment.
|
|
101
|
+
|
|
102
|
+
Default role: `app`
|
|
103
|
+
|
|
104
|
+
Configuration variables:
|
|
105
|
+
- `ruby_version` indicates the ruby version installed.
|
|
106
|
+
- `rbenv_bootstrap` indicates the ubuntu version to install the rbenv bootstrap.
|
|
107
|
+
|
|
108
|
+
Tasks:
|
|
109
|
+
- `rbenv:install` installs `rbenv`, setups configuration in `~/.bashrc` and installs `ruby` with `ruby_version`
|
|
110
|
+
- `rbenv:patch` autoruns a ruby patch to enhance performance. [more info](https://gist.github.com/1688857?utm_source=rubyweekly&utm_medium=email)
|
|
111
|
+
|
|
112
|
+
### PostgreSQL
|
|
113
|
+
Currently, postgresql configuration is tightly attached to a rails application, it depends on the `config/database.yml` to setup remote server.
|
|
114
|
+
|
|
115
|
+
Default role: `db`
|
|
116
|
+
|
|
117
|
+
Configuration variables:
|
|
118
|
+
- `pg_config_path` the path for the `database.yml` file, the recipe reads from it to create database and generate remote `database.yml`. If you are using this recipe out of Rails application, store your configuration in a `config/database.yml`.
|
|
119
|
+
- `pg_backup_path` the path to store database dumps.
|
|
120
|
+
|
|
121
|
+
Tasks:
|
|
122
|
+
- `pg:install` installs `postgresql` and `libpg-dev` from `ppa:pitti/postgresql`.
|
|
123
|
+
- `pg:reset` drops the databases and roles with the same names as in the application.
|
|
124
|
+
- `pg:init` generates roles and databases for the rails application.
|
|
125
|
+
- `pg:setup` generates remote `database.yml` based on local `database.yml`'s `production` settings.
|
|
126
|
+
- `pg:symlink` creates symbolic for the `database.yml` in the release.
|
|
127
|
+
- `pg:dump` dumps and compresses the application database, store them in the `pg_backup_path`.
|
|
128
|
+
- `pg:restore` prompts and restores selected dumps from the `pg_backup_path`, it defaults to lastest dump.
|
|
129
|
+
|
|
130
|
+
### Unicorn
|
|
131
|
+
This recipes setup unicorn configuration based on current rails application, and generate a `init.d` control scripts to manage the service.
|
|
132
|
+
Default role: `app`
|
|
133
|
+
|
|
134
|
+
Configuration variables:
|
|
135
|
+
- `unicorn_user` the user to run unicorn process, default to the same user as remote login user.
|
|
136
|
+
- `unicorn_group` the group to run unicorn process.
|
|
137
|
+
- `unicorn_pid` the path for the `unicorn.pid` file, default to the `current/tmp/pids/unicorn.pid`.
|
|
138
|
+
- `unicorn_config` the path to put the unicorn config file, default to `shared/config/unicorn.rb`.
|
|
139
|
+
- `unicorn_log` the path to put the unicorn log file, default to `shared/log/unicorn.log`.
|
|
140
|
+
- `unicorn_workers` the number of unicorn workers, default to 4.
|
|
141
|
+
|
|
142
|
+
Tasks:
|
|
143
|
+
- `unicorn:setup` generate `unicorn.rb` config file and register `service` with `unicorn_init`.
|
|
144
|
+
- `unicorn:start/stop/restart/upgrade/force-stop` maps to remote `service unicorn start/stop/restart/upgrade/force-stop`. Details is in `/tmpls/unicorn_init.rb`
|
|
145
|
+
|
|
146
|
+
### Utils
|
|
147
|
+
- `check:revision` autoruns before any deployment tasks. It compares the local and remote master branch head to make sure remote master branch are up-to-date.
|
|
148
|
+
- `dev_lib:install` install libraries on which some gems depend such as `nokogiri` or `paperclip`.
|
|
149
|
+
|
|
150
|
+
## Get Started with Capistrano
|
|
151
|
+
The [wiki page](https://github.com/capistrano/capistrano/wiki) of `capistrano` has good resources to make you up to speed.
|
|
152
|
+
[Railscasts](http://railscasts.com/episodes?utf8=%E2%9C%93&search=capistrano) also has a good coverage for this tool.
|
|
153
|
+
|
|
154
|
+
## TODO
|
|
155
|
+
- make configuration rails-less
|
|
156
|
+
- add more recipes
|
data/Rakefile
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "bundler/gem_tasks"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'capistrano-zen/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |gem|
|
|
7
|
+
gem.name = "capistrano-zen"
|
|
8
|
+
gem.version = Capistrano::Zen::VERSION
|
|
9
|
+
gem.authors = ["Steven Yang"]
|
|
10
|
+
gem.email = ["yangchenyun@gmail.com"]
|
|
11
|
+
gem.description = %q{Capistrano Recipes used at zenhacks.org.}
|
|
12
|
+
gem.summary = %q{Nginx, Unicorn, PostgreSQL, NodeJS Recipes install on a machine running Ubuntu. }
|
|
13
|
+
gem.homepage = ""
|
|
14
|
+
|
|
15
|
+
gem.files = `git ls-files`.split($/)
|
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
18
|
+
gem.require_paths = ["lib"]
|
|
19
|
+
gem.extra_rdoc_files = [
|
|
20
|
+
"LICENSE"
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
gem.add_dependency "capistrano", ">= 2.5.3"
|
|
24
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
require 'capistrano-zen/common'
|
|
2
|
+
|
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
5
|
+
Capistrano.configuration(:must_exist)
|
|
6
|
+
|
|
7
|
+
configuration.load do
|
|
8
|
+
namespace :deploy do
|
|
9
|
+
desc "Install everything onto the server"
|
|
10
|
+
task :install do
|
|
11
|
+
run "#{sudo} apt-get -y update"
|
|
12
|
+
run "#{sudo} apt-get -y install python-software-properties"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'capistrano-zen/base'
|
|
2
|
+
|
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
5
|
+
Capistrano.configuration(:must_exist)
|
|
6
|
+
|
|
7
|
+
configuration.load do
|
|
8
|
+
namespace :nginx do
|
|
9
|
+
desc "Install latest stable release of nginx"
|
|
10
|
+
task :install, roles: :web do
|
|
11
|
+
run "#{sudo} add-apt-repository -y ppa:nginx/stable"
|
|
12
|
+
run "#{sudo} apt-get -y update"
|
|
13
|
+
run "#{sudo} apt-get -y install nginx"
|
|
14
|
+
run "#{sudo} rm -f /etc/nginx/sites-enabled/default"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
namespace :setup do
|
|
18
|
+
desc "Setup nginx configuration for unicorn application"
|
|
19
|
+
task :unicorn, roles: :web do
|
|
20
|
+
template "nginx_unicorn.erb", "/tmp/nginx_conf"
|
|
21
|
+
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-enabled/#{application}"
|
|
22
|
+
restart
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
desc "Setup nginx configuration for static website"
|
|
26
|
+
task :static, roles: :web do
|
|
27
|
+
template "nginx_static.erb", "/tmp/nginx_conf"
|
|
28
|
+
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-enabled/#{application}"
|
|
29
|
+
restart
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
%w[start stop restart reload].each do |command|
|
|
34
|
+
desc "#{command} nginx"
|
|
35
|
+
task command, roles: :web do
|
|
36
|
+
run "#{sudo} service nginx #{command}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'capistrano-zen/base'
|
|
2
|
+
|
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
5
|
+
Capistrano.configuration(:must_exist)
|
|
6
|
+
|
|
7
|
+
configuration.load do
|
|
8
|
+
namespace :nodejs do
|
|
9
|
+
desc "Install the latest relase of Node.js"
|
|
10
|
+
# Reference
|
|
11
|
+
# https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
|
|
12
|
+
task :install, roles: :app do
|
|
13
|
+
run "#{sudo} add-apt-repository -y ppa:chris-lea/node.js"
|
|
14
|
+
run "#{sudo} apt-get -y update"
|
|
15
|
+
run "#{sudo} apt-get -y install nodejs npm"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require 'capistrano-zen/base'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
5
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
6
|
+
Capistrano.configuration(:must_exist)
|
|
7
|
+
|
|
8
|
+
configuration.load do
|
|
9
|
+
|
|
10
|
+
_cset(:pg_config_path) { abort "[Error] posgtresql recipes need `pg_config_path` to find the database.yml file." }
|
|
11
|
+
_cset(:pg_backup_path) { abort "[Error] posgtresql recipes need `pg_backup_path` to execute backups." }
|
|
12
|
+
|
|
13
|
+
DB_FILE_PATH = "#{pg_config_path}/database.yml"
|
|
14
|
+
DBCONFIG = YAML.load_file(DB_FILE_PATH)
|
|
15
|
+
|
|
16
|
+
_cset(:psql_host) { DBCONFIG['production']['host'] }
|
|
17
|
+
_cset(:psql_user) { DBCONFIG['production']['username'] }
|
|
18
|
+
_cset(:psql_password) { DBCONFIG['production']['password'] }
|
|
19
|
+
_cset(:psql_database) { DBCONFIG['production']['database'] }
|
|
20
|
+
|
|
21
|
+
namespace :pg do
|
|
22
|
+
desc "Install the latest stable release of psql."
|
|
23
|
+
task :install, roles: :db, only: {primary: true} do
|
|
24
|
+
run "#{sudo} add-apt-repository -y ppa:pitti/psql"
|
|
25
|
+
run "#{sudo} apt-get -y update"
|
|
26
|
+
run "#{sudo} apt-get -y install psql libpq-dev"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
desc "Create a database for this application."
|
|
30
|
+
task :init, roles: :db, only: { primary: true } do
|
|
31
|
+
# reset the database and role
|
|
32
|
+
run %Q{#{sudo} -u postgres psql -c "CREATE USER #{psql_user} WITH PASSWORD '#{psql_password}';"}
|
|
33
|
+
run %Q{#{sudo} -u postgres psql -c "CREATE DATABASE #{psql_database} OWNER #{psql_user};"}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
desc "Reset the database and role for this application."
|
|
37
|
+
task :reset, roles: :db, only: { primary: true } do
|
|
38
|
+
# drop the database and role
|
|
39
|
+
run %Q{#{sudo} -u postgres psql -c "DROP DATABASE #{psql_database};"}
|
|
40
|
+
run %Q{#{sudo} -u postgres psql -c "DROP ROLE #{psql_user};"}
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc "Generate the database.yml configuration file."
|
|
44
|
+
task :setup, roles: :app do
|
|
45
|
+
run "mkdir -p #{shared_path}/config"
|
|
46
|
+
template "postgresql.yml.erb", "#{shared_path}/config/database.yml"
|
|
47
|
+
# init backup directory
|
|
48
|
+
run "#{sudo} mkdir -p #{pg_backup_path}"
|
|
49
|
+
run "#{sudo} chown :#{group} #{pg_backup_path}"
|
|
50
|
+
run "#{sudo} chmod g+w #{pg_backup_path}"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
desc "Symlink the database.yml file into latest release"
|
|
54
|
+
task :symlink, roles: :app do
|
|
55
|
+
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
desc "Dump the application's database to backup path."
|
|
59
|
+
task :dump, roles: :db, only: { primary: true } do
|
|
60
|
+
# ignore migrations / exclude ownership / clean restore
|
|
61
|
+
run "pg_dump #{psql_database} -T '*migrations' -O -c -U #{psql_user} -h #{psql_host} | gzip > #{pg_backup_path}/#{application}-#{release_name}.sql.gz" do |channel, stream, data|
|
|
62
|
+
puts data if data.length >= 3
|
|
63
|
+
channel.send_data("#{psql_password}\n") if data.include? 'Password'
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
desc "Restore the application's database from dump files."
|
|
68
|
+
task :restore, roles: :db, only: { primary: true } do
|
|
69
|
+
backups = capture("ls -x #{pg_backup_path}").split.sort
|
|
70
|
+
default_backup = backups.last
|
|
71
|
+
puts "Available backups: "
|
|
72
|
+
puts backups
|
|
73
|
+
backup = Capistrano::CLI.ui.ask "Which backup would you like to restore? [#{default_backup}] "
|
|
74
|
+
backup = backups.last if backup.empty?
|
|
75
|
+
run "gunzip -c #{pg_backup_path}/#{backup} | psql -d #{psql_database} -U #{psql_user} -h #{psql_host}" do |channel, stream, data|
|
|
76
|
+
puts data if data.length >= 3
|
|
77
|
+
channel.send_data("#{psql_password}\n") if data.include? 'Password'
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require 'capistrano-zen/base'
|
|
2
|
+
|
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
5
|
+
Capistrano.configuration(:must_exist)
|
|
6
|
+
|
|
7
|
+
configuration.load do
|
|
8
|
+
_cset :ruby_version, "1.9.3-p194"
|
|
9
|
+
_cset :rbenv_bootstrap, "bootstrap-ubuntu-12-04"
|
|
10
|
+
_cset(:root_password) { Capistrano::CLI.password_prompt "Root Password: " }
|
|
11
|
+
|
|
12
|
+
# https://github.com/fesplugas/rbenv-installer
|
|
13
|
+
namespace :rbenv do
|
|
14
|
+
desc "Install rbenv, Ruby, and the Bundler gem"
|
|
15
|
+
task :install, roles: :app do
|
|
16
|
+
run "#{sudo} apt-get -y install curl git-core"
|
|
17
|
+
run "curl -L https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash"
|
|
18
|
+
# FIXME run command to change download path to taobao
|
|
19
|
+
bashrc = <<-BASHRC
|
|
20
|
+
if [ -d $HOME/.rbenv ]; then
|
|
21
|
+
export PATH="$HOME/.rbenv/bin:$PATH"
|
|
22
|
+
eval "$(rbenv init -)"
|
|
23
|
+
fi
|
|
24
|
+
BASHRC
|
|
25
|
+
put bashrc, "/tmp/rbenvrc"
|
|
26
|
+
run "cat /tmp/rbenvrc ~/.bashrc > ~/.bashrc.tmp"
|
|
27
|
+
run "mv ~/.bashrc.tmp ~/.bashrc"
|
|
28
|
+
run "rm /tmp/rbenvrc"
|
|
29
|
+
run "rbenv #{rbenv_bootstrap}" do |channel, stream, data|
|
|
30
|
+
puts data if data.length >= 3
|
|
31
|
+
channel.send_data("#{root_password}\n") if data.include? 'password'
|
|
32
|
+
end
|
|
33
|
+
run "rbenv install #{ruby_version}"
|
|
34
|
+
run "rbenv global #{ruby_version}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
task :patch, roles: :app do
|
|
38
|
+
# the performance patch
|
|
39
|
+
# https://gist.github.com/1688857?utm_source=rubyweekly&utm_medium=email
|
|
40
|
+
run "#{sudo} apt-get -y install autoconf"
|
|
41
|
+
case "#{ruby_version}"
|
|
42
|
+
when "1.9.3-p194"
|
|
43
|
+
run "curl https://raw.github.com/gist/1688857/rbenv.sh | sh ; rbenv global 1.9.3-p194-perf"
|
|
44
|
+
when "1.9.3-p286"
|
|
45
|
+
run "curl https://raw.github.com/gist/3885178/rbenv.sh | sh ; rbenv global 1.9.3-p286-perf"
|
|
46
|
+
end
|
|
47
|
+
run "gem install bundler --no-ri --no-rdoc"
|
|
48
|
+
run "rbenv rehash"
|
|
49
|
+
end
|
|
50
|
+
after "rbenv:install", "rbenv:patch"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
server {
|
|
2
|
+
listen 80;
|
|
3
|
+
server_name <%= domain %>;
|
|
4
|
+
|
|
5
|
+
root <%= deploy_to %>;
|
|
6
|
+
gzip_static on;
|
|
7
|
+
|
|
8
|
+
access_log /var/log/nginx/<%= application %>-access.log;
|
|
9
|
+
error_log /var/log/nginx/<%= application %>-error.log;
|
|
10
|
+
|
|
11
|
+
error_page 500 502 503 504 /500.html;
|
|
12
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
upstream <%= application %>_unicorn {
|
|
2
|
+
server unix:/tmp/unicorn.<%= application %>.sock fail_timeout=0;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
server {
|
|
6
|
+
listen 80;
|
|
7
|
+
server_name <%= domain %>;
|
|
8
|
+
|
|
9
|
+
access_log /var/log/nginx/<%= application %>-access.log;
|
|
10
|
+
error_log /var/log/nginx/<%= application %>-error.log;
|
|
11
|
+
|
|
12
|
+
root <%= current_path %>/public;
|
|
13
|
+
|
|
14
|
+
location ^~ /assets/ {
|
|
15
|
+
gzip_static on;
|
|
16
|
+
expires max;
|
|
17
|
+
add_header Cache-Control public;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
# try to serve static file first
|
|
21
|
+
try_files $uri/index.html $uri @unicorn;
|
|
22
|
+
|
|
23
|
+
location @unicorn {
|
|
24
|
+
proxy_set_header Host $http_host;
|
|
25
|
+
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
|
|
26
|
+
proxy_redirect off;
|
|
27
|
+
proxy_pass http://<%= application %>_unicorn;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
error_page 500 502 503 504 /500.html;
|
|
31
|
+
client_max_body_size 100M;
|
|
32
|
+
keepalive_timeout 10;
|
|
33
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
RAILS_ENV = ENV['RAILS_ENV'] || 'production'
|
|
2
|
+
|
|
3
|
+
# unicorn workers
|
|
4
|
+
worker_processes <%= unicorn_workers %>
|
|
5
|
+
|
|
6
|
+
# FIXME problems here
|
|
7
|
+
# working_directory "<%= current_path %>"
|
|
8
|
+
|
|
9
|
+
# Load rails+github.git into the master before forking workers
|
|
10
|
+
# for super-fast worker spawn times
|
|
11
|
+
preload_app true
|
|
12
|
+
|
|
13
|
+
# Restart any workers that haven't responded in 30 seconds
|
|
14
|
+
timeout 30
|
|
15
|
+
|
|
16
|
+
pid "<%= unicorn_pid %>"
|
|
17
|
+
stderr_path "<%= current_path %>/log/unicorn.stderr.log"
|
|
18
|
+
stdout_path "<%= current_path %>/log/unicorn.stdout.log"
|
|
19
|
+
|
|
20
|
+
# Listen on a Unix data socket
|
|
21
|
+
listen '/tmp/unicorn.<%= application %>.sock', :backlog => 2048
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# REE
|
|
25
|
+
|
|
26
|
+
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
|
|
27
|
+
if GC.respond_to?(:copy_on_write_friendly=)
|
|
28
|
+
GC.copy_on_write_friendly = true
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
before_fork do |server, worker|
|
|
33
|
+
##
|
|
34
|
+
# When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
|
|
35
|
+
# immediately start loading up a new version of itself (loaded with a new
|
|
36
|
+
# version of our app). When this new Unicorn is completely loaded
|
|
37
|
+
# it will begin spawning workers. The first worker spawned will check to
|
|
38
|
+
# see if an .oldbin pidfile exists. If so, this means we've just booted up
|
|
39
|
+
# a new Unicorn and need to tell the old one that it can now die. To do so
|
|
40
|
+
# we send it a QUIT.
|
|
41
|
+
#
|
|
42
|
+
# Using this method we get 0 downtime deploys.
|
|
43
|
+
|
|
44
|
+
old_pid = '<%= unicorn_pid %>.oldbin'
|
|
45
|
+
if File.exists?(old_pid) && server.pid != old_pid
|
|
46
|
+
begin
|
|
47
|
+
Process.kill("QUIT", File.read(old_pid).to_i)
|
|
48
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
|
49
|
+
# someone else did our job for us
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
after_fork do |server, worker|
|
|
56
|
+
##
|
|
57
|
+
# Unicorn master loads the app then forks off workers - because of the way
|
|
58
|
+
# Unix forking works, we need to make sure we aren't using any of the parent's
|
|
59
|
+
# sockets, e.g. db connection
|
|
60
|
+
|
|
61
|
+
ActiveRecord::Base.establish_connection
|
|
62
|
+
# CHIMNEY.client.connect_to_server
|
|
63
|
+
# Redis and Memcached would go here but their connections are established
|
|
64
|
+
# on demand, so the master never opens a socket
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
##
|
|
68
|
+
# Unicorn master is started as root, which is fine, but let's
|
|
69
|
+
# drop the workers to deploy:deploy
|
|
70
|
+
|
|
71
|
+
begin
|
|
72
|
+
uid, gid = Process.euid, Process.egid
|
|
73
|
+
user, group = '<%= unicorn_user %>', '<%= unicorn_group %>'
|
|
74
|
+
target_uid = Etc.getpwnam(user).uid
|
|
75
|
+
target_gid = Etc.getgrnam(group).gid
|
|
76
|
+
worker.tmp.chown(target_uid, target_gid)
|
|
77
|
+
if uid != target_uid || gid != target_gid
|
|
78
|
+
Process.initgroups(user, target_gid)
|
|
79
|
+
Process::GID.change_privilege(target_gid)
|
|
80
|
+
Process::UID.change_privilege(target_uid)
|
|
81
|
+
end
|
|
82
|
+
rescue => e
|
|
83
|
+
if RAILS_ENV == 'development'
|
|
84
|
+
STDERR.puts "couldn't change user, oh well"
|
|
85
|
+
else
|
|
86
|
+
raise e
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
### BEGIN INIT INFO
|
|
3
|
+
# Provides: unicorn
|
|
4
|
+
# Required-Start: $remote_fs $syslog
|
|
5
|
+
# Required-Stop: $remote_fs $syslog
|
|
6
|
+
# Default-Start: 2 3 4 5
|
|
7
|
+
# Default-Stop: 0 1 6
|
|
8
|
+
# Short-Description: Manage unicorn server
|
|
9
|
+
# Description: Start, stop, restart unicorn server for a specific application.
|
|
10
|
+
### END INIT INFO
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
# Feel free to change any of the following variables for your app:
|
|
14
|
+
TIMEOUT=${TIMEOUT-60}
|
|
15
|
+
APP_ROOT=<%= current_path %>
|
|
16
|
+
PID=<%= unicorn_pid %>
|
|
17
|
+
CMD="cd <%= current_path %>; bundle exec unicorn -D -c <%= unicorn_config %> -E production"
|
|
18
|
+
AS_USER=<%= unicorn_user %>
|
|
19
|
+
set -u
|
|
20
|
+
|
|
21
|
+
OLD_PIN="$PID.oldbin"
|
|
22
|
+
|
|
23
|
+
sig () {
|
|
24
|
+
test -s "$PID" && kill -$1 `cat $PID`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
oldsig () {
|
|
28
|
+
test -s $OLD_PIN && kill -$1 `cat $OLD_PIN`
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
run () {
|
|
32
|
+
if [ "$(id -un)" = "$AS_USER" ]; then
|
|
33
|
+
eval $1
|
|
34
|
+
else
|
|
35
|
+
su -c "$1" - $AS_USER
|
|
36
|
+
fi
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
case "$1" in
|
|
40
|
+
start)
|
|
41
|
+
sig 0 && echo >&2 "Already running" && exit 0
|
|
42
|
+
run "$CMD"
|
|
43
|
+
;;
|
|
44
|
+
stop)
|
|
45
|
+
sig QUIT && exit 0
|
|
46
|
+
echo >&2 "Not running"
|
|
47
|
+
;;
|
|
48
|
+
force-stop)
|
|
49
|
+
sig TERM && exit 0
|
|
50
|
+
echo >&2 "Not running"
|
|
51
|
+
;;
|
|
52
|
+
restart|reload)
|
|
53
|
+
sig HUP && echo reloaded OK && exit 0
|
|
54
|
+
echo >&2 "Couldn't reload, starting '$CMD' instead"
|
|
55
|
+
run "$CMD"
|
|
56
|
+
;;
|
|
57
|
+
upgrade)
|
|
58
|
+
if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
|
|
59
|
+
then
|
|
60
|
+
n=$TIMEOUT
|
|
61
|
+
while test -s $OLD_PIN && test $n -ge 0
|
|
62
|
+
do
|
|
63
|
+
printf '.' && sleep 1 && n=$(( $n - 1 ))
|
|
64
|
+
done
|
|
65
|
+
echo
|
|
66
|
+
|
|
67
|
+
if test $n -lt 0 && test -s $OLD_PIN
|
|
68
|
+
then
|
|
69
|
+
echo >&2 "$OLD_PIN still exists after $TIMEOUT seconds"
|
|
70
|
+
exit 1
|
|
71
|
+
fi
|
|
72
|
+
exit 0
|
|
73
|
+
fi
|
|
74
|
+
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
|
|
75
|
+
run "$CMD"
|
|
76
|
+
;;
|
|
77
|
+
reopen-logs)
|
|
78
|
+
sig USR1
|
|
79
|
+
;;
|
|
80
|
+
*)
|
|
81
|
+
echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
|
|
82
|
+
exit 1
|
|
83
|
+
;;
|
|
84
|
+
esac
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'capistrano-zen/base'
|
|
2
|
+
|
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
5
|
+
Capistrano.configuration(:must_exist)
|
|
6
|
+
|
|
7
|
+
configuration.load do
|
|
8
|
+
_cset(:unicorn_user) { user }
|
|
9
|
+
_cset(:unicorn_group) { group }
|
|
10
|
+
_cset(:unicorn_pid) { "#{current_path}/tmp/pids/unicorn.pid" }
|
|
11
|
+
_cset(:unicorn_config) { "#{shared_path}/config/unicorn.rb" }
|
|
12
|
+
_cset(:unicorn_log) { "#{shared_path}/log/unicorn.log" }
|
|
13
|
+
_cset(:unicorn_workers, 4)
|
|
14
|
+
|
|
15
|
+
namespace :unicorn do
|
|
16
|
+
desc "Setup Unicorn initializer and app configuration"
|
|
17
|
+
task :setup, roles: :app do
|
|
18
|
+
run "mkdir -p #{shared_path}/config"
|
|
19
|
+
template "unicorn.rb.erb", unicorn_config
|
|
20
|
+
template "unicorn_init.erb", "/tmp/unicorn_init"
|
|
21
|
+
run "chmod +x /tmp/unicorn_init"
|
|
22
|
+
run "#{sudo} mv /tmp/unicorn_init /etc/init.d/unicorn_#{application}"
|
|
23
|
+
run "#{sudo} update-rc.d -f unicorn_#{application} defaults"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
%w[start stop restart upgrade force-stop].each do |command|
|
|
27
|
+
desc "#{command} unicorn"
|
|
28
|
+
task command, roles: :app do
|
|
29
|
+
run "service unicorn_#{application} #{command}"
|
|
30
|
+
end
|
|
31
|
+
after "deploy:#{command}", "unicorn:#{command}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'capistrano-zen/base'
|
|
2
|
+
|
|
3
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
4
|
+
Capistrano::Configuration.instance(:must_exist) :
|
|
5
|
+
Capistrano.configuration(:must_exist)
|
|
6
|
+
|
|
7
|
+
configuration.load do
|
|
8
|
+
before "deploy", "check:revision"
|
|
9
|
+
before "deploy:migrations", "check:revision"
|
|
10
|
+
before "deploy:cold", "check:revision"
|
|
11
|
+
|
|
12
|
+
namespace :check do
|
|
13
|
+
desc "Make sure local git is in sync with remote."
|
|
14
|
+
task :revision do
|
|
15
|
+
unless `git rev-parse #{branch}` == `git rev-parse origin/#{branch}`
|
|
16
|
+
puts "WARNING: HEAD is not the same as origin/#{branch}"
|
|
17
|
+
puts "Run `git push` to sync changes."
|
|
18
|
+
exit
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
namespace :dev_lib do
|
|
24
|
+
task :install do
|
|
25
|
+
# nokogiri dependencies
|
|
26
|
+
run "#{sudo} apt-get -y install libxslt-dev libxml2-dev"
|
|
27
|
+
|
|
28
|
+
# paperclip dependencies
|
|
29
|
+
run "#{sudo} apt-get -y install imagemagick"
|
|
30
|
+
|
|
31
|
+
# sqlite3 dependencies
|
|
32
|
+
run "#{sudo} apt-get -y install libsqlite3-dev"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: capistrano-zen
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Steven Yang
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-11-15 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: capistrano
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: 2.5.3
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 2.5.3
|
|
30
|
+
description: Capistrano Recipes used at zenhacks.org.
|
|
31
|
+
email:
|
|
32
|
+
- yangchenyun@gmail.com
|
|
33
|
+
executables: []
|
|
34
|
+
extensions: []
|
|
35
|
+
extra_rdoc_files:
|
|
36
|
+
- LICENSE
|
|
37
|
+
files:
|
|
38
|
+
- .gitignore
|
|
39
|
+
- Capfile-rails.sample
|
|
40
|
+
- Capfile-static.sample
|
|
41
|
+
- Gemfile
|
|
42
|
+
- LICENSE
|
|
43
|
+
- README.md
|
|
44
|
+
- Rakefile
|
|
45
|
+
- capistrano-zen.gemspec
|
|
46
|
+
- lib/capistrano-zen/base.rb
|
|
47
|
+
- lib/capistrano-zen/common.rb
|
|
48
|
+
- lib/capistrano-zen/nginx.rb
|
|
49
|
+
- lib/capistrano-zen/nodejs.rb
|
|
50
|
+
- lib/capistrano-zen/postgresql.rb
|
|
51
|
+
- lib/capistrano-zen/rbenv.rb
|
|
52
|
+
- lib/capistrano-zen/tmpls/nginx_static.erb
|
|
53
|
+
- lib/capistrano-zen/tmpls/nginx_unicorn.erb
|
|
54
|
+
- lib/capistrano-zen/tmpls/postgresql.yml.erb
|
|
55
|
+
- lib/capistrano-zen/tmpls/unicorn.rb.erb
|
|
56
|
+
- lib/capistrano-zen/tmpls/unicorn_init.erb
|
|
57
|
+
- lib/capistrano-zen/unicorn.rb
|
|
58
|
+
- lib/capistrano-zen/utils.rb
|
|
59
|
+
- lib/capistrano-zen/version.rb
|
|
60
|
+
homepage: ''
|
|
61
|
+
licenses: []
|
|
62
|
+
post_install_message:
|
|
63
|
+
rdoc_options: []
|
|
64
|
+
require_paths:
|
|
65
|
+
- lib
|
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
67
|
+
none: false
|
|
68
|
+
requirements:
|
|
69
|
+
- - ! '>='
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '0'
|
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
requirements: []
|
|
79
|
+
rubyforge_project:
|
|
80
|
+
rubygems_version: 1.8.24
|
|
81
|
+
signing_key:
|
|
82
|
+
specification_version: 3
|
|
83
|
+
summary: Nginx, Unicorn, PostgreSQL, NodeJS Recipes install on a machine running Ubuntu.
|
|
84
|
+
test_files: []
|