wpcap 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +67 -0
- data/Rakefile +2 -0
- data/bin/wpcap +14 -0
- data/lib/wpcap/command.rb +64 -0
- data/lib/wpcap/recipes/base.rb +50 -0
- data/lib/wpcap/recipes/check.rb +19 -0
- data/lib/wpcap/recipes/memcached.rb +30 -0
- data/lib/wpcap/recipes/mysql.rb +230 -0
- data/lib/wpcap/recipes/nginx.rb +34 -0
- data/lib/wpcap/recipes/php.rb +48 -0
- data/lib/wpcap/recipes/server.rb +31 -0
- data/lib/wpcap/recipes/templates/deploy-stage.rb.erb +10 -0
- data/lib/wpcap/recipes/templates/deploy.rb.erb +35 -0
- data/lib/wpcap/recipes/templates/maintenance.html.erb +44 -0
- data/lib/wpcap/recipes/templates/mysql.yml.erb +8 -0
- data/lib/wpcap/recipes/templates/nginx_php.erb +58 -0
- data/lib/wpcap/recipes/templates/php-fpm.conf.erb +122 -0
- data/lib/wpcap/recipes/templates/php.ini.erb +1818 -0
- data/lib/wpcap/recipes/varnish.rb +17 -0
- data/lib/wpcap/recipes/wordpress.rb +185 -0
- data/lib/wpcap/utility.rb +14 -0
- data/lib/wpcap/version.rb +3 -0
- data/lib/wpcap.rb +5 -0
- data/wpcap.gemspec +19 -0
- metadata +106 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Russell Osborne
|
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,67 @@
|
|
1
|
+
# WPcap
|
2
|
+
|
3
|
+
WPcap is a set of capistrano recipes designed to deploy wordpress instaliations to ubuntu 12.04 and up. It provides database and asset sync tasks, per deploy mysql backups, a helper appication to setup a brand new wordpress install ready to be deployed.
|
4
|
+
|
5
|
+
WPcap is opinionated, and currently reasonably narrow minded.
|
6
|
+
|
7
|
+
WPcap assumptions
|
8
|
+
|
9
|
+
* Local Macine is a Mac running MAMP
|
10
|
+
* Remote Server is a brand new Ubuntu Server
|
11
|
+
* Passwordless access to remote server has be established (ssh keys)
|
12
|
+
* Wordpress is using mysql
|
13
|
+
|
14
|
+
WPcap server configuration
|
15
|
+
|
16
|
+
* nginx stable
|
17
|
+
* php5-fpm stable
|
18
|
+
* mysql > 5.5
|
19
|
+
* memcached
|
20
|
+
* varnish (Optional)
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Install it:
|
25
|
+
|
26
|
+
gem install wpcap
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
Create a new projet
|
31
|
+
|
32
|
+
wpcap create mynewproject
|
33
|
+
|
34
|
+
Build a remote server
|
35
|
+
|
36
|
+
cap deploy:install
|
37
|
+
|
38
|
+
Setup a remote server for this wordpress install
|
39
|
+
|
40
|
+
cap deploy:setup
|
41
|
+
|
42
|
+
Deploy your latest code to the server
|
43
|
+
|
44
|
+
cap deploy
|
45
|
+
|
46
|
+
Push Local Database and Assets to remote server
|
47
|
+
|
48
|
+
cap db:push
|
49
|
+
|
50
|
+
Pull Remote Database and Assets to local enviroment
|
51
|
+
|
52
|
+
cap db:pull
|
53
|
+
|
54
|
+
## Todo
|
55
|
+
|
56
|
+
* Covert a predone wordpress install into a wpcap style directory
|
57
|
+
* Do not require MAMP
|
58
|
+
* Allow users to customize templates by placing them in there config directory (think devise generators for views)
|
59
|
+
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/bin/wpcap
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
require 'wpcap'
|
7
|
+
require 'wpcap/command'
|
8
|
+
require 'wpcap/utility'
|
9
|
+
|
10
|
+
args = ARGV.dup
|
11
|
+
ARGV.clear
|
12
|
+
command = args.shift.strip rescue 'help'
|
13
|
+
|
14
|
+
Wpcap::Command.run(command, args)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class Wpcap::Command
|
2
|
+
require 'shellwords'
|
3
|
+
require 'wpcap/utility'
|
4
|
+
|
5
|
+
def self.run(command, args)
|
6
|
+
Wpcap::Command.send(command, args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.create(args)
|
10
|
+
@application = args.first
|
11
|
+
@wp_root = File.join( (args[1].nil? ? Dir.pwd : args[1]) , @application.to_s)
|
12
|
+
locale = args[2].nil? ? "en_US" : args[2]
|
13
|
+
puts @wp_root
|
14
|
+
if File.directory? "#{@wp_root}"
|
15
|
+
puts "Project Folder Already Exists"
|
16
|
+
return
|
17
|
+
end
|
18
|
+
`mkdir -p #{@wp_root}`
|
19
|
+
`cd #{@wp_root} && mkdir app`
|
20
|
+
|
21
|
+
if File.exists? @wp_root + 'app/wp-load.php'
|
22
|
+
puts "This folder seems to already contain wordpress files. "
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
if locale != "en_US"
|
27
|
+
output = IO.popen( "cd #{@wp_root} && curl -s #{Shellwords.escape( 'https://api.wordpress.org/core/version-check/1.5/?locale=')}#{locale} " )
|
28
|
+
download_url = output[2].gsub(".zip", ".tar.gz")
|
29
|
+
puts 'Downloading WordPress #{output[3]} (#{output[4]})...'
|
30
|
+
else
|
31
|
+
download_url = 'https://wordpress.org/latest.tar.gz';
|
32
|
+
puts 'Downloading latest WordPress (en_US)...'
|
33
|
+
end
|
34
|
+
|
35
|
+
`cd #{@application} && curl -f #{Shellwords.escape( download_url )} | tar xz`
|
36
|
+
`cd #{@application} && mv wordpress/* app`
|
37
|
+
`rm -rf #{@wp_root}/wordpress`
|
38
|
+
|
39
|
+
puts 'WordPress downloaded.'
|
40
|
+
self.setup
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.setup
|
44
|
+
puts "Capifying your project and seting up config directories"
|
45
|
+
unless File.exists? "#{@wp_root}/app/wp-load.php"
|
46
|
+
puts "This does not Appear to be a wpcap"
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
`capify #{@wp_root}`
|
51
|
+
`touch #{@wp_root}/config/database.yml`
|
52
|
+
`rm #{@wp_root}/config/deploy.rb`
|
53
|
+
`cp #{File.dirname(__FILE__)}/recipes/templates/deploy.rb.erb #{@wp_root}/config/deploy.rb`
|
54
|
+
`mkdir -p #{@wp_root}/config/deploy`
|
55
|
+
`cp #{File.dirname(__FILE__)}/recipes/templates/deploy-stage.rb.erb #{@wp_root}/config/deploy/staging.rb`
|
56
|
+
`cp #{File.dirname(__FILE__)}/recipes/templates/deploy-stage.rb.erb #{@wp_root}/config/deploy/production.rb`
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.help(cmd)
|
61
|
+
puts "`#{cmd}` is not a wpcap command."
|
62
|
+
puts "See `wpcap help` for a list of available commands."
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'railsless-deploy'
|
3
|
+
require 'capistrano/ext/multistage'
|
4
|
+
|
5
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
6
|
+
Capistrano::Configuration.instance(:must_exist) :
|
7
|
+
Capistrano.configuration(:must_exist)
|
8
|
+
|
9
|
+
configuration.load do
|
10
|
+
|
11
|
+
def template(from, to)
|
12
|
+
erb = File.read(File.expand_path("../templates/#{from}", __FILE__))
|
13
|
+
put ERB.new(erb).result(binding), to
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_default(name, *args, &block)
|
17
|
+
set(name, *args, &block) unless exists?(name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def random_password(size = 8)
|
21
|
+
chars = (('a'..'z').to_a + ('0'..'9').to_a) - %w(i o 0 1 l 0)
|
22
|
+
(1..size).collect{|a| chars[rand(chars.size)] }.join
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_with_tty(server, cmd)
|
26
|
+
# looks like total pizdets
|
27
|
+
command = []
|
28
|
+
command += %W( ssh -t #{gateway} -l #{self[:gateway_user] || self[:user]} ) if self[:gateway]
|
29
|
+
command += %W( ssh -t )
|
30
|
+
command += %W( -p #{server.port}) if server.port
|
31
|
+
command += %W( -l #{user} #{server.host} )
|
32
|
+
command += %W( cd #{current_path} )
|
33
|
+
# have to escape this once if running via double ssh
|
34
|
+
command += [self[:gateway] ? '\&\&' : '&&']
|
35
|
+
command += Array(cmd)
|
36
|
+
system * command
|
37
|
+
end
|
38
|
+
|
39
|
+
default_run_options[:pty] = true
|
40
|
+
ssh_options[:forward_agent] = true
|
41
|
+
set :use_sudo , false
|
42
|
+
|
43
|
+
namespace :deploy do
|
44
|
+
desc "Install everything onto the server"
|
45
|
+
task :install do
|
46
|
+
run "#{sudo} apt-get -y update"
|
47
|
+
run "#{sudo} apt-get -y install git debconf-utils python-software-properties"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
2
|
+
Capistrano::Configuration.instance(:must_exist) :
|
3
|
+
Capistrano.configuration(:must_exist)
|
4
|
+
|
5
|
+
configuration.load do
|
6
|
+
namespace :check do
|
7
|
+
desc "Make sure local git is in sync with remote."
|
8
|
+
task :revision, roles: :web do
|
9
|
+
unless `git rev-parse HEAD` == `git rev-parse origin/#{branch}`
|
10
|
+
puts "WARNING: HEAD is not the same as origin/#{branch}"
|
11
|
+
puts "Run `git push` to sync changes."
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
end
|
15
|
+
before "deploy", "check:revision"
|
16
|
+
before "deploy:migrations", "check:revision"
|
17
|
+
before "deploy:cold", "check:revision"
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
2
|
+
Capistrano::Configuration.instance(:must_exist) :
|
3
|
+
Capistrano.configuration(:must_exist)
|
4
|
+
|
5
|
+
configuration.load do
|
6
|
+
set_default :memcached_memory_limit, 256
|
7
|
+
|
8
|
+
namespace :memcached do
|
9
|
+
desc "Install Memcached"
|
10
|
+
task :install, roles: :app do
|
11
|
+
run "#{sudo} apt-get install memcached"
|
12
|
+
end
|
13
|
+
after "deploy:install", "memcached:install"
|
14
|
+
|
15
|
+
desc "Setup Memcached"
|
16
|
+
task :setup, roles: :app do
|
17
|
+
template "memcached.erb", "/tmp/memcached.conf"
|
18
|
+
run "#{sudo} mv /tmp/memcached.conf /etc/memcached.conf"
|
19
|
+
restart
|
20
|
+
end
|
21
|
+
after "deploy:setup", "memcached:setup"
|
22
|
+
|
23
|
+
%w[start stop restart].each do |command|
|
24
|
+
desc "#{command} Memcached"
|
25
|
+
task command, roles: :app do
|
26
|
+
run "service memcached #{command}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
require 'wpcap'
|
4
|
+
require 'wpcap/utility'
|
5
|
+
|
6
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
7
|
+
Capistrano::Configuration.instance(:must_exist) :
|
8
|
+
Capistrano.configuration(:must_exist)
|
9
|
+
|
10
|
+
configuration.load do
|
11
|
+
namespace :db do
|
12
|
+
namespace :mysql do
|
13
|
+
desc "Install Mysql Database Server"
|
14
|
+
task :install_server, roles: :db do
|
15
|
+
create_yaml
|
16
|
+
prepare_env
|
17
|
+
run "#{sudo} apt-get -y update"
|
18
|
+
run "#{sudo} echo 'mysql-server-5.5 mysql-server/root_password password #{db_priv_pass}' | #{sudo} debconf-set-selections"
|
19
|
+
run "#{sudo} echo 'mysql-server-5.5 mysql-server/root_password_again password #{db_priv_pass}' | #{sudo} debconf-set-selections"
|
20
|
+
run "#{sudo} apt-get -y install mysql-server"
|
21
|
+
end
|
22
|
+
after "deploy:install", "db:mysql:install_server"
|
23
|
+
|
24
|
+
desc "Install Mysql Database Client Bindings"
|
25
|
+
task :install_client, roles: :web do
|
26
|
+
run "#{sudo} apt-get -y update"
|
27
|
+
run "#{sudo} apt-get -y install mysql-client"
|
28
|
+
end
|
29
|
+
after "deploy:install", "db:mysql:install_client"
|
30
|
+
|
31
|
+
desc <<-EOF
|
32
|
+
Performs a compressed database dump. \
|
33
|
+
WARNING: This locks your tables for the duration of the mysqldump.
|
34
|
+
Don't run it madly!
|
35
|
+
EOF
|
36
|
+
task :dump, :roles => :db, :only => { :primary => true } do
|
37
|
+
|
38
|
+
prepare_env
|
39
|
+
run "mkdir -p #{backups_path}"
|
40
|
+
filename = "db_backup.#{Time.now.utc.to_i}.sql.bz2"
|
41
|
+
filepath = "#{backups_path}/#{filename}"
|
42
|
+
on_rollback { run "rm #{filepath}" }
|
43
|
+
run "mysqldump --user=#{db_username} -p --host=#{db_host} #{db_database} | bzip2 -z9 > #{filepath}" do |ch, stream, out|
|
44
|
+
ch.send_data "#{db_password}\n" if out =~ /^Enter password:/
|
45
|
+
puts out
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
desc "Restores the database from the latest compressed dump"
|
50
|
+
task :restore_most_recent, :roles => :db, :only => { :primary => true } do
|
51
|
+
prepare_env
|
52
|
+
run "bzcat #{most_recent_backup} | mysql --user=#{db_username} -p --host=#{db_host} #{db_database}" do |ch, stream, out|
|
53
|
+
ch.send_data "#{db_password}\n" if out =~ /^Enter password:/
|
54
|
+
puts out
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "Restores the database from the latest downloaded compressed dump"
|
59
|
+
task :local_restore do
|
60
|
+
prepare_env(:development)
|
61
|
+
run_locally "bzcat #{local_dump} | #{local_mysql_path}mysql --user=#{db_username} -p#{db_password} #{db_database}"
|
62
|
+
run_locally "rm #{local_dump}"
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Downloads the compressed database dump to this machine"
|
66
|
+
task :fetch_dump, :roles => :db, :only => { :primary => true } do
|
67
|
+
prepare_env
|
68
|
+
run_locally "touch #{local_dump}"
|
69
|
+
download most_recent_backup, local_dump, :via => :scp
|
70
|
+
end
|
71
|
+
|
72
|
+
desc "Uploads the compressed database dump to the remote server"
|
73
|
+
task :push_dump, :roles => :db, :only => { :primary => true } do
|
74
|
+
prepare_env(:development)
|
75
|
+
run_locally "#{local_mysql_path}mysqldump --user #{db_username} --password=#{db_password} #{db_database} | bzip2 -z9 > #{local_dump}"
|
76
|
+
run "mkdir -p #{backups_path}"
|
77
|
+
filename = "local_upload.#{Time.now.to_f}.sql.bz2"
|
78
|
+
filepath = "#{backups_path}/#{filename}"
|
79
|
+
upload "#{local_dump}" , "#{filepath}"
|
80
|
+
end
|
81
|
+
|
82
|
+
desc "Push the Local DB to Remote Server"
|
83
|
+
task :push, :roles => :db do
|
84
|
+
prepare_env
|
85
|
+
push_dump
|
86
|
+
restore_most_recent
|
87
|
+
run_locally "rm #{local_dump}"
|
88
|
+
end
|
89
|
+
|
90
|
+
desc "Pull the Remote DB to Local"
|
91
|
+
task :pull, :roles => :db do
|
92
|
+
prepare_env
|
93
|
+
dump
|
94
|
+
fetch_dump
|
95
|
+
local_restore
|
96
|
+
end
|
97
|
+
|
98
|
+
desc "Create MySQL database and user for this stage using database.yml values"
|
99
|
+
task :create, :roles => :db, :only => { :primary => true } do
|
100
|
+
prepare_env
|
101
|
+
create_db_if_missing
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Create MySQL database and user for this stage using database.yml values on your local machine"
|
105
|
+
task :create_local_db do
|
106
|
+
prepare_env
|
107
|
+
create_db_if_missing("development")
|
108
|
+
end
|
109
|
+
|
110
|
+
desc "Load the DB enviroment from the app server"
|
111
|
+
task :prepare_enviroment do
|
112
|
+
prepare_env
|
113
|
+
end
|
114
|
+
|
115
|
+
desc "Remote dbconsole"
|
116
|
+
task :dbconsole, :roles => :app do
|
117
|
+
prepare_env
|
118
|
+
server = find_servers(:roles => [:db]).first
|
119
|
+
run_with_tty server, %W( mysql --user=#{db_username} -password#{db_password} --host=#{db_host} #{db_database} )
|
120
|
+
end
|
121
|
+
|
122
|
+
desc "Create database.yml in shared path with settings for current stage and test env"
|
123
|
+
task :create_yaml do
|
124
|
+
prepare_env
|
125
|
+
template_path = "#{shared_path}/config/database.yml"
|
126
|
+
|
127
|
+
unless db_config[rails_env]
|
128
|
+
set :db_priv_pass, random_password(16)
|
129
|
+
set :db_username, "#{application.split(".").first}_#{stage}"
|
130
|
+
set :db_database, "#{application.split(".").first}_#{stage}"
|
131
|
+
set :db_password, random_password(16)
|
132
|
+
run "mkdir -p #{shared_path}/config"
|
133
|
+
template "mysql.yml.erb", template_path
|
134
|
+
server_yaml = capture "cat #{template_path}"
|
135
|
+
server_mysql_config_yaml = YAML.load(server_yaml)
|
136
|
+
update_db_config(server_mysql_config_yaml)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def db_config
|
141
|
+
@db_config ||= fetch_db_config
|
142
|
+
end
|
143
|
+
|
144
|
+
def fetch_db_config
|
145
|
+
YAML.load(File.open("config/database.yml"))
|
146
|
+
end
|
147
|
+
|
148
|
+
# Sets database variables from remote database.yaml
|
149
|
+
def prepare_env(rails_env = stage)
|
150
|
+
abort "No Database Configuratons Found" if !db_config
|
151
|
+
|
152
|
+
rails_env = rails_env.to_s
|
153
|
+
set(:local_dump) { "/tmp/#{application}.sql.bz2" }
|
154
|
+
|
155
|
+
if db_config[rails_env]
|
156
|
+
set(:db_priv_user) { db_config[rails_env]["priv_username"].nil? ? db_config[rails_env]["username"] : db_config[rails_env]["priv_username"] }
|
157
|
+
set(:db_priv_pass) { db_config[rails_env]["priv_password"].nil? ? db_config[rails_env]["password"] : db_config[rails_env]["priv_password"] }
|
158
|
+
set(:db_host) { db_config[rails_env]["host"] }
|
159
|
+
set(:db_database) { db_config[rails_env]["database"] }
|
160
|
+
set(:db_username) { db_config[rails_env]["username"] }
|
161
|
+
set(:db_password) { db_config[rails_env]["password"] }
|
162
|
+
set(:db_encoding) { db_config[rails_env]["encoding"] }
|
163
|
+
set(:db_prefix) { db_config[rails_env]["prefix"].nil? ? db_config["development"]["prefix"] : db_config[rails_env]["prefix"] }
|
164
|
+
else
|
165
|
+
Wpcap::Utility.error "No Database Configuration for #{rails_env} Found"
|
166
|
+
abort
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
def update_db_config(hash_to_save)
|
172
|
+
database_yaml = db_config.merge(hash_to_save)
|
173
|
+
print "Saving Database Config file to local Repo"
|
174
|
+
File.open('config/database.yml', 'w') do |f|
|
175
|
+
f.puts YAML::dump(database_yaml).sub("---","").split("\n").map(&:rstrip).join("\n").strip
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def most_recent_backup
|
180
|
+
most_recent_sql = capture "cd #{backups_path}; ls -lrt | awk '{ f=$NF }; END{ print f }'"
|
181
|
+
return "#{backups_path}/#{most_recent_sql}".strip
|
182
|
+
end
|
183
|
+
|
184
|
+
def database_exits?(environment = stage)
|
185
|
+
exists = false
|
186
|
+
databases = run_mysql_command("show databases;", environment)
|
187
|
+
exists = exists || databases.include?(db_database)
|
188
|
+
exists
|
189
|
+
end
|
190
|
+
|
191
|
+
def create_db_if_missing(environment = stage)
|
192
|
+
unless database_exits?(environment)
|
193
|
+
sql = <<-SQL
|
194
|
+
CREATE DATABASE #{db_database};
|
195
|
+
GRANT ALL PRIVILEGES ON #{db_database}.* TO #{db_username}@#{db_host} IDENTIFIED BY '#{db_password}';
|
196
|
+
SQL
|
197
|
+
|
198
|
+
run_mysql_command(sql, environment)
|
199
|
+
else
|
200
|
+
print "databases exists -- skipping"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
def run_mysql_command(sql, environment = stage)
|
205
|
+
environment = environment.to_s
|
206
|
+
prepare_env(environment)
|
207
|
+
|
208
|
+
db_username = db_priv_user
|
209
|
+
db_password = db_priv_pass
|
210
|
+
output = ""
|
211
|
+
if environment == "development"
|
212
|
+
output = run_locally "#{local_mysql_path}mysql --user=#{db_username} -p#{db_password} --execute=\"#{sql}\""
|
213
|
+
else
|
214
|
+
run "mysql --user=#{db_username} --password --execute=\"#{sql}\"" do |channel, stream, data|
|
215
|
+
if data =~ /^Enter password:/
|
216
|
+
channel.send_data "#{db_password}\n"
|
217
|
+
end
|
218
|
+
output += data
|
219
|
+
end
|
220
|
+
end
|
221
|
+
return output
|
222
|
+
end
|
223
|
+
before "db:mysql:push", "db:mysql:create"
|
224
|
+
before "db:mysql:pull", "db:mysql:create_local_db"
|
225
|
+
after "deploy:update_code" , "db:mysql:prepare_enviroment"
|
226
|
+
after "deploy:setup", "db:mysql:create"
|
227
|
+
before :deploy, 'db:mysql:dump'
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
2
|
+
Capistrano::Configuration.instance(:must_exist) :
|
3
|
+
Capistrano.configuration(:must_exist)
|
4
|
+
|
5
|
+
configuration.load do
|
6
|
+
namespace :nginx do
|
7
|
+
desc "Install latest stable release of nginx"
|
8
|
+
task :install, roles: :web do
|
9
|
+
run "#{sudo} add-apt-repository ppa:nginx/stable -y"
|
10
|
+
run "#{sudo} apt-get -y update"
|
11
|
+
run "#{sudo} apt-get -y install nginx"
|
12
|
+
end
|
13
|
+
after "deploy:install", "nginx:install"
|
14
|
+
|
15
|
+
desc "Setup nginx configuration for this application"
|
16
|
+
task :setup, roles: :web do
|
17
|
+
template "nginx_php.erb", "/tmp/nginx_conf"
|
18
|
+
run "#{sudo} mv /tmp/nginx_conf /etc/nginx/sites-enabled/#{application}"
|
19
|
+
run "#{sudo} rm -f /etc/nginx/sites-enabled/default"
|
20
|
+
run "mkdir -p #{shared_path}/logs"
|
21
|
+
run "#{sudo} touch #{shared_path}/logs/access.log"
|
22
|
+
run "#{sudo} touch #{shared_path}/logs/error.log"
|
23
|
+
restart
|
24
|
+
end
|
25
|
+
after "deploy:setup", "nginx:setup"
|
26
|
+
|
27
|
+
%w[start stop restart].each do |command|
|
28
|
+
desc "#{command} nginx"
|
29
|
+
task command, roles: :web do
|
30
|
+
run "#{sudo} service nginx #{command}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
2
|
+
Capistrano::Configuration.instance(:must_exist) :
|
3
|
+
Capistrano.configuration(:must_exist)
|
4
|
+
|
5
|
+
configuration.load do
|
6
|
+
|
7
|
+
namespace :php do
|
8
|
+
desc "Install the latest relase of PHP and PHP-FPM"
|
9
|
+
task :install, roles: :app do
|
10
|
+
run "#{sudo} add-apt-repository ppa:ondrej/php5 -y"
|
11
|
+
run "#{sudo} apt-get -y update"
|
12
|
+
run "#{sudo} apt-get -y install php5 php5-fpm php5-mysql php5-memcache php-apc"
|
13
|
+
end
|
14
|
+
after "deploy:install", "php:install"
|
15
|
+
|
16
|
+
desc "Setup php and php fpm configuration for this application"
|
17
|
+
task :setup, roles: :web do
|
18
|
+
template "php-fpm.conf.erb", "/tmp/php_fpm_conf"
|
19
|
+
run "#{sudo} mv /tmp/php_fpm_conf /etc/php5/fpm/php-fpm.conf"
|
20
|
+
|
21
|
+
template "php.ini.erb", "/tmp/php_ini"
|
22
|
+
run "#{sudo} mv /tmp/php_ini /etc/php5/fpm/php.ini"
|
23
|
+
|
24
|
+
restart
|
25
|
+
end
|
26
|
+
after "deploy:setup", "php:setup"
|
27
|
+
|
28
|
+
namespace :apc do
|
29
|
+
desc "Disable the APC administrative panel"
|
30
|
+
task :disable, :roles => :web, :except => { :no_release => true } do
|
31
|
+
run "rm #{current_path}/app/apc.php"
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Enable the APC administrative panel"
|
35
|
+
task :enable, :roles => :web, :except => { :no_release => true } do
|
36
|
+
run "ln -s /usr/local/lib/php/apc.php #{current_path}/app/apc.php"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
%w[start stop restart].each do |command|
|
41
|
+
desc "#{command} php5-fpm"
|
42
|
+
task command, roles: :web do
|
43
|
+
run "#{sudo} service php5-fpm #{command}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
after "deploy", "php:restart"
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
configuration = Capistrano::Configuration.respond_to?(:instance) ?
|
2
|
+
Capistrano::Configuration.instance(:must_exist) :
|
3
|
+
Capistrano.configuration(:must_exist)
|
4
|
+
|
5
|
+
configuration.load do
|
6
|
+
namespace :servers do
|
7
|
+
desc "Update Servers"
|
8
|
+
task :update do
|
9
|
+
run "#{sudo} apt-get update -y"
|
10
|
+
run "#{sudo} apt-get upgrade -y"
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "Restart Servers"
|
14
|
+
task :restart do
|
15
|
+
run "#{sudo} reboot"
|
16
|
+
end
|
17
|
+
|
18
|
+
%w[access error].each do |log|
|
19
|
+
desc "Tail #{log} log"
|
20
|
+
task "#{log}_log", roles: :web do
|
21
|
+
run "tail -f #{shared_path}/logs/error.log" do |channel, stream, data|
|
22
|
+
trap("INT") { puts 'Interupted'; exit 0; }
|
23
|
+
puts # for an extra line break before the host name
|
24
|
+
puts "#{channel[:host]}: #{data}"
|
25
|
+
break if stream == :err
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# Deploy WordPress site using Capistrano
|
2
|
+
#
|
3
|
+
# Usage:
|
4
|
+
# cap production deploy:setup
|
5
|
+
# cap production deploy
|
6
|
+
|
7
|
+
set :user, "root"
|
8
|
+
set :application_url, "your full url here includeing the protocol (https/http)"
|
9
|
+
server "your server address or url here", :web, :app, :db, primary: true
|
10
|
+
|