capistrano-zen 0.0.2 → 0.0.4
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/Capfile-rails-farigo.sample +64 -0
- data/Capfile-rails-mysql.sample +60 -0
- data/{Capfile-rails.sample → Capfile-rails-postgresql.sample} +12 -3
- data/README.md +30 -10
- data/capistrano-zen.gemspec +1 -0
- data/lib/capistrano-zen/base.rb +1 -1
- data/lib/capistrano-zen/common.rb +1 -1
- data/lib/capistrano-zen/config.rb +31 -0
- data/lib/capistrano-zen/mysql.rb +155 -0
- data/lib/capistrano-zen/nginx.rb +19 -3
- data/lib/capistrano-zen/nodejs.rb +1 -1
- data/lib/capistrano-zen/postgresql.rb +74 -27
- data/lib/capistrano-zen/redis.rb +23 -0
- data/lib/capistrano-zen/tmpls/mysql.yml.erb +8 -0
- data/lib/capistrano-zen/tmpls/nginx_unicorn.erb +8 -2
- data/lib/capistrano-zen/tmpls/nginx_wordpress.erb +49 -0
- data/lib/capistrano-zen/tmpls/postgresql.yml.erb +2 -1
- data/lib/capistrano-zen/tmpls/unicorn.rb.erb +56 -53
- data/lib/capistrano-zen/tmpls/unicorn_init.erb +1 -1
- data/lib/capistrano-zen/tmpls/wp-config.php.erb +74 -0
- data/lib/capistrano-zen/version.rb +1 -1
- data/lib/capistrano-zen/wordpress.rb +19 -0
- metadata +35 -15
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 790154ec5aca0ee50a3b28ab70a166e9bd63e5fa
|
|
4
|
+
data.tar.gz: be4028936c26a2cced22887968ec37f61e210225
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 3c9242904d99e8175fffc204376763599c8af77aadf8e7e319c18b7316ad9268e08158365853d3eadfa67f5e7bb355a34c32bf09bb8d7477d4f187778bd89dbf
|
|
7
|
+
data.tar.gz: 401227ddce5e8c9f8fa7bafee09ee41070149c1886e8753c05879dd8448391dd12378f22fb2c6cc73a19dff0fc0ba13820816071215ad9fc54cd8165804ddf1f
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# default capistrano tasks
|
|
2
|
+
load 'deploy'
|
|
3
|
+
load 'deploy/assets'
|
|
4
|
+
|
|
5
|
+
# the database.yml path
|
|
6
|
+
set :config_path, File.expand_path(File.dirname(__FILE__), 'config')
|
|
7
|
+
set :db_backup_path, '/var/backups/db'
|
|
8
|
+
|
|
9
|
+
# load the recipes
|
|
10
|
+
require 'capistrano-zen/utils'
|
|
11
|
+
require 'capistrano-zen/nginx'
|
|
12
|
+
require 'capistrano-zen/nodejs'
|
|
13
|
+
require 'capistrano-zen/postgresql'
|
|
14
|
+
require 'capistrano-zen/rbenv'
|
|
15
|
+
require 'capistrano-zen/unicorn'
|
|
16
|
+
require 'capistrano-zen/config'
|
|
17
|
+
|
|
18
|
+
# Use Git as Version Control System
|
|
19
|
+
set :scm, :git
|
|
20
|
+
set :repository, "git@github.com:zenhacks/some_application.git"
|
|
21
|
+
set :branch, 'master'
|
|
22
|
+
|
|
23
|
+
# enable prompt for password
|
|
24
|
+
default_run_options[:pty] = true
|
|
25
|
+
|
|
26
|
+
# access github.com using as the local user
|
|
27
|
+
ssh_options[:forward_agent] = true
|
|
28
|
+
|
|
29
|
+
set :application, 'my_application'
|
|
30
|
+
|
|
31
|
+
set :domain, "domain.com"
|
|
32
|
+
|
|
33
|
+
set :unicorn_workers, 1
|
|
34
|
+
|
|
35
|
+
set :rails_env, "production"
|
|
36
|
+
|
|
37
|
+
server 'domain.com', :web, :app, :db, :primary => true
|
|
38
|
+
|
|
39
|
+
set :user, 'deploy'
|
|
40
|
+
set :group, 'deploy'
|
|
41
|
+
set :deploy_to, "/home/#{user}/repositories/#{application}-production"
|
|
42
|
+
|
|
43
|
+
## Deploy Dependencies
|
|
44
|
+
after "deploy:install",
|
|
45
|
+
"nginx:install",
|
|
46
|
+
"nodejs:install",
|
|
47
|
+
"rbenv:install",
|
|
48
|
+
"dev_lib:install",
|
|
49
|
+
"pg:install"
|
|
50
|
+
|
|
51
|
+
after "deploy:setup",
|
|
52
|
+
"nginx:setup",
|
|
53
|
+
"pg:setup",
|
|
54
|
+
"pg:init",
|
|
55
|
+
# using application.yml to setup application environment variables
|
|
56
|
+
"config:setup",
|
|
57
|
+
"unicorn:setup"
|
|
58
|
+
|
|
59
|
+
# dump database before a new successful release
|
|
60
|
+
before "config:db:symlink", "pg:dump"
|
|
61
|
+
after "deploy:finalize_update",
|
|
62
|
+
# symlink application.yml
|
|
63
|
+
"config:env:symlink"
|
|
64
|
+
"config:db:symlink"
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# default capistrano tasks
|
|
2
|
+
load 'deploy'
|
|
3
|
+
load 'deploy/assets'
|
|
4
|
+
|
|
5
|
+
# the database.yml path
|
|
6
|
+
set :config_path, File.expand_path(File.dirname(__FILE__), 'config')
|
|
7
|
+
set :db_backup_path, '/var/backups/db'
|
|
8
|
+
|
|
9
|
+
# load the recipes
|
|
10
|
+
require 'capistrano-zen/utils'
|
|
11
|
+
require 'capistrano-zen/nginx'
|
|
12
|
+
require 'capistrano-zen/nodejs'
|
|
13
|
+
require 'capistrano-zen/mysql'
|
|
14
|
+
require 'capistrano-zen/rbenv'
|
|
15
|
+
require 'capistrano-zen/unicorn'
|
|
16
|
+
require 'capistrano-zen/config'
|
|
17
|
+
|
|
18
|
+
# Use Git as Version Control System
|
|
19
|
+
set :scm, :git
|
|
20
|
+
set :repository, "git@github.com:zenhacks/some_application.git"
|
|
21
|
+
set :branch, 'master'
|
|
22
|
+
|
|
23
|
+
# enable prompt for password
|
|
24
|
+
default_run_options[:pty] = true
|
|
25
|
+
|
|
26
|
+
# access github.com using as the local user
|
|
27
|
+
ssh_options[:forward_agent] = true
|
|
28
|
+
|
|
29
|
+
set :application, 'my_application'
|
|
30
|
+
|
|
31
|
+
set :domain, "domain.com"
|
|
32
|
+
|
|
33
|
+
set :unicorn_workers, 1
|
|
34
|
+
|
|
35
|
+
set :rails_env, "production"
|
|
36
|
+
|
|
37
|
+
server 'domain.com', :web, :app, :db, :primary => true
|
|
38
|
+
|
|
39
|
+
set :user, 'deploy'
|
|
40
|
+
set :group, 'deploy'
|
|
41
|
+
set :deploy_to, "/home/#{user}/repositories/#{application}-production"
|
|
42
|
+
|
|
43
|
+
## Deploy Dependencies
|
|
44
|
+
after "deploy:install",
|
|
45
|
+
"nginx:install",
|
|
46
|
+
"nodejs:install",
|
|
47
|
+
"rbenv:install",
|
|
48
|
+
"dev_lib:install",
|
|
49
|
+
"mysql:install"
|
|
50
|
+
|
|
51
|
+
after "deploy:setup",
|
|
52
|
+
"nginx:setup",
|
|
53
|
+
"mysql:setup",
|
|
54
|
+
"mysql:init",
|
|
55
|
+
"unicorn:setup"
|
|
56
|
+
|
|
57
|
+
# dump database before a new successful release
|
|
58
|
+
before "config:db:symlink", "mysql:dump"
|
|
59
|
+
after "deploy:finalize_update",
|
|
60
|
+
"config:db:symlink"
|
|
@@ -3,14 +3,17 @@ load 'deploy'
|
|
|
3
3
|
load 'deploy/assets'
|
|
4
4
|
|
|
5
5
|
# the database.yml path
|
|
6
|
-
set :
|
|
6
|
+
set :config_path, File.expand_path(File.dirname(__FILE__), 'config')
|
|
7
|
+
set :db_backup_path, '/var/backups/db'
|
|
7
8
|
|
|
8
9
|
# load the recipes
|
|
9
10
|
require 'capistrano-zen/utils'
|
|
10
11
|
require 'capistrano-zen/nginx'
|
|
12
|
+
require 'capistrano-zen/nodejs'
|
|
11
13
|
require 'capistrano-zen/postgresql'
|
|
12
14
|
require 'capistrano-zen/rbenv'
|
|
13
15
|
require 'capistrano-zen/unicorn'
|
|
16
|
+
require 'capistrano-zen/config'
|
|
14
17
|
|
|
15
18
|
# Use Git as Version Control System
|
|
16
19
|
set :scm, :git
|
|
@@ -27,13 +30,16 @@ set :application, 'my_application'
|
|
|
27
30
|
|
|
28
31
|
set :domain, "domain.com"
|
|
29
32
|
|
|
33
|
+
set :unicorn_workers, 1
|
|
34
|
+
|
|
35
|
+
set :rails_env, "production"
|
|
36
|
+
|
|
30
37
|
server 'domain.com', :web, :app, :db, :primary => true
|
|
31
38
|
|
|
32
39
|
set :user, 'deploy'
|
|
33
40
|
set :group, 'deploy'
|
|
34
41
|
set :deploy_to, "/home/#{user}/repositories/#{application}-production"
|
|
35
42
|
|
|
36
|
-
|
|
37
43
|
## Deploy Dependencies
|
|
38
44
|
after "deploy:install",
|
|
39
45
|
"nginx:install",
|
|
@@ -48,4 +54,7 @@ after "deploy:setup",
|
|
|
48
54
|
"pg:init",
|
|
49
55
|
"unicorn:setup"
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
# dump database before a new successful release
|
|
58
|
+
before "config:db:symlink", "pg:dump"
|
|
59
|
+
after "deploy:finalize_update",
|
|
60
|
+
"config:db:symlink",
|
data/README.md
CHANGED
|
@@ -4,21 +4,21 @@
|
|
|
4
4
|
It provides installation and management recipes for the following service:
|
|
5
5
|
- nginx
|
|
6
6
|
- with config templates for rails app
|
|
7
|
+
- static website template
|
|
7
8
|
- nodejs
|
|
8
9
|
- postgresql
|
|
10
|
+
- mysql
|
|
9
11
|
- unicorn (integrated with a nginx/railsapp)
|
|
10
12
|
- rbenv
|
|
13
|
+
- redis
|
|
11
14
|
|
|
12
15
|
The upcoming recipes include:
|
|
13
16
|
- nginx
|
|
14
17
|
- global config template
|
|
15
|
-
- static website template
|
|
16
18
|
- shorewall
|
|
17
19
|
- vsftp
|
|
18
20
|
- php-fpm
|
|
19
|
-
- mysql
|
|
20
21
|
- mongodb
|
|
21
|
-
- redis
|
|
22
22
|
|
|
23
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
24
|
|
|
@@ -31,7 +31,7 @@ The upcoming recipes include:
|
|
|
31
31
|
|
|
32
32
|
You will need to declare those in your own capistrano config file such as `Capfile` or `config/deploy.rb`.
|
|
33
33
|
|
|
34
|
-
The gem includes some sample files to start with `Capfile-rails.
|
|
34
|
+
The gem includes some sample files to start with `Capfile-rails-****.sample` for various deployment-prove usage.
|
|
35
35
|
|
|
36
36
|
## Installation
|
|
37
37
|
|
|
@@ -71,8 +71,10 @@ Here is the recipes included in this gem:
|
|
|
71
71
|
|
|
72
72
|
- nginx
|
|
73
73
|
- with config templates for rails app
|
|
74
|
+
- static website template
|
|
74
75
|
- nodejs
|
|
75
76
|
- postgresql
|
|
77
|
+
- mysql
|
|
76
78
|
- unicorn (integrated with a nginx/railsapp)
|
|
77
79
|
- rbenv
|
|
78
80
|
|
|
@@ -84,7 +86,8 @@ Configuration variables: none
|
|
|
84
86
|
Tasks:
|
|
85
87
|
- `nginx:install` installs the lastest release from the ppa `ppa:nginx/stable`.
|
|
86
88
|
- `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.
|
|
89
|
+
- `nginx:setup:unicorn` generates a nginx site configuration for a rails app runs with `unicorn` through unix socket.
|
|
90
|
+
- `nginx:setup:static` generates a nginx site configuration for static sites. require `domain`, `deploy_to` and `application`.
|
|
88
91
|
|
|
89
92
|
### NodeJS
|
|
90
93
|
Default role: `app`
|
|
@@ -96,6 +99,15 @@ Tasks:
|
|
|
96
99
|
|
|
97
100
|
The ppa comes from [official wiki](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager).
|
|
98
101
|
|
|
102
|
+
### Redis
|
|
103
|
+
Default role: `app`
|
|
104
|
+
|
|
105
|
+
Configuration variables: none
|
|
106
|
+
|
|
107
|
+
Tasks:
|
|
108
|
+
- `redis:install` installs `node` and `npm` from the `ppa:chris-lea/redis-server`.
|
|
109
|
+
- `redis:start/stop/reload` maps to `sudo service redis start/stop/reload` on the remote machine.
|
|
110
|
+
|
|
99
111
|
### Rbenv
|
|
100
112
|
It uses the [rbenv installer](https://github.com/fesplugas/rbenv-installer) to create a `ruby` environment.
|
|
101
113
|
|
|
@@ -115,17 +127,25 @@ Currently, postgresql configuration is tightly attached to a rails application,
|
|
|
115
127
|
Default role: `db`
|
|
116
128
|
|
|
117
129
|
Configuration variables:
|
|
118
|
-
- `
|
|
119
|
-
- `
|
|
130
|
+
- `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`.
|
|
131
|
+
- `db_backup_path` the path to store database dumps.
|
|
132
|
+
- `pg_keep_backups` the backups versions you want to keep on one remote machine, it defaults to 10.
|
|
120
133
|
|
|
121
134
|
Tasks:
|
|
122
135
|
- `pg:install` installs `postgresql` and `libpg-dev` from `ppa:pitti/postgresql`.
|
|
123
136
|
- `pg:reset` drops the databases and roles with the same names as in the application.
|
|
124
137
|
- `pg:init` generates roles and databases for the rails application.
|
|
125
138
|
- `pg:setup` generates remote `database.yml` based on local `database.yml`'s `production` settings.
|
|
126
|
-
- `
|
|
127
|
-
- `pg:dump` dumps and compresses the application database, store them in the `
|
|
128
|
-
- `pg:
|
|
139
|
+
- `config:db:symlink` creates symbolic for the `database.yml` in the release.
|
|
140
|
+
- `pg:dump` dumps and compresses the application database, store them in the `db_backup_path`.
|
|
141
|
+
- `pg:get` download the remote dump to local `/tmp` directory
|
|
142
|
+
- `pg:put` upload the local dumps in `/tmp` to the remote server
|
|
143
|
+
- `pg:restore:remote` On the remote machine, restores selected dumps from the `db_backup_path`, it defaults to lastest dump.
|
|
144
|
+
- `pg:restore:local` On the local machine, restores selected dumps from the `/tmp`, it defaults to lastest dump.
|
|
145
|
+
- `pg:cleanup` cleans up old backups while keep `pg_keep_backups` numbers of backups.
|
|
146
|
+
|
|
147
|
+
### MySQL
|
|
148
|
+
Most `capistrano-zen/mysql` has similar tasks as Postgresql.
|
|
129
149
|
|
|
130
150
|
### Unicorn
|
|
131
151
|
This recipes setup unicorn configuration based on current rails application, and generate a `init.d` control scripts to manage the service.
|
data/capistrano-zen.gemspec
CHANGED
data/lib/capistrano-zen/base.rb
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
_cset(:config_path) { abort "[Error] config recipes need `config_path` to find the application.yml file." }
|
|
10
|
+
|
|
11
|
+
namespace :config do
|
|
12
|
+
desc "upload the application.yml file into the deploy environments"
|
|
13
|
+
task :setup, roles: :app do
|
|
14
|
+
upload "#{config_path}/application.yml", "#{shared_path}/config/application.yml"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
desc "Symlink the database.yml file into latest release"
|
|
18
|
+
namespace :db do
|
|
19
|
+
task :symlink, roles: :app do
|
|
20
|
+
run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
desc "Symlink the application.yml file into latest release"
|
|
25
|
+
namespace :env do
|
|
26
|
+
task :symlink, roles: :app do
|
|
27
|
+
run "ln -nfs #{shared_path}/config/application.yml #{release_path}/config/application.yml"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,155 @@
|
|
|
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(:config_path) { abort "[Error] mysql recipes need `config_path` to find the database.yml file." }
|
|
11
|
+
_cset(:db_backup_path) { abort "[Error] mysql recipes need `db_backup_path` to execute backups." }
|
|
12
|
+
|
|
13
|
+
DB_FILE_PATH ||= "#{config_path}/database.yml"
|
|
14
|
+
DBCONFIG ||= YAML.load_file(DB_FILE_PATH)
|
|
15
|
+
|
|
16
|
+
_cset(:mysql_host) { DBCONFIG['production']['host'] }
|
|
17
|
+
_cset(:mysql_user) { DBCONFIG['production']['username'] }
|
|
18
|
+
_cset(:mysql_password) { DBCONFIG['production']['password'] }
|
|
19
|
+
_cset(:mysql_database) { DBCONFIG['production']['database'] }
|
|
20
|
+
|
|
21
|
+
_cset(:mysql_host_dev) { DBCONFIG['development']['host'] }
|
|
22
|
+
_cset(:mysql_user_dev) { DBCONFIG['development']['username'] }
|
|
23
|
+
_cset(:mysql_password_dev) { DBCONFIG['development']['password'] }
|
|
24
|
+
_cset(:mysql_database_dev) { DBCONFIG['development']['database'] }
|
|
25
|
+
|
|
26
|
+
namespace :mysql do
|
|
27
|
+
desc "Install the latest stable release of MySQL with root password."
|
|
28
|
+
task :install, roles: :db, only: {primary: true} do
|
|
29
|
+
root_password = Capistrano::CLI.password_prompt "Enter database password for 'root':"
|
|
30
|
+
# install MySQL interactively
|
|
31
|
+
# http://serverfault.com/questions/19367/scripted-install-of-mysql-on-ubuntu
|
|
32
|
+
run "#{sudo} debconf-set-selections << 'mysql-server-5.5 mysql-server/root_password password #{root_password}'"
|
|
33
|
+
run "#{sudo} debconf-set-selections << 'mysql-server-5.5 mysql-server/root_password_again password #{root_password}'"
|
|
34
|
+
run "#{sudo} apt-get -y update"
|
|
35
|
+
run "#{sudo} apt-get -y install mysql-server libmysqlclient-dev libmysql-ruby"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
desc "Create a database for this application."
|
|
39
|
+
task :init, roles: :db, only: { primary: true } do
|
|
40
|
+
# User will be created if not existed
|
|
41
|
+
sql = <<-SQL
|
|
42
|
+
CREATE DATABASE #{mysql_database} DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
|
|
43
|
+
GRANT ALL PRIVILEGES ON #{mysql_database}.* TO #{mysql_user}@localhost IDENTIFIED BY '#{mysql_password}';
|
|
44
|
+
SQL
|
|
45
|
+
|
|
46
|
+
run_sql(sql)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
desc "Reset the database and role for this application."
|
|
50
|
+
task :reset, roles: :db, only: { primary: true } do
|
|
51
|
+
# drop the database and role
|
|
52
|
+
# http://bugs.mysql.com/bug.php?id=19166
|
|
53
|
+
sql = <<-SQL
|
|
54
|
+
GRANT USAGE ON *.* TO #{mysql_user}@'localhost';
|
|
55
|
+
DROP USER #{mysql_user}@localhost;
|
|
56
|
+
DROP DATABASE IF EXISTS #{mysql_database};
|
|
57
|
+
SQL
|
|
58
|
+
|
|
59
|
+
run_sql(sql)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
desc "Generate the database.yml configuration file."
|
|
63
|
+
task :setup, roles: :app do
|
|
64
|
+
run "mkdir -p #{shared_path}/config"
|
|
65
|
+
template "mysql.yml.erb", "#{shared_path}/config/database.yml"
|
|
66
|
+
# init backup directory
|
|
67
|
+
run "#{sudo} mkdir -p #{db_backup_path}"
|
|
68
|
+
run "#{sudo} chown :#{group} #{db_backup_path}"
|
|
69
|
+
run "#{sudo} chmod g+w #{db_backup_path}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc "Dump the application's database to backup path."
|
|
73
|
+
task :dump, roles: :db, only: { primary: true } do
|
|
74
|
+
run "mysqldump -u #{mysql_user} -p --host=#{mysql_host} #{mysql_database} --add-drop-table | gzip > #{db_backup_path}/#{application}-#{release_name}.mysql.sql.gz" do |channel, stream, data|
|
|
75
|
+
puts data if data.length >= 3
|
|
76
|
+
channel.send_data("#{mysql_password}\n") if data =~ /password/
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
desc "Get the remote dump to local /tmp directory."
|
|
81
|
+
task :get, roles: :db, only: { primary: true } do
|
|
82
|
+
list_remote
|
|
83
|
+
download "#{db_backup_path}/#{backup}", "/tmp/#{backup}", :once => true
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
desc "Put the local dump in /tmp to remote backups."
|
|
87
|
+
task :put, roles: :db, only: { primary: true } do
|
|
88
|
+
list_local
|
|
89
|
+
upload "/tmp/#{backup}", "#{db_backup_path}/#{backup}"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
namespace :restore do
|
|
93
|
+
desc "Restore the remote database from dump files."
|
|
94
|
+
task :remote, roles: :db, only: { primary: true } do
|
|
95
|
+
list_remote
|
|
96
|
+
run "gunzip -c #{db_backup_path}/#{backup} | mysql -u #{mysql_user} -p -h #{mysql_host} #{mysql_database} " do |channel, stream, data|
|
|
97
|
+
puts data if data.length >= 3
|
|
98
|
+
channel.send_data("#{mysql_password}\n") if data =~ /password/
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
desc "Restore the local database from dump files."
|
|
103
|
+
task :local do
|
|
104
|
+
list_local
|
|
105
|
+
run_locally "gunzip -c /tmp/#{backup} | mysql -u -p #{mysql_user_dev} -h #{mysql_host_dev}" do |channel, stream, data|
|
|
106
|
+
puts data if data.length >= 3
|
|
107
|
+
channel.send_data("#{mysql_password}\n") if data =~ /password/
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
task :cleanup, roles: :db, only: { primary: true } do
|
|
113
|
+
count = fetch(:pg_keep_backups, 10).to_i
|
|
114
|
+
local_backups = capture("ls -xt #{db_backup_path} | grep mysql").split.reverse
|
|
115
|
+
if count >= local_backups.length
|
|
116
|
+
logger.important "no old backups to clean up"
|
|
117
|
+
else
|
|
118
|
+
logger.info "keeping #{count} of #{local_backups.length} backups"
|
|
119
|
+
directories = (local_backups - local_backups.last(count)).map { |release|
|
|
120
|
+
File.join(db_backup_path, release) }.join(" ")
|
|
121
|
+
|
|
122
|
+
try_sudo "rm -rf #{directories}"
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# private tasks
|
|
127
|
+
task :list_remote, roles: :db, only: { primary: true } do
|
|
128
|
+
backups = capture("ls -x #{db_backup_path} | grep mysql").split.sort
|
|
129
|
+
default_backup = backups.last
|
|
130
|
+
puts "Available backups: "
|
|
131
|
+
puts backups
|
|
132
|
+
choice = Capistrano::CLI.ui.ask "Which backup would you like to choose? [#{default_backup}] "
|
|
133
|
+
set :backup, choice.empty? ? backups.last : choice
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
task :list_local do
|
|
137
|
+
backups = `ls -x /tmp | grep -e '.sql.gz$' | grep mysql`.split.sort
|
|
138
|
+
default_backup = backups.last
|
|
139
|
+
puts "Available local backups: "
|
|
140
|
+
puts backups
|
|
141
|
+
choice = Capistrano::CLI.ui.ask "Which backup would you like to choose? [#{default_backup}] "
|
|
142
|
+
set :backup, choice.empty? ? backups.last : choice
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def run_sql(sql)
|
|
146
|
+
run "mysql -u root -p --execute=\"#{sql}\"" do |channel, stream, data|
|
|
147
|
+
if data =~ /^Enter password:/
|
|
148
|
+
puts data if data.length >= 3
|
|
149
|
+
pass = Capistrano::CLI.password_prompt "Enter database password for 'root':"
|
|
150
|
+
channel.send_data "#{pass}\n"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
data/lib/capistrano-zen/nginx.rb
CHANGED
|
@@ -8,7 +8,7 @@ configuration.load do
|
|
|
8
8
|
namespace :nginx do
|
|
9
9
|
desc "Install latest stable release of nginx"
|
|
10
10
|
task :install, roles: :web do
|
|
11
|
-
run "#{sudo} add-apt-repository
|
|
11
|
+
run "#{sudo} add-apt-repository ppa:nginx/stable"
|
|
12
12
|
run "#{sudo} apt-get -y update"
|
|
13
13
|
run "#{sudo} apt-get -y install nginx"
|
|
14
14
|
run "#{sudo} rm -f /etc/nginx/sites-enabled/default"
|
|
@@ -18,16 +18,32 @@ configuration.load do
|
|
|
18
18
|
desc "Setup nginx configuration for unicorn application"
|
|
19
19
|
task :unicorn, roles: :web do
|
|
20
20
|
template "nginx_unicorn.erb", "/tmp/nginx_conf"
|
|
21
|
-
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-
|
|
21
|
+
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-available/#{application}"
|
|
22
|
+
link
|
|
22
23
|
restart
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
desc "Setup nginx configuration for static website"
|
|
26
27
|
task :static, roles: :web do
|
|
27
28
|
template "nginx_static.erb", "/tmp/nginx_conf"
|
|
28
|
-
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-
|
|
29
|
+
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-available/#{application}"
|
|
30
|
+
link
|
|
29
31
|
restart
|
|
30
32
|
end
|
|
33
|
+
|
|
34
|
+
desc "Setup nginx configuration for wordpress website"
|
|
35
|
+
task :wordpress, roles: :web do
|
|
36
|
+
template "nginx_wordpress.erb", "/tmp/nginx_conf"
|
|
37
|
+
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-available/#{application}"
|
|
38
|
+
link
|
|
39
|
+
restart
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
desc "create symbolic link"
|
|
43
|
+
task :link do
|
|
44
|
+
run "#{sudo} rm /etc/nginx/sites-enabled/#{application}"
|
|
45
|
+
run "#{sudo} ln -s /etc/nginx/sites-available/#{application} /etc/nginx/sites-enabled/"
|
|
46
|
+
end
|
|
31
47
|
end
|
|
32
48
|
|
|
33
49
|
%w[start stop restart reload].each do |command|
|
|
@@ -10,7 +10,7 @@ configuration.load do
|
|
|
10
10
|
# Reference
|
|
11
11
|
# https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager
|
|
12
12
|
task :install, roles: :app do
|
|
13
|
-
run "#{sudo} add-apt-repository
|
|
13
|
+
run "#{sudo} add-apt-repository ppa:chris-lea/node.js"
|
|
14
14
|
run "#{sudo} apt-get -y update"
|
|
15
15
|
run "#{sudo} apt-get -y install nodejs npm"
|
|
16
16
|
end
|
|
@@ -7,10 +7,10 @@ configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
|
|
7
7
|
|
|
8
8
|
configuration.load do
|
|
9
9
|
|
|
10
|
-
_cset(:
|
|
11
|
-
_cset(:
|
|
10
|
+
_cset(:config_path) { abort "[Error] posgtresql recipes need `config_path` to find the database.yml file." }
|
|
11
|
+
_cset(:db_backup_path) { abort "[Error] posgtresql recipes need `db_backup_path` to execute backups." }
|
|
12
12
|
|
|
13
|
-
DB_FILE_PATH = "#{
|
|
13
|
+
DB_FILE_PATH = "#{config_path}/database.yml"
|
|
14
14
|
DBCONFIG = YAML.load_file(DB_FILE_PATH)
|
|
15
15
|
|
|
16
16
|
_cset(:psql_host) { DBCONFIG['production']['host'] }
|
|
@@ -18,18 +18,22 @@ configuration.load do
|
|
|
18
18
|
_cset(:psql_password) { DBCONFIG['production']['password'] }
|
|
19
19
|
_cset(:psql_database) { DBCONFIG['production']['database'] }
|
|
20
20
|
|
|
21
|
+
_cset(:psql_host_dev) { DBCONFIG['development']['host'] }
|
|
22
|
+
_cset(:psql_user_dev) { DBCONFIG['development']['username'] }
|
|
23
|
+
_cset(:psql_password_dev) { DBCONFIG['development']['password'] }
|
|
24
|
+
_cset(:psql_database_dev) { DBCONFIG['development']['database'] }
|
|
25
|
+
|
|
21
26
|
namespace :pg do
|
|
22
|
-
desc "Install the latest stable release of
|
|
27
|
+
desc "Install the latest stable release of PostgreSQL."
|
|
23
28
|
task :install, roles: :db, only: {primary: true} do
|
|
24
|
-
run "#{sudo} add-apt-repository
|
|
29
|
+
run "#{sudo} add-apt-repository ppa:pitti/postgresql"
|
|
25
30
|
run "#{sudo} apt-get -y update"
|
|
26
|
-
run "#{sudo} apt-get -y install
|
|
31
|
+
run "#{sudo} apt-get -y install postgresql libpq-dev"
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
desc "Create a database for this application."
|
|
30
35
|
task :init, roles: :db, only: { primary: true } do
|
|
31
|
-
#
|
|
32
|
-
run %Q{#{sudo} -u postgres psql -c "CREATE USER #{psql_user} WITH PASSWORD '#{psql_password}';"}
|
|
36
|
+
run %Q{#{sudo} -u postgres psql -c "CREATE USER #{psql_user} WITH PASSWORD '#{psql_password}'; ALTER USER #{psql_user} CREATEDB;"}
|
|
33
37
|
run %Q{#{sudo} -u postgres psql -c "CREATE DATABASE #{psql_database} OWNER #{psql_user};"}
|
|
34
38
|
end
|
|
35
39
|
|
|
@@ -45,37 +49,80 @@ configuration.load do
|
|
|
45
49
|
run "mkdir -p #{shared_path}/config"
|
|
46
50
|
template "postgresql.yml.erb", "#{shared_path}/config/database.yml"
|
|
47
51
|
# init backup directory
|
|
48
|
-
run "#{sudo} mkdir -p #{
|
|
49
|
-
run "#{sudo} chown :#{group} #{
|
|
50
|
-
run "#{sudo} chmod g+w #{
|
|
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"
|
|
52
|
+
run "#{sudo} mkdir -p #{db_backup_path}"
|
|
53
|
+
run "#{sudo} chown :#{group} #{db_backup_path}"
|
|
54
|
+
run "#{sudo} chmod g+w #{db_backup_path}"
|
|
56
55
|
end
|
|
57
56
|
|
|
58
57
|
desc "Dump the application's database to backup path."
|
|
59
58
|
task :dump, roles: :db, only: { primary: true } do
|
|
60
|
-
#
|
|
61
|
-
run "pg_dump #{psql_database} -
|
|
59
|
+
# exclude ownership / clean restore
|
|
60
|
+
run "pg_dump #{psql_database} -O -c -U #{psql_user} -h #{psql_host} | gzip > #{db_backup_path}/#{application}-#{release_name}.pg.sql.gz" do |channel, stream, data|
|
|
62
61
|
puts data if data.length >= 3
|
|
63
62
|
channel.send_data("#{psql_password}\n") if data.include? 'Password'
|
|
64
63
|
end
|
|
65
64
|
end
|
|
66
65
|
|
|
67
|
-
desc "
|
|
68
|
-
task :
|
|
69
|
-
|
|
66
|
+
desc "Get the remote dump to local /tmp directory."
|
|
67
|
+
task :get, roles: :db, only: { primary: true } do
|
|
68
|
+
list_remote
|
|
69
|
+
download "#{db_backup_path}/#{backup}", "/tmp/#{backup}", :once => true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
desc "Put the local dump in /tmp to remote backups."
|
|
73
|
+
task :put, roles: :db, only: { primary: true } do
|
|
74
|
+
list_local
|
|
75
|
+
upload "/tmp/#{backup}", "#{db_backup_path}/#{backup}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
namespace :restore do
|
|
79
|
+
desc "Restore the remote database from dump files."
|
|
80
|
+
task :remote, roles: :db, only: { primary: true } do
|
|
81
|
+
list_remote
|
|
82
|
+
run "gunzip -c #{db_backup_path}/#{backup} | psql -d #{psql_database} -U #{psql_user} -h #{psql_host}" do |channel, stream, data|
|
|
83
|
+
puts data if data.length >= 3
|
|
84
|
+
channel.send_data("#{psql_password}\n") if data.include? 'Password'
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
desc "Restore the local database from dump files."
|
|
89
|
+
task :local do
|
|
90
|
+
list_local
|
|
91
|
+
run_locally "gunzip -c /tmp/#{backup} | psql -d #{psql_database_dev} -U #{psql_user_dev} -h #{psql_host_dev}"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
task :cleanup, roles: :db, only: { primary: true } do
|
|
96
|
+
count = fetch(:pg_keep_backups, 10).to_i
|
|
97
|
+
local_backups = capture("ls -xt #{db_backup_path} | grep pg").split.reverse
|
|
98
|
+
if count >= local_backups.length
|
|
99
|
+
logger.important "no old backups to clean up"
|
|
100
|
+
else
|
|
101
|
+
logger.info "keeping #{count} of #{local_backups.length} backups"
|
|
102
|
+
directories = (local_backups - local_backups.last(count)).map { |release|
|
|
103
|
+
File.join(db_backup_path, release) }.join(" ")
|
|
104
|
+
|
|
105
|
+
try_sudo "rm -rf #{directories}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# private tasks
|
|
110
|
+
task :list_remote, roles: :db, only: { primary: true } do
|
|
111
|
+
backups = capture("ls -x #{db_backup_path} | grep pg").split.sort
|
|
70
112
|
default_backup = backups.last
|
|
71
113
|
puts "Available backups: "
|
|
72
114
|
puts backups
|
|
73
|
-
|
|
74
|
-
backup
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
115
|
+
choice = Capistrano::CLI.ui.ask "Which backup would you like to choose? [#{default_backup}] "
|
|
116
|
+
set :backup, choice.empty? ? backups.last : choice
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
task :list_local do
|
|
120
|
+
backups = `ls -1 /tmp | grep -e '.sql.gz$' | grep pg`.split.sort
|
|
121
|
+
default_backup = backups.last
|
|
122
|
+
puts "Available local backups: "
|
|
123
|
+
puts backups
|
|
124
|
+
choice = Capistrano::CLI.ui.ask "Which backup would you like to choose? [#{default_backup}] "
|
|
125
|
+
set :backup, choice.empty? ? backups.last : choice
|
|
79
126
|
end
|
|
80
127
|
end
|
|
81
128
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
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 :redis do
|
|
9
|
+
desc "Install the latest release of Redis"
|
|
10
|
+
task :install, roles: :app do
|
|
11
|
+
run "#{sudo} add-apt-repository ppa:chris-lea/redis-server"
|
|
12
|
+
run "#{sudo} apt-get -y update"
|
|
13
|
+
run "#{sudo} apt-get -y install redis-server"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
%w[start stop restart].each do |command|
|
|
17
|
+
desc "#{command} redis"
|
|
18
|
+
task command, roles: :web do
|
|
19
|
+
run "#{sudo} service redis-server #{command}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -18,12 +18,18 @@ server {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
# try to serve static file first
|
|
21
|
-
try_files $uri/index.html $uri @unicorn;
|
|
21
|
+
try_files $uri $uri/index.html $uri.html @unicorn;
|
|
22
22
|
|
|
23
|
+
# if a file, which is not found in the root folder is requested,
|
|
24
|
+
# then the proxy pass the request to the upsteam (application_unicorn)
|
|
23
25
|
location @unicorn {
|
|
26
|
+
proxy_redirect off;
|
|
27
|
+
|
|
24
28
|
proxy_set_header Host $http_host;
|
|
25
29
|
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
|
|
26
|
-
|
|
30
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
31
|
+
proxy_set_header X-Real-IP $remote_addr;
|
|
32
|
+
|
|
27
33
|
proxy_pass http://<%= application %>_unicorn;
|
|
28
34
|
}
|
|
29
35
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
server {
|
|
2
|
+
listen 80;
|
|
3
|
+
server_name <%= domain %>;
|
|
4
|
+
root <%= deploy_to %>;
|
|
5
|
+
gzip_static on;
|
|
6
|
+
index index.php;
|
|
7
|
+
|
|
8
|
+
access_log /var/log/nginx/<%= application %>/access.log;
|
|
9
|
+
error_log /var/log/nginx/<%= application %>/error.log;
|
|
10
|
+
|
|
11
|
+
location = /favicon.ico {
|
|
12
|
+
log_not_found off;
|
|
13
|
+
access_log off;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
location = /robots.txt {
|
|
17
|
+
allow all;
|
|
18
|
+
log_not_found off;
|
|
19
|
+
access_log off;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
## Images and static content is treated different
|
|
23
|
+
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
|
|
24
|
+
access_log off;
|
|
25
|
+
expires 360d;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
location ~ /\.ht {
|
|
29
|
+
deny all;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
location / {
|
|
33
|
+
try_files $uri $uri/ /index.php?$args;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
location ~ .*\.(php|php5)?$
|
|
37
|
+
{
|
|
38
|
+
try_files $uri $uri/ /index.php?$args;
|
|
39
|
+
include /etc/nginx/fastcgi_params;
|
|
40
|
+
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
|
41
|
+
fastcgi_index index.php;
|
|
42
|
+
fastcgi_param SCRIPT_FILENAME /home/deployer/sites/<%= application %>$fastcgi_script_name;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!-e $request_filename) {
|
|
46
|
+
rewrite ^(.+)$ /index.php?q=$1 last;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
RAILS_ENV = ENV['RAILS_ENV'] ||
|
|
1
|
+
RAILS_ENV = ENV['RAILS_ENV'] || "<%= rails_env %>"
|
|
2
2
|
|
|
3
3
|
# unicorn workers
|
|
4
4
|
worker_processes <%= unicorn_workers %>
|
|
@@ -25,65 +25,68 @@ listen '/tmp/unicorn.<%= application %>.sock', :backlog => 2048
|
|
|
25
25
|
|
|
26
26
|
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
|
|
27
27
|
if GC.respond_to?(:copy_on_write_friendly=)
|
|
28
|
-
|
|
28
|
+
GC.copy_on_write_friendly = true
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
before_fork do |server, worker|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
33
|
+
# the following is highly recomended for Rails + "preload_app true"
|
|
34
|
+
# as there's no need for the master process to hold a connection
|
|
35
|
+
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
|
|
36
|
+
|
|
37
|
+
# When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
|
|
38
|
+
# immediately start loading up a new version of itself (loaded with a new
|
|
39
|
+
# version of our app). When this new Unicorn is completely loaded
|
|
40
|
+
# it will begin spawning workers. The first worker spawned will check to
|
|
41
|
+
# see if an .oldbin pidfile exists. If so, this means we've just booted up
|
|
42
|
+
# a new Unicorn and need to tell the old one that it can now die. To do so
|
|
43
|
+
# we send it a QUIT.
|
|
44
|
+
#
|
|
45
|
+
# Using this method we get 0 downtime deploys.
|
|
46
|
+
|
|
47
|
+
old_pid = "#{server.config[:pid]}.oldbin"
|
|
48
|
+
if File.exists?(old_pid) && server.pid != old_pid
|
|
49
|
+
begin
|
|
50
|
+
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
|
|
51
|
+
Process.kill(sig, File.read(old_pid).to_i)
|
|
52
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
|
53
|
+
# someone else did our job for us
|
|
54
|
+
end
|
|
55
|
+
end
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
|
|
55
59
|
after_fork do |server, worker|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
raise e
|
|
87
|
-
end
|
|
60
|
+
##
|
|
61
|
+
# Unicorn master loads the app then forks off workers - because of the way
|
|
62
|
+
# Unix forking works, we need to make sure we aren't using any of the parent's
|
|
63
|
+
# sockets, e.g. db connection
|
|
64
|
+
|
|
65
|
+
ActiveRecord::Base.establish_connection
|
|
66
|
+
# CHIMNEY.client.connect_to_server
|
|
67
|
+
# Redis and Memcached would go here but their connections are established
|
|
68
|
+
# on demand, so the master never opens a socket
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Unicorn master is started as root, which is fine, but let's
|
|
72
|
+
# drop the workers to deploy:deploy
|
|
73
|
+
|
|
74
|
+
begin
|
|
75
|
+
uid, gid = Process.euid, Process.egid
|
|
76
|
+
user, group = '<%= unicorn_user %>', '<%= unicorn_group %>'
|
|
77
|
+
target_uid = Etc.getpwnam(user).uid
|
|
78
|
+
target_gid = Etc.getgrnam(group).gid
|
|
79
|
+
worker.tmp.chown(target_uid, target_gid)
|
|
80
|
+
if uid != target_uid || gid != target_gid
|
|
81
|
+
Process.initgroups(user, target_gid)
|
|
82
|
+
Process::GID.change_privilege(target_gid)
|
|
83
|
+
Process::UID.change_privilege(target_uid)
|
|
84
|
+
end
|
|
85
|
+
rescue => e
|
|
86
|
+
if RAILS_ENV == 'development'
|
|
87
|
+
STDERR.puts "couldn't change user, oh well"
|
|
88
|
+
else
|
|
89
|
+
raise e
|
|
88
90
|
end
|
|
91
|
+
end
|
|
89
92
|
end
|
|
@@ -14,7 +14,7 @@ set -e
|
|
|
14
14
|
TIMEOUT=${TIMEOUT-60}
|
|
15
15
|
APP_ROOT=<%= current_path %>
|
|
16
16
|
PID=<%= unicorn_pid %>
|
|
17
|
-
CMD="cd <%= current_path %>; bundle exec unicorn -D -c <%= unicorn_config %> -E
|
|
17
|
+
CMD="cd <%= current_path %>; bundle exec unicorn -D -c <%= unicorn_config %> -E <%= rails_env %>"
|
|
18
18
|
AS_USER=<%= unicorn_user %>
|
|
19
19
|
set -u
|
|
20
20
|
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* The base configurations of the WordPress.
|
|
4
|
+
*
|
|
5
|
+
* This file has the following configurations: MySQL settings, Table Prefix,
|
|
6
|
+
* Secret Keys, WordPress Language, and ABSPATH. You can find more information
|
|
7
|
+
* by visiting {@link http://codex.wordpress.org/Editing_wp-config.php Editing
|
|
8
|
+
* wp-config.php} Codex page. You can get the MySQL settings from your web host.
|
|
9
|
+
* @package WordPress
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ** MySQL settings - You can get this info from your web host ** //
|
|
13
|
+
/** The name of the database for WordPress */
|
|
14
|
+
define('DB_NAME', '<%= db_name %>');
|
|
15
|
+
|
|
16
|
+
/** MySQL database username */
|
|
17
|
+
define('DB_USER', '<%= db_user %>');
|
|
18
|
+
|
|
19
|
+
/** MySQL database password */
|
|
20
|
+
define('DB_PASSWORD', '<%= db_password %>');
|
|
21
|
+
|
|
22
|
+
/** MySQL hostname */
|
|
23
|
+
define('DB_HOST', '<%= db_host %>');
|
|
24
|
+
|
|
25
|
+
/** Database Charset to use in creating database tables. */
|
|
26
|
+
define('DB_CHARSET', 'utf8');
|
|
27
|
+
|
|
28
|
+
/** The Database Collate type. Don't change this if in doubt. */
|
|
29
|
+
define('DB_COLLATE', '');
|
|
30
|
+
|
|
31
|
+
/**#@+
|
|
32
|
+
* Authentication Unique Keys and Salts.
|
|
33
|
+
*
|
|
34
|
+
* Change these to different unique phrases!
|
|
35
|
+
* You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
|
|
36
|
+
* You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
|
|
37
|
+
*/
|
|
38
|
+
define('AUTH_KEY', '<%= random_salts %>');
|
|
39
|
+
define('SECURE_AUTH_KEY', '<%= random_salts %>');
|
|
40
|
+
define('LOGGED_IN_KEY', '<%= random_salts %>');
|
|
41
|
+
define('NONCE_KEY', '<%= random_salts %>');
|
|
42
|
+
define('AUTH_SALT', '<%= random_salts %>');
|
|
43
|
+
define('SECURE_AUTH_SALT', '<%= random_salts %>');
|
|
44
|
+
define('LOGGED_IN_SALT', '<%= random_salts %>');
|
|
45
|
+
define('NONCE_SALT', '<%= random_salts %>');
|
|
46
|
+
/**#@-*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* WordPress Database Table prefix.
|
|
50
|
+
*
|
|
51
|
+
* You can have multiple installations in one database if you give each a unique
|
|
52
|
+
* prefix. Only numbers, letters, and underscores please!
|
|
53
|
+
*/
|
|
54
|
+
$table_prefix = 'wp_';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* WordPress Localized Language, defaults to English.
|
|
58
|
+
*
|
|
59
|
+
* Change this to localize WordPress. A corresponding MO file for the chosen
|
|
60
|
+
* language must be installed to wp-content/languages. For example, install
|
|
61
|
+
* de_DE.mo to wp-content/languages and set WPLANG to 'de_DE' to enable German
|
|
62
|
+
* language support.
|
|
63
|
+
*/
|
|
64
|
+
define('WPLANG', '');
|
|
65
|
+
|
|
66
|
+
/* That's all, stop editing! Happy blogging. */
|
|
67
|
+
|
|
68
|
+
/** Absolute path to the WordPress directory. */
|
|
69
|
+
if ( !defined('ABSPATH') )
|
|
70
|
+
define('ABSPATH', dirname(__FILE__) . '/');
|
|
71
|
+
|
|
72
|
+
/** Sets up WordPress vars and included files. */
|
|
73
|
+
require_once(ABSPATH . 'wp-settings.php');
|
|
74
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
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 :wordpress do
|
|
9
|
+
desc "upload the configuration to remote server"
|
|
10
|
+
task :config, roles: :web do
|
|
11
|
+
template "wp-config.php.erb", "/tmp/wp-config.php"
|
|
12
|
+
run "#{sudo} mv /tmp/wp-config.php #{deploy_to}/"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def random_salts
|
|
18
|
+
('.'..'z').to_a.shuffle[0,60].join
|
|
19
|
+
end
|
metadata
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: capistrano-zen
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.0.4
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Steven Yang
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2013-11-11 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: capistrano
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
|
-
- -
|
|
17
|
+
- - ">="
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
19
|
version: 2.5.3
|
|
22
20
|
type: :runtime
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
|
-
- -
|
|
24
|
+
- - ">="
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
29
26
|
version: 2.5.3
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
30
41
|
description: Capistrano Recipes used at zenhacks.org.
|
|
31
42
|
email:
|
|
32
43
|
- yangchenyun@gmail.com
|
|
@@ -35,8 +46,10 @@ extensions: []
|
|
|
35
46
|
extra_rdoc_files:
|
|
36
47
|
- LICENSE
|
|
37
48
|
files:
|
|
38
|
-
- .gitignore
|
|
39
|
-
- Capfile-rails.sample
|
|
49
|
+
- ".gitignore"
|
|
50
|
+
- Capfile-rails-farigo.sample
|
|
51
|
+
- Capfile-rails-mysql.sample
|
|
52
|
+
- Capfile-rails-postgresql.sample
|
|
40
53
|
- Capfile-static.sample
|
|
41
54
|
- Gemfile
|
|
42
55
|
- LICENSE
|
|
@@ -45,40 +58,47 @@ files:
|
|
|
45
58
|
- capistrano-zen.gemspec
|
|
46
59
|
- lib/capistrano-zen/base.rb
|
|
47
60
|
- lib/capistrano-zen/common.rb
|
|
61
|
+
- lib/capistrano-zen/config.rb
|
|
62
|
+
- lib/capistrano-zen/mysql.rb
|
|
48
63
|
- lib/capistrano-zen/nginx.rb
|
|
49
64
|
- lib/capistrano-zen/nodejs.rb
|
|
50
65
|
- lib/capistrano-zen/postgresql.rb
|
|
51
66
|
- lib/capistrano-zen/rbenv.rb
|
|
67
|
+
- lib/capistrano-zen/redis.rb
|
|
68
|
+
- lib/capistrano-zen/tmpls/mysql.yml.erb
|
|
52
69
|
- lib/capistrano-zen/tmpls/nginx_static.erb
|
|
53
70
|
- lib/capistrano-zen/tmpls/nginx_unicorn.erb
|
|
71
|
+
- lib/capistrano-zen/tmpls/nginx_wordpress.erb
|
|
54
72
|
- lib/capistrano-zen/tmpls/postgresql.yml.erb
|
|
55
73
|
- lib/capistrano-zen/tmpls/unicorn.rb.erb
|
|
56
74
|
- lib/capistrano-zen/tmpls/unicorn_init.erb
|
|
75
|
+
- lib/capistrano-zen/tmpls/wp-config.php.erb
|
|
57
76
|
- lib/capistrano-zen/unicorn.rb
|
|
58
77
|
- lib/capistrano-zen/utils.rb
|
|
59
78
|
- lib/capistrano-zen/version.rb
|
|
79
|
+
- lib/capistrano-zen/wordpress.rb
|
|
60
80
|
homepage: ''
|
|
61
81
|
licenses: []
|
|
82
|
+
metadata: {}
|
|
62
83
|
post_install_message:
|
|
63
84
|
rdoc_options: []
|
|
64
85
|
require_paths:
|
|
65
86
|
- lib
|
|
66
87
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
67
|
-
none: false
|
|
68
88
|
requirements:
|
|
69
|
-
- -
|
|
89
|
+
- - ">="
|
|
70
90
|
- !ruby/object:Gem::Version
|
|
71
91
|
version: '0'
|
|
72
92
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
|
-
none: false
|
|
74
93
|
requirements:
|
|
75
|
-
- -
|
|
94
|
+
- - ">="
|
|
76
95
|
- !ruby/object:Gem::Version
|
|
77
96
|
version: '0'
|
|
78
97
|
requirements: []
|
|
79
98
|
rubyforge_project:
|
|
80
|
-
rubygems_version:
|
|
99
|
+
rubygems_version: 2.0.3
|
|
81
100
|
signing_key:
|
|
82
|
-
specification_version:
|
|
101
|
+
specification_version: 4
|
|
83
102
|
summary: Nginx, Unicorn, PostgreSQL, NodeJS Recipes install on a machine running Ubuntu.
|
|
84
103
|
test_files: []
|
|
104
|
+
has_rdoc:
|