ubistrano 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.markdown +162 -0
- data/Rakefile +25 -0
- data/bin/ubify +13 -0
- data/changelog.markdown +54 -0
- data/example/deploy.rb +29 -0
- data/gemspec.rb +19 -0
- data/lib/ubistrano.rb +83 -0
- data/lib/ubistrano/apache.rb +38 -0
- data/lib/ubistrano/deploy.rb +67 -0
- data/lib/ubistrano/ec2.rb +113 -0
- data/lib/ubistrano/gems.rb +29 -0
- data/lib/ubistrano/helpers.rb +287 -0
- data/lib/ubistrano/log.rb +20 -0
- data/lib/ubistrano/mysql.rb +85 -0
- data/lib/ubistrano/rails.rb +76 -0
- data/lib/ubistrano/sinatra.rb +20 -0
- data/lib/ubistrano/ssh.rb +56 -0
- data/lib/ubistrano/stage.rb +29 -0
- data/lib/ubistrano/ubuntu.rb +273 -0
- data/templates/apache/virtual_host.erb +32 -0
- data/templates/log/rotate.conf.erb +9 -0
- data/templates/rails/database.yml.erb +13 -0
- data/templates/ubuntu/apache.god.erb +31 -0
- data/templates/ubuntu/god.erb +36 -0
- data/templates/ubuntu/god.god.erb +1 -0
- data/templates/ubuntu/iptables.rules.erb +31 -0
- data/templates/ubuntu/mysql.god.erb +31 -0
- data/templates/ubuntu/sshd.god.erb +31 -0
- data/ubistrano.gemspec +32 -0
- metadata +93 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 AppTower
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
Ubistrano
|
2
|
+
=========
|
3
|
+
|
4
|
+
Provision and deploy to an Ubuntu/God/Apache/Passenger stack using Capistrano and EC2.
|
5
|
+
|
6
|
+
Goals
|
7
|
+
-----
|
8
|
+
|
9
|
+
* Create an Ubuntu Hardy EC2 instance in one command (<code>cap ec2</code>)
|
10
|
+
* Provision a solid Ubuntu Hardy application server in one command (<code>cap ubuntu</code>)
|
11
|
+
* Deploy PHP, Rails, and Sinatra apps
|
12
|
+
* Be descriptive about what is going on and allow the user to opt out
|
13
|
+
* Simplify the <code>deploy.rb</code> file
|
14
|
+
|
15
|
+
The stack
|
16
|
+
---------
|
17
|
+
|
18
|
+
* Apache
|
19
|
+
* EC2 (optional)
|
20
|
+
* Git
|
21
|
+
* MySQL
|
22
|
+
* MySQLTuner
|
23
|
+
* Perl
|
24
|
+
* PHP
|
25
|
+
* Postfix (relay)
|
26
|
+
* Ruby
|
27
|
+
* RubyGems
|
28
|
+
* Passenger (mod\_rails)
|
29
|
+
* God
|
30
|
+
* Rails
|
31
|
+
* Sinatra
|
32
|
+
* Sphinx
|
33
|
+
|
34
|
+
|
35
|
+
Getting started
|
36
|
+
---------------
|
37
|
+
|
38
|
+
### Install gem
|
39
|
+
|
40
|
+
gem install winton-ubistrano
|
41
|
+
|
42
|
+
### Ubify your project
|
43
|
+
|
44
|
+
<pre>
|
45
|
+
cd your_project
|
46
|
+
ubify .
|
47
|
+
</pre>
|
48
|
+
|
49
|
+
* Runs <code>capify</code>
|
50
|
+
* Creates <code>config/deploy.example.rb</code>
|
51
|
+
* Adds <code>config/deploy.rb</code> to your project's <code>.gitignore</code>
|
52
|
+
|
53
|
+
### Copy config/deploy.example.rb to config/deploy.rb
|
54
|
+
|
55
|
+
It should look like this:
|
56
|
+
|
57
|
+
<pre>
|
58
|
+
set :ubistrano, {
|
59
|
+
:application => :my_app,
|
60
|
+
:platform => :rails, # :php, :rails, :sinatra
|
61
|
+
:repository => 'git@github.com:user/my-app.git',
|
62
|
+
|
63
|
+
:ec2 => {
|
64
|
+
:access_key => '',
|
65
|
+
:secret_key => ''
|
66
|
+
},
|
67
|
+
|
68
|
+
:mysql => {
|
69
|
+
:root_password => '',
|
70
|
+
:app_password => ''
|
71
|
+
# Ubistrano creates a mysql user for each app
|
72
|
+
},
|
73
|
+
|
74
|
+
:production => {
|
75
|
+
:domains => [ 'myapp.com', 'www.myapp.com' ],
|
76
|
+
:ssl => [ 'myapp.com' ],
|
77
|
+
:host => '127.0.0.1'
|
78
|
+
},
|
79
|
+
|
80
|
+
:staging => {
|
81
|
+
:domains => [ 'staging.myapp.com' ],
|
82
|
+
:host => '127.0.0.1'
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
require 'ubistrano'
|
87
|
+
</pre>
|
88
|
+
|
89
|
+
Ubistrano uses the same Capistrano options you've come to love, but provides defaults and a few extra options as well.
|
90
|
+
|
91
|
+
Edit deploy.rb to the best of your ability. If setting up an EC2 instance, be sure to provide your AWS keys. Your IP address will be provided later. Provide passwords even if they haven't been created yet.
|
92
|
+
|
93
|
+
Feel free to move any options into or out of the stage groups.
|
94
|
+
|
95
|
+
Create your EC2 instance
|
96
|
+
------------------------
|
97
|
+
|
98
|
+
### From your app directory
|
99
|
+
|
100
|
+
<pre>
|
101
|
+
cap ec2
|
102
|
+
</pre>
|
103
|
+
|
104
|
+
### Example output
|
105
|
+
|
106
|
+
<pre>
|
107
|
+
================================================================================
|
108
|
+
Press enter for Ubuntu Hardy or enter an AMI image id:
|
109
|
+
</pre>
|
110
|
+
|
111
|
+
Set up your Ubuntu Hardy server
|
112
|
+
-------------------------------
|
113
|
+
|
114
|
+
### From your app directory
|
115
|
+
|
116
|
+
<pre>
|
117
|
+
cap ubuntu
|
118
|
+
</pre>
|
119
|
+
|
120
|
+
### Example output
|
121
|
+
|
122
|
+
<pre>
|
123
|
+
================================================================================
|
124
|
+
Let's set up an Ubuntu server! (Tested with 8.04 LTS Hardy)
|
125
|
+
|
126
|
+
With each task, Ubistrano will describe what it is doing, and wait for a yes/no.
|
127
|
+
|
128
|
+
================================================================================
|
129
|
+
Please ssh into your server (use -i only for EC2):
|
130
|
+
ssh root@174.129.232.34 -i ~/.ssh/id_rsa-studicious
|
131
|
+
|
132
|
+
Edit your sudoers file:
|
133
|
+
visudo
|
134
|
+
|
135
|
+
Add the following line:
|
136
|
+
deploy ALL=NOPASSWD: ALL
|
137
|
+
|
138
|
+
Continue? (y/n)
|
139
|
+
</pre>
|
140
|
+
|
141
|
+
Deploy your app
|
142
|
+
---------------
|
143
|
+
|
144
|
+
All apps should have a <code>public</code> directory.
|
145
|
+
|
146
|
+
### First deploy
|
147
|
+
|
148
|
+
cap deploy:first
|
149
|
+
|
150
|
+
### Subsequent deploys
|
151
|
+
|
152
|
+
cap deploy
|
153
|
+
|
154
|
+
|
155
|
+
Deploy to staging
|
156
|
+
-----------------
|
157
|
+
|
158
|
+
Use any capistrano task, but replace <code>cap</code> with <code>cap staging</code>.
|
159
|
+
|
160
|
+
### Example
|
161
|
+
|
162
|
+
cap staging deploy:first
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
require 'gemspec'
|
6
|
+
|
7
|
+
desc "Generate gemspec"
|
8
|
+
task :gemspec do
|
9
|
+
File.open("#{Dir.pwd}/#{GEM_NAME}.gemspec", 'w') do |f|
|
10
|
+
f.write(GEM_SPEC.to_ruby)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Install gem"
|
15
|
+
task :install do
|
16
|
+
Rake::Task['gem'].invoke
|
17
|
+
`sudo gem uninstall #{GEM_NAME} -x`
|
18
|
+
`sudo gem install pkg/#{GEM_NAME}*.gem`
|
19
|
+
`rm -Rf pkg`
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Package gem"
|
23
|
+
Rake::GemPackageTask.new(GEM_SPEC) do |pkg|
|
24
|
+
pkg.gem_spec = GEM_SPEC
|
25
|
+
end
|
data/bin/ubify
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
UBISTRANO = File.expand_path("../", File.dirname(__FILE__))
|
4
|
+
TO = File.expand_path("#{ARGV.join(' ')}", FileUtils.pwd)
|
5
|
+
|
6
|
+
# Capify
|
7
|
+
`capify #{TO}`
|
8
|
+
|
9
|
+
# Copy config/deploy.example.rb
|
10
|
+
FileUtils.cp "#{UBISTRANO}/example/deploy.rb", "#{TO}/config/deploy.example.rb"
|
11
|
+
|
12
|
+
# Add config/deploy.rb to .gitignore
|
13
|
+
File.open("#{TO}/.gitignore", 'a') { |f| f.write("\nconfig/deploy.rb\n") }
|
data/changelog.markdown
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
Version 1.2.7
|
2
|
+
-------------
|
3
|
+
|
4
|
+
* More work on Sinatra tasks
|
5
|
+
* God init.d updates
|
6
|
+
* Better Rakefile
|
7
|
+
|
8
|
+
Version 1.2.6
|
9
|
+
-------------
|
10
|
+
|
11
|
+
* Sinatra projects should have their own config.ru present, getting rid of sinatra:install
|
12
|
+
|
13
|
+
Version 1.2.5
|
14
|
+
-------------
|
15
|
+
|
16
|
+
* Removing unnecessary tmp/restart.txt touch for PHP apps
|
17
|
+
* Fixed some of the mysql:backup tasks
|
18
|
+
|
19
|
+
Version 1.2.4
|
20
|
+
-------------
|
21
|
+
|
22
|
+
* Complete EC2/Ubuntu Hardy provision and deploy tested with Rails and Sinatra
|
23
|
+
|
24
|
+
Version 1.2.3
|
25
|
+
-------------
|
26
|
+
|
27
|
+
* Added bin/ubify which executes capify in addition to copying config/deploy.example.rb and adding config/deploy.rb to the project's .gitignore
|
28
|
+
* Added mysql option in deploy.rb
|
29
|
+
* Minor ubuntu:install fixes
|
30
|
+
|
31
|
+
Version 1.2.2
|
32
|
+
-------------
|
33
|
+
|
34
|
+
* Hardened cap ec2 -> cap ubuntu -> cap ubuntu:install
|
35
|
+
* There should be nothing to cause the user to stop and restart the tasks
|
36
|
+
|
37
|
+
Version 1.2.0
|
38
|
+
-------------
|
39
|
+
|
40
|
+
* New EC2 tasks
|
41
|
+
* EC2 setup and `cap ubuntu` provision tested
|
42
|
+
|
43
|
+
Version 1.1.0
|
44
|
+
-------------
|
45
|
+
|
46
|
+
* Sinatra apps deploying properly
|
47
|
+
* PHP and Rails apps should be deploying properly
|
48
|
+
* `cap ubuntu` flow hardened
|
49
|
+
|
50
|
+
Version 1.0.3
|
51
|
+
-------------
|
52
|
+
|
53
|
+
* `cap ubuntu` tested on Ubuntu 8.04 LTS Hardy
|
54
|
+
* App deploying not at all tested
|
data/example/deploy.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
set :ubistrano, {
|
2
|
+
:application => :my_app,
|
3
|
+
:platform => :rails, # :php, :rails, :sinatra
|
4
|
+
:repository => 'git@github.com:user/my-app.git',
|
5
|
+
|
6
|
+
:ec2 => {
|
7
|
+
:access_key => '',
|
8
|
+
:secret_key => ''
|
9
|
+
},
|
10
|
+
|
11
|
+
:mysql => {
|
12
|
+
:root_password => '',
|
13
|
+
:app_password => ''
|
14
|
+
# Ubistrano creates a mysql user for each app
|
15
|
+
},
|
16
|
+
|
17
|
+
:production => {
|
18
|
+
:domains => [ 'myapp.com', 'www.myapp.com' ],
|
19
|
+
:ssl => [ 'myapp.com' ],
|
20
|
+
:host => '127.0.0.1'
|
21
|
+
},
|
22
|
+
|
23
|
+
:staging => {
|
24
|
+
:domains => [ 'staging.myapp.com' ],
|
25
|
+
:host => '127.0.0.1'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
require 'ubistrano'
|
data/gemspec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
GEM_NAME = 'ubistrano'
|
2
|
+
GEM_FILES = FileList['**/*'] - FileList['coverage', 'coverage/**/*', 'pkg', 'pkg/**/*']
|
3
|
+
GEM_SPEC = Gem::Specification.new do |s|
|
4
|
+
# == CONFIGURE ==
|
5
|
+
s.author = "Winton Welsh"
|
6
|
+
s.email = "mail@wintoni.us"
|
7
|
+
s.homepage = "http://github.com/winton/#{GEM_NAME}"
|
8
|
+
s.summary = "Provision and deploy to an Ubuntu/God/Apache/Passenger stack using Capistrano"
|
9
|
+
# == CONFIGURE ==
|
10
|
+
s.add_dependency('amazon-ec2', '=0.4.5')
|
11
|
+
s.executables << 'ubify'
|
12
|
+
s.extra_rdoc_files = [ "README.markdown" ]
|
13
|
+
s.files = GEM_FILES.to_a
|
14
|
+
s.has_rdoc = false
|
15
|
+
s.name = GEM_NAME
|
16
|
+
s.platform = Gem::Platform::RUBY
|
17
|
+
s.require_path = "lib"
|
18
|
+
s.version = "1.2.7"
|
19
|
+
end
|
data/lib/ubistrano.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
gem 'amazon-ec2', '=0.4.5'
|
3
|
+
require 'EC2'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
# Require helpers and recipes
|
7
|
+
Dir["#{File.dirname(__FILE__)}/ubistrano/*.rb"].each { |f| require f }
|
8
|
+
|
9
|
+
|
10
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
11
|
+
|
12
|
+
# Default capistrano/ubistrano values
|
13
|
+
set :ubistrano, {
|
14
|
+
:base_dir => '/var/www',
|
15
|
+
:deploy_via => :remote_cache,
|
16
|
+
:domains => [],
|
17
|
+
:mysql_root_password => '',
|
18
|
+
:mysql_app_password => '',
|
19
|
+
:platform => :rails,
|
20
|
+
:plugins => {},
|
21
|
+
:port => 22,
|
22
|
+
:repository_cache => 'git_cache',
|
23
|
+
:scm => :git,
|
24
|
+
:ssl => [],
|
25
|
+
:stage => :production,
|
26
|
+
:use_sudo => false,
|
27
|
+
:user => 'deploy',
|
28
|
+
:versions => {}
|
29
|
+
}.merge(ubistrano)
|
30
|
+
|
31
|
+
# Default plugins
|
32
|
+
ubistrano[:plugins] = {
|
33
|
+
:app_helpers => false,
|
34
|
+
:asset_packager => false,
|
35
|
+
:attachment_fu => false,
|
36
|
+
:rails_widget => false,
|
37
|
+
:thinking_sphinx => false
|
38
|
+
}.merge(ubistrano[:plugins])
|
39
|
+
|
40
|
+
# Default versions
|
41
|
+
ubistrano[:versions] = {
|
42
|
+
:git => '1.6.0.4',
|
43
|
+
:mysecureshell => '1.1',
|
44
|
+
:rails => '2.2.2',
|
45
|
+
:ruby => '1.8.7-p72',
|
46
|
+
:rubygems => '1.3.1',
|
47
|
+
:sphinx => '0.9.8.1'
|
48
|
+
}.merge(ubistrano[:versions])
|
49
|
+
|
50
|
+
# Merge ubistrano hash with capistrano
|
51
|
+
ubistrano.each do |key, value|
|
52
|
+
value.respond_to?(:keys) ?
|
53
|
+
value.each { |k, v| set "#{key}_#{k}".intern, v } :
|
54
|
+
set(key, value)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Default sources
|
58
|
+
set :sources, {
|
59
|
+
:git => "http://kernel.org/pub/software/scm/git/git-#{versions_git}.tar.gz",
|
60
|
+
:mysecureshell => "http://internap.dl.sourceforge.net/sourceforge/mysecureshell/MySecureShell-#{versions_mysecureshell}_source.tgz",
|
61
|
+
:mysqltuner => "http://mysqltuner.com/mysqltuner.pl",
|
62
|
+
:ruby => "ftp://ftp.ruby-lang.org/pub/ruby/#{versions_ruby.split('.')[0..1].join('.')}/ruby-#{versions_ruby}.tar.gz",
|
63
|
+
:rubygems => "http://rubyforge.org/frs/download.php/45905/rubygems-#{versions_rubygems}.tgz",
|
64
|
+
:sphinx => "http://www.sphinxsearch.com/downloads/sphinx-#{versions_sphinx}.tar.gz"
|
65
|
+
}.merge(fetch(:sources, {}))
|
66
|
+
|
67
|
+
# Events
|
68
|
+
on :before, 'setup_stage', :except => [ :staging, :testing ] # Executed before every task
|
69
|
+
after('deploy:update_code', 'rails:config:to_app' ) if platform == :rails
|
70
|
+
after('deploy:update_code', 'sinatra:config:to_app') if platform == :sinatra
|
71
|
+
after('deploy:update_code', 'rails:config:app_helpers') if plugins_app_helpers
|
72
|
+
after('deploy:update_code', 'rails:config:asset_packager') if plugins_asset_packager
|
73
|
+
after('deploy:update_code', 'rails:config:attachment_fu') if plugins_attachment_fu
|
74
|
+
after('deploy:update_code', 'rails:config:rails_widget') if plugins_rails_widget
|
75
|
+
after('deploy:update_code', 'rails:config:thinking_sphinx') if plugins_thinking_sphinx
|
76
|
+
|
77
|
+
# Other options
|
78
|
+
ssh_options[:paranoid] = false
|
79
|
+
|
80
|
+
# Reference ROOT when namespaces clash
|
81
|
+
ROOT = self
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
+
|
3
|
+
namespace :apache do
|
4
|
+
desc "Reload apache settings"
|
5
|
+
task :reload, :roles => :web do
|
6
|
+
sudo_puts "/etc/init.d/apache2 reload"
|
7
|
+
end
|
8
|
+
|
9
|
+
desc "Restart apache"
|
10
|
+
task :restart, :roles => :web do
|
11
|
+
sudo_puts "/etc/init.d/apache2 restart"
|
12
|
+
end
|
13
|
+
|
14
|
+
namespace :virtual_host do
|
15
|
+
desc "Create a new virtual host"
|
16
|
+
task :create, :roles => :web do
|
17
|
+
upload_from_erb "/etc/apache2/sites-available/#{application}_#{stage}", binding, :name => 'virtual_host', :folder => 'apache'
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Enable a virtual host"
|
21
|
+
task :enable, :roles => :web do
|
22
|
+
sudo_puts "a2ensite #{application}_#{stage}"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Destroy a virtual host"
|
26
|
+
task :destroy, :roles => :web do
|
27
|
+
apache.virtual_host.disable
|
28
|
+
sudo_each "rm /etc/apache2/sites-available/#{application}_#{stage}"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Disable a virtual host"
|
32
|
+
task :disable, :roles => :web do
|
33
|
+
sudo_puts "a2dissite #{application}_#{stage}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|