capistrano_recipes 1.0.0
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 +15 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +89 -0
- data/Rakefile +7 -0
- data/capistrano_recipes.gemspec +24 -0
- data/lib/capistrano/recipes/bundle.rb +9 -0
- data/lib/capistrano/recipes/bundler.rb +2 -0
- data/lib/capistrano/recipes/git.rb +119 -0
- data/lib/capistrano/recipes/multistage.rb +73 -0
- data/lib/capistrano/recipes/mysql.rb +134 -0
- data/lib/capistrano/recipes/nginx.rb +75 -0
- data/lib/capistrano/recipes/rails_assets.rb +7 -0
- data/lib/capistrano/recipes/templates/mysql.yml.erb +7 -0
- data/lib/capistrano/recipes/templates/nginx.vhost.erb +139 -0
- data/lib/capistrano/recipes/templates/unicorn.rb.erb +47 -0
- data/lib/capistrano/recipes/templates/unicorn_init.erb +84 -0
- data/lib/capistrano/recipes/unicorn.rb +71 -0
- data/lib/capistrano/recipes.rb +1 -0
- data/lib/capistrano_recipes.rb +129 -0
- data/spec/bundle_spec.rb +15 -0
- data/spec/bundler_spec.rb +14 -0
- data/spec/git_spec.rb +57 -0
- data/spec/multistage_spec.rb +66 -0
- data/spec/mysql_spec.rb +14 -0
- data/spec/nginx_spec.rb +16 -0
- data/spec/rails_assets.rb +37 -0
- data/spec/spec_helper.rb +108 -0
- data/spec/unicorn_spec.rb +16 -0
- metadata +126 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmM2MzhjY2ZhZjY2ZTc4ODhjYzJjY2Q3NWYxZjFkZjZiZjczYWZkMQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YmU5OGQ3NjRkMDhmNTczNTQwZjE5MzZhNTlkMjg4MzE2OTY1NjRhZA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NzRiNDhjZGRmNTRkY2JmNjhjYTBjYWFmZWFmOWY5MjA1Yzc0NmE2Yjc0NGQ1
|
10
|
+
MDgzMzY1Nzg3OGMyZjg0MGE5ZWUwMjBhZDE0NDQ1NTZjNWZlMzM2OTZjYzE1
|
11
|
+
NzcyODljNWRmYTBkMjZjNTM0NDBlNjc4OWRjZDI5NmJkYjFmNDY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MmE1ZDlhYmZiZDAwMmMzYWU0ZmYyM2ZmNDVkMTRlNWI1ZDNlNmRhNjBmM2Ux
|
14
|
+
MzRmYTUzNDhiOTk3ZTYzODcyODQxZjRjYjgyZTNkN2QyZjgzMDZhYWNiNzZk
|
15
|
+
ZGEyYTE3NDE1ZWFjYmMzMmVkMmU5MTdmZjE0ZGRkMTdiNjMzZmY=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Fernando Aleman
|
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,89 @@
|
|
1
|
+
# Capistrano Recipes [](https://travis-ci.org/fernandoaleman/capistrano_recipes) [](https://gemnasium.com/fernandoaleman/capistrano_recipes)
|
2
|
+
|
3
|
+
Powerful capistrano recipes to make your rails deployments fast and easy.
|
4
|
+
|
5
|
+
## Quickstart Guide
|
6
|
+
|
7
|
+
Create a file called 'Capfile' in your application's root directory.
|
8
|
+
|
9
|
+
For a single environment add:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'capistrano/recipes'
|
13
|
+
|
14
|
+
use_recipes :bundler, :git, :rails_assets
|
15
|
+
|
16
|
+
server 'Add your web server domain or ip here', :app, :web, :db, :primary => true
|
17
|
+
|
18
|
+
set :application, "Set application name here"
|
19
|
+
set :deploy_to, "/path/to/your/app/here"
|
20
|
+
set :repository, "Set repository location here"
|
21
|
+
set :domain, "Set domain name here"
|
22
|
+
```
|
23
|
+
|
24
|
+
For a multistage environment add:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
require 'capistrano/recipes'
|
28
|
+
|
29
|
+
use_recipes :bundler, :git, :multistage, :rails_assets
|
30
|
+
|
31
|
+
stage :staging, :branch => :dev, :default => true do
|
32
|
+
server 'Add your web server domain or ip here', :app, :web, :db, :primary => true
|
33
|
+
end
|
34
|
+
|
35
|
+
stage :production, :branch => :master do
|
36
|
+
server 'Add your web server domain or ip here', :app, :web, :db, :primary => true
|
37
|
+
end
|
38
|
+
|
39
|
+
set :application, "Set application name here"
|
40
|
+
set :deploy_to, "/path/to/your/app/here"
|
41
|
+
set :repository, "Set repository location here"
|
42
|
+
set :domain, "Set domain name here"
|
43
|
+
```
|
44
|
+
|
45
|
+
To add a single recipe:
|
46
|
+
```ruby
|
47
|
+
use_recipe :bundle
|
48
|
+
```
|
49
|
+
|
50
|
+
To add multiple recipes:
|
51
|
+
```ruby
|
52
|
+
use_recipes :bundle, :git, :multistage, :rails_assets
|
53
|
+
```
|
54
|
+
|
55
|
+
## Recipes
|
56
|
+
| Recipe | Documentation |
|
57
|
+
| ------------ | ------------- |
|
58
|
+
| :bundle | [Bundle recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Bundle) |
|
59
|
+
| :git | [Git recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Git) |
|
60
|
+
| :multistage | [Multistage recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Multistage) |
|
61
|
+
| :mysql | [Mysql](https://github.com/fernandoaleman/capistrano_recipes/wiki/Mysql) |
|
62
|
+
| :nginx | [Nginx](https://github.com/fernandoaleman/capistrano_recipes/wiki/Nginx) |
|
63
|
+
| :rails_assets | [Rails assets recipe documentation](https://github.com/fernandoaleman/capistrano_recipes/wiki/Rails-Assets) |
|
64
|
+
| :unicorn | [Unicorn](https://github.com/fernandoaleman/capistrano_recipes/wiki/Unicorn) |
|
65
|
+
|
66
|
+
## Installation
|
67
|
+
|
68
|
+
Add this line to your application's Gemfile:
|
69
|
+
|
70
|
+
gem 'capistrano_recipes'
|
71
|
+
|
72
|
+
And then execute:
|
73
|
+
|
74
|
+
$ bundle
|
75
|
+
|
76
|
+
Or install it yourself as:
|
77
|
+
|
78
|
+
$ gem install capistrano_recipes
|
79
|
+
|
80
|
+
## Documentation
|
81
|
+
For more detailed information, visit the [wiki](https://github.com/fernandoaleman/capistrano_recipes/wiki).
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'capistrano_recipes'
|
7
|
+
s.version = '1.0.0'
|
8
|
+
s.authors = ['Fernando Aleman']
|
9
|
+
s.email = ['fernandoaleman@mac.com']
|
10
|
+
s.description = 'Capistrano recipes to make your deployments fast and easy'
|
11
|
+
s.summary = 'Capistrano deployment recipes'
|
12
|
+
s.homepage = 'https://github.com/fernandoaleman/capistrano_recipes'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split($/)
|
16
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency 'capistrano', '~> 2.12'
|
21
|
+
s.add_dependency 'bundler', '~> 1.3'
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec', '~> 2.5'
|
24
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Git
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
default_run_options[:pty] = true
|
6
|
+
ssh_options[:forward_agent] = true
|
7
|
+
|
8
|
+
set(:repository) { abort "Please specify repository, set :repository, 'foo'" }
|
9
|
+
|
10
|
+
_cset :branch, 'master'
|
11
|
+
_cset :use_sudo, false
|
12
|
+
_cset :check_repo, true
|
13
|
+
|
14
|
+
set :migrate_target, :current
|
15
|
+
|
16
|
+
set(:latest_release) { fetch(:current_path) }
|
17
|
+
set(:release_path) { fetch(:current_path) }
|
18
|
+
set(:releases_path) { fetch(:current_path) }
|
19
|
+
set(:current_release) { fetch(:current_path) }
|
20
|
+
set(:current_revision) { capture("cd #{deploy_to} && git rev-parse --short HEAD").strip }
|
21
|
+
set(:latest_revision) { capture("cd #{deploy_to} && git rev-parse --short HEAD").strip }
|
22
|
+
set(:previous_revision) { capture("cd #{deploy_to} && git rev-parse --short HEAD@{1}").strip }
|
23
|
+
|
24
|
+
set :local_branch do
|
25
|
+
`git symbolic-ref HEAD 2> /dev/null`.strip.sub('refs/heads/', '')
|
26
|
+
end
|
27
|
+
|
28
|
+
after 'deploy:setup' do
|
29
|
+
run "git clone --no-checkout #{repository} #{current_path}"
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :deploy do
|
33
|
+
desc 'Deploy and start a cold application'
|
34
|
+
task :cold do
|
35
|
+
update
|
36
|
+
migrate
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Update the deployed code through transaction to rollback if it has errors'
|
40
|
+
task :update do
|
41
|
+
transaction do
|
42
|
+
update_code
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'Update the deployed code'
|
47
|
+
task :update_code, :except => { :no_release => true } do
|
48
|
+
run "cd #{deploy_to} && git fetch origin && git reset --hard origin/#{branch}"
|
49
|
+
finalize_update
|
50
|
+
end
|
51
|
+
|
52
|
+
desc 'Run migrations'
|
53
|
+
task :migrate, :roles => :db, :only => { :primary => true } do
|
54
|
+
run "cd #{deploy_to} && RAILS_ENV=#{rails_env} #{rake} db:migrate"
|
55
|
+
end
|
56
|
+
|
57
|
+
desc 'Deploy and run migrations'
|
58
|
+
task :migrations do
|
59
|
+
update
|
60
|
+
migrate
|
61
|
+
restart
|
62
|
+
end
|
63
|
+
|
64
|
+
namespace :rollback do
|
65
|
+
desc 'Move repo back to the previous version of HEAD'
|
66
|
+
task :repo, :except => { :no_release => true } do
|
67
|
+
set :branch, "HEAD@{1}"
|
68
|
+
deploy.default
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'Rewrite reflog so HEAD@{1} will continue to point to the next previous release'
|
72
|
+
task :cleanup, :except => { :no_release => true } do
|
73
|
+
run "cd #{deploy_to}; git reflog delete --rewrite HEAD@{1}; git reflog delete --rewrite HEAD@{1}"
|
74
|
+
end
|
75
|
+
|
76
|
+
desc 'Roll back to the previously deployed version'
|
77
|
+
task :default do
|
78
|
+
rollback.repo
|
79
|
+
rollback.cleanup
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
namespace :pending do
|
84
|
+
task :diff, :except => { :no_release => true } do
|
85
|
+
# nothing
|
86
|
+
end
|
87
|
+
|
88
|
+
desc 'Show pending commits'
|
89
|
+
task :default do
|
90
|
+
system("git log --pretty=medium --stat #{current_revision}..origin/#{branch}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc 'Check that local git repo is in sync with remote'
|
95
|
+
task :check_repo do
|
96
|
+
unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
|
97
|
+
puts "WARNING: HEAD is not the same as origin/#{branch}"
|
98
|
+
puts "Run `git push origin #{branch}` to sync changes."
|
99
|
+
exit
|
100
|
+
end if fetch(:check_repo)
|
101
|
+
end
|
102
|
+
%w[deploy deploy:cold deploy:migrations].each do |task|
|
103
|
+
before "#{task}", "deploy:check_repo"
|
104
|
+
end
|
105
|
+
|
106
|
+
task :symlink do
|
107
|
+
# nothing
|
108
|
+
# if task is not being used, it will not appear in `cap -T`
|
109
|
+
end
|
110
|
+
|
111
|
+
task :create_symlink do
|
112
|
+
# nothing
|
113
|
+
# if task is not being used, it will not appear in `cap -T`
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Multistage
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
set :multistage_config, Config.new(configuration)
|
6
|
+
|
7
|
+
def stage(name, options={}, &block)
|
8
|
+
set :default_stage, name.to_sym if options.delete(:default)
|
9
|
+
multistage_config.stage(name, options)
|
10
|
+
callbacks[:start].detect { |c| c.source == 'multistage:ensure' }.except << name.to_s
|
11
|
+
|
12
|
+
task(name) do
|
13
|
+
set :current_stage, name.to_s
|
14
|
+
set :rails_env, name.to_s
|
15
|
+
options.each do |k, v|
|
16
|
+
set k, v if v
|
17
|
+
end
|
18
|
+
block.call if block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
namespace :multistage do
|
23
|
+
task :ensure do
|
24
|
+
unless exists?(:current_stage)
|
25
|
+
if stage = multistage_config.inferred_stage
|
26
|
+
find_and_execute_task(stage.name)
|
27
|
+
elsif exists?(:default_stage)
|
28
|
+
find_and_execute_task(default_stage)
|
29
|
+
else
|
30
|
+
stage_names = multistage_config.stages.map(&:name)
|
31
|
+
abort "No stage specified. Please specify one of: #{stage_names.join(', ')} (e.g. `cap #{stage_names.first} #{ARGV.last}')"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
on :start, 'multistage:ensure'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Handles multistage configuration
|
42
|
+
class Config
|
43
|
+
attr_reader :config
|
44
|
+
attr_reader :stages
|
45
|
+
|
46
|
+
def initialize(config)
|
47
|
+
@config = config
|
48
|
+
@stages = []
|
49
|
+
end
|
50
|
+
|
51
|
+
def stage(name, options={})
|
52
|
+
stages << Stage.new(name, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def inferred_stage
|
56
|
+
if config.using_recipe?(:git)
|
57
|
+
branch = config.local_branch
|
58
|
+
stages.find { |stage| stage.options[:branch].to_s == branch }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class Stage
|
64
|
+
attr_reader :name
|
65
|
+
attr_reader :options
|
66
|
+
|
67
|
+
def initialize(name, options={})
|
68
|
+
@name = name
|
69
|
+
@options = options
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Mysql
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
# MySQL admin user with access to create databases and grant permissions
|
6
|
+
_cset :mysql_admin_user, lambda { ask "Enter #{rails_env} database username with access to create database" }
|
7
|
+
|
8
|
+
# Application database adapter
|
9
|
+
_cset :mysql_adapter, lambda { 'mysql2' }
|
10
|
+
|
11
|
+
# Application database name
|
12
|
+
_cset :mysql_database, lambda { "#{application}_#{rails_env}" }
|
13
|
+
|
14
|
+
# Application database user
|
15
|
+
_cset :mysql_user, lambda { ask "Enter #{rails_env} database username" }
|
16
|
+
|
17
|
+
# Application database password
|
18
|
+
_cset(:mysql_password) { password_prompt "Enter #{rails_env} database password" }
|
19
|
+
|
20
|
+
# Application database host
|
21
|
+
_cset :mysql_host, lambda { 'localhost' }
|
22
|
+
|
23
|
+
# Application database encoding
|
24
|
+
_cset :mysql_encoding, lambda { 'utf8' }
|
25
|
+
|
26
|
+
# Path to local database config template
|
27
|
+
_cset :mysql_local_config_template, lambda { "#{templates_path}/mysql.yml.erb" }
|
28
|
+
|
29
|
+
# Path to remote database config file
|
30
|
+
_cset :mysql_remote_config_file, lambda { "#{config_path}/database.yml" }
|
31
|
+
|
32
|
+
# Application database backup file
|
33
|
+
_cset :mysql_backup_file, lambda { "#{application}-backup.sql.bz2" }
|
34
|
+
|
35
|
+
# Path to local database backup file
|
36
|
+
_cset :mysql_local_backup_file, lambda { "tmp/#{mysql_backup_file}" }
|
37
|
+
|
38
|
+
# Path to remote database backup file
|
39
|
+
_cset :mysql_remote_backup_file, lambda { "#{backup_path}/#{mysql_backup_file}" }
|
40
|
+
|
41
|
+
namespace :mysql do
|
42
|
+
desc 'Generate the database.yml configuration file'
|
43
|
+
task :setup, :roles => :app, :except => { :no_release => true } do
|
44
|
+
upload_template mysql_local_config_template, mysql_remote_config_file
|
45
|
+
end
|
46
|
+
after 'deploy:setup' do
|
47
|
+
mysql.setup if agree? 'Setup database.yml?'
|
48
|
+
mysql.create if agree? 'Create database?'
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'Create mysql database'
|
52
|
+
task :create, :roles => :db, :only => { :primary => true } do
|
53
|
+
sql = <<-SQL.gsub(/^ {14}/, '')
|
54
|
+
"CREATE DATABASE #{mysql_database};
|
55
|
+
GRANT ALL PRIVILEGES ON #{mysql_database}.* TO #{mysql_user}@localhost IDENTIFIED BY '#{mysql_password}';"
|
56
|
+
SQL
|
57
|
+
|
58
|
+
mysql_admin = mysql_admin_user
|
59
|
+
|
60
|
+
run "mysql --user=#{mysql_user} -p --execute=#{sql}" do |channel, stream, data|
|
61
|
+
if data =~ /^Enter password:/
|
62
|
+
pass = password_prompt "Enter database password for '#{mysql_admin}'"
|
63
|
+
channel.send_data "#{pass}\n"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Symlink the database.yml file into the latest deploy'
|
69
|
+
task :symlink, :roles => :app, :except => { :no_release => true } do
|
70
|
+
run "ln -nfs #{mysql_remote_config} #{release_path}/config/database.yml"
|
71
|
+
end
|
72
|
+
after 'deploy:finalize_update', 'mysql:symlink'
|
73
|
+
|
74
|
+
desc 'Populate the database with seed data'
|
75
|
+
task :seed do
|
76
|
+
run "cd #{current_path} && #{rake} RAILS_ENV=#{rails_env} db:seed"
|
77
|
+
end
|
78
|
+
after 'deploy:cold' do
|
79
|
+
mysql.seed if agree? 'Load seed data into database?'
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'Performs a mysqldump of the database'
|
83
|
+
task :dump, :roles => :db, :only => { :primary => true } do
|
84
|
+
prepare_from_yaml
|
85
|
+
|
86
|
+
run "mysqldump --user=#{db_user} -p --host=#{db_host} #{db_name} | bzip2 -z9 > #{mysql_remote_backup_file}" do |channel, stream, out|
|
87
|
+
channel.send_data "#{db_pass}\n" if out =~ /^Enter password:/
|
88
|
+
puts out
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
desc "Download compressed database dump"
|
93
|
+
task :fetch_dump, :roles => :db, :only => { :primary => true } do
|
94
|
+
download mysql_remote_backup_file, mysql_local_backup_file, :via => :scp
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Restore the database from the latest compressed dump"
|
98
|
+
task :restore, :roles => :db, :only => { :primary => true } do
|
99
|
+
prepare_from_yaml
|
100
|
+
|
101
|
+
run "bzcat #{mysql_remote_backup_file} | mysql --user=#{db_user} -p --host=#{db_host} #{db_name}" do |channel, stream, out|
|
102
|
+
channel.send_data "#{db_pass}\n" if out =~ /^Enter password:/
|
103
|
+
puts out
|
104
|
+
end if agree? 'Are you sure you want to restore your database?'
|
105
|
+
end
|
106
|
+
|
107
|
+
%w[start stop restart status].each do |command|
|
108
|
+
desc "#{command.capitalize} mysql"
|
109
|
+
task command, :roles => :db, :only => { :primary => true } do
|
110
|
+
run "#{sudo} service mysqld #{command}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def prepare_from_yaml
|
116
|
+
set(:db_user) { db_config[rails_env]["username"] }
|
117
|
+
set(:db_pass) { db_config[rails_env]["password"] }
|
118
|
+
set(:db_host) { db_config[rails_env]["host"] }
|
119
|
+
set(:db_name) { db_config[rails_env]["database"] }
|
120
|
+
end
|
121
|
+
|
122
|
+
def db_config
|
123
|
+
@db_config ||= fetch_db_config
|
124
|
+
end
|
125
|
+
|
126
|
+
def fetch_db_config
|
127
|
+
require 'yaml'
|
128
|
+
file = capture "cat #{mysql_remote_config_file}"
|
129
|
+
db_config = YAML.load(file)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module CapistranoRecipes
|
2
|
+
module Nginx
|
3
|
+
def self.load_into(configuration)
|
4
|
+
configuration.load do
|
5
|
+
# Nginx path on server
|
6
|
+
_cset :nginx_path, '/etc/nginx'
|
7
|
+
|
8
|
+
# Nginx http port
|
9
|
+
_cset :nginx_port, '80'
|
10
|
+
|
11
|
+
# Path to local nginx vhost template
|
12
|
+
_cset(:nginx_local_site_available_template) { "#{templates_path}/nginx.vhost.erb" }
|
13
|
+
|
14
|
+
# Path to remote sites-available location
|
15
|
+
_cset :nginx_remote_site_available_file, lambda { "#{nginx_path}/sites-available/#{application}" }
|
16
|
+
|
17
|
+
# Path to remote sites-enabled location
|
18
|
+
_cset :nginx_remote_site_enabled_link, lambda { "#{nginx_path}/sites-enabled/#{application}" }
|
19
|
+
|
20
|
+
# Whether or not to use ssl
|
21
|
+
_cset :use_ssl, false
|
22
|
+
|
23
|
+
# Nginx https port
|
24
|
+
_cset :nginx_ssl_port, '443'
|
25
|
+
|
26
|
+
# Nginx ssl directory on server
|
27
|
+
_cset :nginx_ssl_dir, 'ssl'
|
28
|
+
|
29
|
+
# Nginx ssl path on server
|
30
|
+
_cset :nginx_ssl_path, lambda { File.join nginx_path, nginx_ssl_dir }
|
31
|
+
|
32
|
+
# Nginx ssl certificates directory on server
|
33
|
+
_cset :nginx_ssl_certs_dir, 'certs'
|
34
|
+
|
35
|
+
# Nginx ssl private keys directory on server
|
36
|
+
_cset :nginx_ssl_private_dir, 'private'
|
37
|
+
|
38
|
+
# Nginx ssl certificates path on server
|
39
|
+
_cset :nginx_ssl_certs_path, lambda { File.join nginx_ssl_path, nginx_ssl_certs_dir }
|
40
|
+
|
41
|
+
# Nginx ssl private keys path on server
|
42
|
+
_cset :nginx_ssl_private_path, lambda { File.join nginx_ssl_path, nginx_ssl_private_dir }
|
43
|
+
|
44
|
+
# Nginx ssl certificate file
|
45
|
+
_cset :nginx_ssl_cert, lambda { "#{application}.crt" }
|
46
|
+
|
47
|
+
# Nginx ssl key file
|
48
|
+
_cset :nginx_ssl_key, lambda { "#{application}.key" }
|
49
|
+
|
50
|
+
def using_ssl?
|
51
|
+
fetch(:use_ssl)
|
52
|
+
end
|
53
|
+
|
54
|
+
namespace :nginx do
|
55
|
+
desc 'Create and upload nginx vhost'
|
56
|
+
task :setup, :roles => :web, :except => { :no_release => true } do
|
57
|
+
upload_template nginx_local_site_available_template, nginx_remote_site_available_file
|
58
|
+
run "#{sudo} ln -nfs #{nginx_remote_site_available_file} #{nginx_remote_site_enabled_link}"
|
59
|
+
restart
|
60
|
+
end
|
61
|
+
after 'deploy:setup' do
|
62
|
+
nginx.setup if agree?("Create and upload nginx vhost for #{application}?")
|
63
|
+
end
|
64
|
+
|
65
|
+
%w[start stop restart status].each do |command|
|
66
|
+
desc "#{command.capitalize} nginx"
|
67
|
+
task command, :roles => :app, :except => { :no_release => true } do
|
68
|
+
run "#{sudo} service nginx #{command}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|