deploify 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +36 -0
- data/LICENSE.txt +22 -0
- data/README.md +2 -0
- data/Rakefile +1 -0
- data/deploify.gemspec +29 -0
- data/lib/deploify/capistrano_extensions.rb +189 -0
- data/lib/deploify/recipes/deploify.rb +171 -0
- data/lib/deploify/recipes/mongodb.rb +15 -0
- data/lib/deploify/recipes/monit.rb +84 -0
- data/lib/deploify/recipes/mysql.rb +85 -0
- data/lib/deploify/recipes/nginx.rb +122 -0
- data/lib/deploify/recipes/passenger.rb +130 -0
- data/lib/deploify/recipes/puma.rb +15 -0
- data/lib/deploify/recipes/rails.rb +221 -0
- data/lib/deploify/recipes/thin.rb +104 -0
- data/lib/deploify/recipes.rb +13 -0
- data/lib/deploify/templates/monit/monit.conf.erb +5 -0
- data/lib/deploify/templates/nginx/logrotate.conf.erb +12 -0
- data/lib/deploify/templates/nginx/vhost_http_force_ssl.conf.erb +79 -0
- data/lib/deploify/templates/nginx/vhost_http_only.conf.erb +66 -0
- data/lib/deploify/templates/nginx/vhost_http_with_ssl.conf.erb +131 -0
- data/lib/deploify/templates/passenger/logrotate.conf.erb +12 -0
- data/lib/deploify/templates/passenger/passengerctl-lib.erb +68 -0
- data/lib/deploify/templates/passenger/passengerctl.erb +10 -0
- data/lib/deploify/templates/thin/logrotate.conf.erb +0 -0
- data/lib/deploify/templates/thin/thinctl-lib.erb +84 -0
- data/lib/deploify/templates/thin/thinctl.erb +9 -0
- data/lib/deploify/version.rb +12 -0
- data/lib/deploify.rb +7 -0
- data/lib/plugins/all.rb +20 -0
- data/lib/plugins/apt.rb +94 -0
- data/lib/plugins/std.rb +203 -0
- metadata +196 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
# Copyright 2006-2008 by Mike Bailey. All rights reserved.
|
2
|
+
# Copyright 2012 by Richard Riman. All rights reserved.
|
3
|
+
|
4
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
5
|
+
|
6
|
+
set :nginx_vhost_dir, "/etc/nginx/sites-available"
|
7
|
+
set :nginx_enabled_vhost_dir, "/etc/nginx/sites-enabled"
|
8
|
+
set :nginx_client_max_body_size, "100M"
|
9
|
+
set :nginx_vhost_type, :http_only
|
10
|
+
set :nginx_vhost_listen_ip, "0.0.0.0"
|
11
|
+
set :nginx_upstream_servers, []
|
12
|
+
# secured sites stuff
|
13
|
+
set :nginx_secured_site, false
|
14
|
+
set :nginx_secure_user, "developer"
|
15
|
+
set(:nginx_secure_password) { Capistrano::CLI.password_prompt "Enter password for securing this site:" }
|
16
|
+
|
17
|
+
set :ssl_certs_source_dir, "config/ssl"
|
18
|
+
|
19
|
+
namespace :deploify do
|
20
|
+
|
21
|
+
namespace :nginx do
|
22
|
+
|
23
|
+
CHOICES_VHOST_TYPES = [:http_only, :http_with_ssl, :http_force_ssl]
|
24
|
+
|
25
|
+
PROJECT_CONFIG_FILES[:nginx] = [
|
26
|
+
{ :template => "logrotate.conf.erb",
|
27
|
+
:path => "logrotate.conf",
|
28
|
+
:mode => 0640,
|
29
|
+
:owner => "root:root" }
|
30
|
+
]
|
31
|
+
|
32
|
+
def project_config_files
|
33
|
+
PROJECT_CONFIG_FILES[:nginx] + [{
|
34
|
+
:template => "vhost_#{nginx_vhost_type}.conf.erb",
|
35
|
+
:path => "vhost.conf",
|
36
|
+
:mode => 0640,
|
37
|
+
:owner => "root:root"
|
38
|
+
}]
|
39
|
+
end
|
40
|
+
|
41
|
+
desc <<-DESC
|
42
|
+
Generate nginx config from one of the templates depending on situation.
|
43
|
+
Note that this does not push the config to the server, it merely generates
|
44
|
+
required configuration files. These should be kept under source control.
|
45
|
+
The can be pushed to the server with the :config task.
|
46
|
+
DESC
|
47
|
+
task :config_gen_project do
|
48
|
+
set :nginx_upstream_name, Digest::SHA1.hexdigest(application)
|
49
|
+
if nginx_upstream_servers.empty?
|
50
|
+
if app_server_type.eql?(:passenger)
|
51
|
+
set :nginx_upstream_servers, %W(unix:#{shared_path}/pids/#{app_server_type}.sock)
|
52
|
+
elsif app_server_type.eql?(:thin)
|
53
|
+
upstreams = []
|
54
|
+
set :nginx_upstream_servers,
|
55
|
+
(0..fetch(:thin_servers) - 1).collect { |idx| "unix:#{shared_path}/pids/#{app_server_type}.#{idx}.sock" }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
project_config_files.each do |file|
|
59
|
+
_deploify.render_template(:nginx, file)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Push nginx config files to server, enable (symlink) vhost and logrotate"
|
64
|
+
task :config_project, :roles => :web do
|
65
|
+
_deploify.push_configs(:nginx, project_config_files)
|
66
|
+
if [:http_with_ssl, :http_force_ssl].include?(nginx_vhost_type)
|
67
|
+
# SSL is demanded, push certificates
|
68
|
+
target_path = "#{deploy_to}/nginx/#{rails_env}"
|
69
|
+
std.su_put(File.read("#{ssl_certs_source_dir}/#{rails_env}.crt"), "#{target_path}.crt", "/tmp", :mode => 0600)
|
70
|
+
std.su_put(File.read("#{ssl_certs_source_dir}/#{rails_env}.key"), "#{target_path}.key", "/tmp", :mode => 0600)
|
71
|
+
end
|
72
|
+
top.deploify.nginx.generate_htaccess_file if nginx_secured_site
|
73
|
+
end
|
74
|
+
|
75
|
+
desc "Generate .htaccess file for site securing"
|
76
|
+
task :generate_htaccess_file, :roles => :web do
|
77
|
+
pwd = `openssl passwd -apr1 #{nginx_secure_password}`
|
78
|
+
std.su_put("#{nginx_secure_user}:#{pwd}", "#{deploy_to}/nginx/.htaccess", "/tmp", :mode => 0644)
|
79
|
+
end
|
80
|
+
|
81
|
+
desc "Activate nginx application vhost and logrotate"
|
82
|
+
task :activate, :roles => :web do
|
83
|
+
# logrotate
|
84
|
+
run "#{try_sudo} ln -sf #{deploy_to}/nginx/logrotate.conf /etc/logrotate.d/nginx-#{application}"
|
85
|
+
# nginx
|
86
|
+
run "#{try_sudo} ln -sf #{deploy_to}/nginx/vhost.conf #{nginx_vhost_dir}/#{application}"
|
87
|
+
run "#{try_sudo} ln -sf #{nginx_vhost_dir}/#{application} #{nginx_enabled_vhost_dir}/#{application}"
|
88
|
+
end
|
89
|
+
|
90
|
+
desc "Start Nginx"
|
91
|
+
task :start, :roles => :web do
|
92
|
+
# Nginx returns error code if you try to start it when it's already running.
|
93
|
+
# We don't want this to kill Capistrano.
|
94
|
+
send(run_method, "service nginx start; exit 0")
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Stop Nginx"
|
98
|
+
task :stop, :roles => :web do
|
99
|
+
# Nginx returns error code if you try to stop when it's not running.
|
100
|
+
# We don't want this to kill Capistrano.
|
101
|
+
send(run_method, "service nginx stop; exit 0")
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Restart Nginx"
|
105
|
+
task :restart, :roles => :web do
|
106
|
+
# Nginx returns error code if you try to reload when it's not running.
|
107
|
+
# We don't want this to kill Capistrano.
|
108
|
+
send(run_method, "service nginx restart; exit 0")
|
109
|
+
end
|
110
|
+
|
111
|
+
desc "Reload Nginx"
|
112
|
+
task :reload, :roles => :web do
|
113
|
+
# Nginx returns error code if you try to reload when it's not running.
|
114
|
+
# We don't want this to kill Capistrano.
|
115
|
+
send(run_method, "service nginx reload; exit 0")
|
116
|
+
end
|
117
|
+
|
118
|
+
end # namespace :nginx
|
119
|
+
|
120
|
+
end # namespace :deploify
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# Copyright 2006-2008 by Mike Bailey. All rights reserved.
|
2
|
+
# Copyright 2012 by Richard Riman. All rights reserved.
|
3
|
+
|
4
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
5
|
+
|
6
|
+
set :passenger_mode, :standalone
|
7
|
+
set :passenger_max_pool_size, 2 # in standalone mode means max. instances, but as nginx/apache module
|
8
|
+
# this means size of the entire application pool
|
9
|
+
set :passenger_min_instances, 1 # specifies minimum instances for application
|
10
|
+
|
11
|
+
set :passenger_port, nil # standalone mode only: application port,
|
12
|
+
# if not specified, passenger is started as unix socket
|
13
|
+
|
14
|
+
set :passenger_spawn_method, "smart-lv2" # smart-lv2 | smart | conservative
|
15
|
+
|
16
|
+
# TODO: passenger as a nginx/apache module
|
17
|
+
# TODO: passenger installation on server
|
18
|
+
|
19
|
+
namespace :deploify do
|
20
|
+
|
21
|
+
namespace :passenger do
|
22
|
+
|
23
|
+
SYSTEM_CONFIG_FILES[:passenger] = [
|
24
|
+
{ :template => "passengerctl-lib.erb",
|
25
|
+
:path => "/usr/local/lib/passengerctl",
|
26
|
+
:mode => 0644,
|
27
|
+
:owner => "root:root" }
|
28
|
+
]
|
29
|
+
|
30
|
+
PROJECT_CONFIG_FILES[:passenger] = [
|
31
|
+
{ :template => "passengerctl.erb",
|
32
|
+
:path => "passengerctl",
|
33
|
+
:mode => 0754,
|
34
|
+
:owner => "root:root" },
|
35
|
+
|
36
|
+
{ :template => "logrotate.conf.erb",
|
37
|
+
:path => "logrotate.conf",
|
38
|
+
:mode => 0644,
|
39
|
+
:owner => "root:root" }
|
40
|
+
]
|
41
|
+
|
42
|
+
desc "Install Passenger"
|
43
|
+
task :install, :roles => :app do
|
44
|
+
# TODO: install passenger things, there's only configuration part yet
|
45
|
+
# run "rvm gemset use global && gem install passenger --no-ri --no-rdoc"
|
46
|
+
# TODO: how to compile standalone passenger?
|
47
|
+
config_gen_system
|
48
|
+
config_system
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Generate Passenger configs (system & project level)."
|
52
|
+
task :config_gen do
|
53
|
+
# config_gen_system
|
54
|
+
config_gen_project
|
55
|
+
end
|
56
|
+
|
57
|
+
desc "Generate Passenger configs (system level) from template."
|
58
|
+
task :config_gen_system do
|
59
|
+
SYSTEM_CONFIG_FILES[:passenger].each do |file|
|
60
|
+
_deploify.render_template(:passenger, file)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc "Generate Passenger configs (project level) from template."
|
65
|
+
task :config_gen_project do
|
66
|
+
PROJECT_CONFIG_FILES[:passenger].each do |file|
|
67
|
+
_deploify.render_template(:passenger, file)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Push Passenger config files (system & project level) to server"
|
72
|
+
task :config, :roles => :app do
|
73
|
+
# config_system
|
74
|
+
config_project
|
75
|
+
end
|
76
|
+
|
77
|
+
desc "Push Passenger configs (system level) to server"
|
78
|
+
task :config_system, :roles => :app do
|
79
|
+
# TODO: passenger as nginx/apache module
|
80
|
+
_deploify.push_configs(:passenger, SYSTEM_CONFIG_FILES[:passenger])
|
81
|
+
end
|
82
|
+
|
83
|
+
desc "Push Passenger configs (project level) to server"
|
84
|
+
task :config_project, :roles => :app do
|
85
|
+
_deploify.push_configs(:passenger, PROJECT_CONFIG_FILES[:passenger])
|
86
|
+
# TODO: passenger as nginx/apache module
|
87
|
+
symlink_logrotate_config
|
88
|
+
end
|
89
|
+
|
90
|
+
task :activate, :roles => :app do
|
91
|
+
# activate_system
|
92
|
+
activate_project
|
93
|
+
end
|
94
|
+
|
95
|
+
task :activate_project, :roles => :app do
|
96
|
+
# TODO: passenger as nginx/apache module
|
97
|
+
case passenger_mode
|
98
|
+
when :standalone
|
99
|
+
symlink_and_activate_passengerctl
|
100
|
+
top.deploify.app.restart
|
101
|
+
end
|
102
|
+
top.deploify.web.reload
|
103
|
+
end
|
104
|
+
|
105
|
+
task :symlink_and_activate_passengerctl, :roles => :app do
|
106
|
+
run "#{try_sudo} ln -sf #{deploy_to}/passenger/passengerctl /etc/init.d/passenger-#{application}"
|
107
|
+
run "#{try_sudo} update-rc.d passenger-#{application} defaults"
|
108
|
+
end
|
109
|
+
|
110
|
+
task :symlink_logrotate_config, :roles => :app do
|
111
|
+
run "#{try_sudo} ln -sf #{deploy_to}/passenger/logrotate.conf /etc/logrotate.d/passenger-#{application}"
|
112
|
+
end
|
113
|
+
|
114
|
+
# Passenger runs Rails as the owner of this file.
|
115
|
+
task :set_owner_of_environment_rb, :roles => :app do
|
116
|
+
unless passenger_mode.eql?(:standalone)
|
117
|
+
run "#{sudo} chown #{app_user} #{current_path}/config/environment.rb"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
desc "Restart Application"
|
122
|
+
task :restart, :roles => :app do
|
123
|
+
run "test -d #{current_path} && #{sudo} service passenger-#{application} restart; exit 0"
|
124
|
+
end
|
125
|
+
|
126
|
+
end # namespace :passenger
|
127
|
+
|
128
|
+
end # namespace :deploify
|
129
|
+
|
130
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
# Copyright 2006-2008 by Mike Bailey. All rights reserved.
|
2
|
+
# Copyright 2012 by Richard Riman. All rights reserved.
|
3
|
+
|
4
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
5
|
+
|
6
|
+
set(:deploy_to) { "/var/www/" + application }
|
7
|
+
|
8
|
+
set :app_user_prefix, "app_"
|
9
|
+
set(:app_user) { app_user_prefix + application }
|
10
|
+
set :app_group_prefix, "app_"
|
11
|
+
set(:app_group) { app_group_prefix + application }
|
12
|
+
set(:app_user_homedir) { deploy_to }
|
13
|
+
set :database_yml_in_scm, false
|
14
|
+
set :app_symlinks, nil
|
15
|
+
set :rails_env, "production"
|
16
|
+
set :shared_dirs, [] # Array of directories that should be created under shared/
|
17
|
+
# and linked to in the project
|
18
|
+
|
19
|
+
# hook into the default capistrano deploy tasks
|
20
|
+
before "deploy:setup", :except => { :no_release => true } do
|
21
|
+
top.deploify.rails.setup_perms
|
22
|
+
top.deploify.rails.setup_paths
|
23
|
+
top.deploify.rails.setup_shared_dirs
|
24
|
+
end
|
25
|
+
|
26
|
+
after "deploy:setup", :except => { :no_release => true } do
|
27
|
+
top.deploify.rails.create_config_dir
|
28
|
+
top.deploify.rails.config_gen
|
29
|
+
top.deploify.rails.config
|
30
|
+
top.deploify.rails.set_perms_and_make_writable_by_app
|
31
|
+
|
32
|
+
top.deploify.rails.activate_services
|
33
|
+
top.deploify.web.reload
|
34
|
+
top.deploify.rails.setup_database
|
35
|
+
end
|
36
|
+
|
37
|
+
after "deploy:update_code", :roles => :app do
|
38
|
+
top.deploify.rails.symlink_database_yml unless database_yml_in_scm
|
39
|
+
end
|
40
|
+
|
41
|
+
after "deploy:create_symlink", :roles => :app do
|
42
|
+
top.deploify.rails.symlink_shared_dirs
|
43
|
+
top.deploify.rails.set_perms_on_shared_and_release
|
44
|
+
top.deploify.rails.set_perms_and_make_writable_by_app
|
45
|
+
top.deploify.passenger.set_owner_of_environment_rb if app_server_type.to_s.eql?("passenger")
|
46
|
+
end
|
47
|
+
|
48
|
+
after :deploy, "deploy:cleanup"
|
49
|
+
|
50
|
+
# If database.yml is not kept in scm and it is present in local
|
51
|
+
# config dir then push it out to server.
|
52
|
+
before "deploify:rails:symlink_database_yml", :roles => :app do
|
53
|
+
top.deploify.rails.push_database_yml unless database_yml_in_scm
|
54
|
+
end
|
55
|
+
|
56
|
+
namespace :deploify do
|
57
|
+
|
58
|
+
namespace :rails do
|
59
|
+
|
60
|
+
desc "Create deployment group and add current user to it, create user and group for application to run as"
|
61
|
+
task :setup_perms, :roles => [:app, :web] do
|
62
|
+
_deploify.groupadd(group)
|
63
|
+
_deploify.add_user_to_group(user, group)
|
64
|
+
_deploify.groupadd(app_group)
|
65
|
+
_deploify.add_user_to_group(user, app_group)
|
66
|
+
# # we've just added ourself to a group - need to teardown connection
|
67
|
+
# # so that next command uses new session where we belong in group
|
68
|
+
_deploify.teardown_connections
|
69
|
+
# create user and group for application to run as
|
70
|
+
_deploify.useradd(app_user, :group => app_group, :homedir => false)
|
71
|
+
# Set the primary group for the user the application runs as (in case
|
72
|
+
# user already existed when previous command was run)
|
73
|
+
sudo "usermod --gid #{app_group} --home #{app_user_homedir} #{app_user}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# setup extra paths required for deployment
|
77
|
+
task :setup_paths, :roles => [:app, :web] do
|
78
|
+
_deploify.mkdir(deploy_to, :mode => 0775, :group => group, :via => :sudo)
|
79
|
+
_deploify.mkdir(shared_path, :mode => 0775, :group => group, :via => :sudo)
|
80
|
+
_deploify.mkdir("#{deploy_to}/releases", :mode => 0755, :group => group, :via => :sudo)
|
81
|
+
end
|
82
|
+
|
83
|
+
# create directories by the list of shared files and dirs
|
84
|
+
# TODO: check, how this works with a files
|
85
|
+
desc "Setup shared dirs"
|
86
|
+
task :setup_shared_dirs, :roles => [:app, :web] do
|
87
|
+
if shared_dirs.any?
|
88
|
+
shared_dirs.each do |dir|
|
89
|
+
_deploify.mkdir(File.join(shared_path, dir), :via => :sudo)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
task :create_config_dir, :roles => :app do
|
95
|
+
_deploify.mkdir(File.join(shared_path, "config"), :group => group, :mode => 0775, :via => :sudo)
|
96
|
+
end
|
97
|
+
|
98
|
+
desc "Generate config files for rails app."
|
99
|
+
task :config_gen do
|
100
|
+
top.deploify.web.config_gen_project
|
101
|
+
top.deploify.app.config_gen_project
|
102
|
+
top.deploify.monit.config_gen_project if use_monit
|
103
|
+
end
|
104
|
+
|
105
|
+
desc "Push out config files for rails app."
|
106
|
+
task :config do
|
107
|
+
top.deploify.web.config_project
|
108
|
+
top.deploify.app.config_project
|
109
|
+
top.deploify.monit.config_project if use_monit
|
110
|
+
end
|
111
|
+
|
112
|
+
desc "Activate web, app and monit (if used)"
|
113
|
+
task :activate_services do
|
114
|
+
top.deploify.web.activate
|
115
|
+
top.deploify.app.activate
|
116
|
+
top.deploify.monit.activate if use_monit
|
117
|
+
end
|
118
|
+
|
119
|
+
task :setup_database, :roles => :db do
|
120
|
+
unless roles[:db].servers.empty? # Some apps don't use database!
|
121
|
+
top.deploify.db.create_database
|
122
|
+
top.deploify.db.grant_user_access_to_database
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
desc "Symlink shared dirs"
|
127
|
+
task :symlink_shared_dirs, :roles => :app do
|
128
|
+
if shared_dirs
|
129
|
+
shared_dirs.each do |dir|
|
130
|
+
path = File.split(dir)[0]
|
131
|
+
if path != '.'
|
132
|
+
_deploify.mkdir(File.join(current_path, path))
|
133
|
+
end
|
134
|
+
run "#{sudo} test -d #{current_path}/#{dir} && mv #{current_path}/#{dir} #{current_path}/#{dir}.moved_by_deploify; exit 0"
|
135
|
+
run "ln -nfs #{shared_path}/#{dir} #{current_path}/#{dir}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
task :set_perms_on_shared_and_release, :roles => :app do
|
141
|
+
run "#{sudo} chgrp -R #{app_group} #{shared_path} #{release_path}"
|
142
|
+
run "#{sudo} chown -Rf #{app_user}:#{app_group} #{release_path}/tmp/cache/assets; exit 0"
|
143
|
+
run "#{sudo} chmod -R g+w #{shared_path} #{release_path}"
|
144
|
+
end
|
145
|
+
|
146
|
+
desc "set group ownership and permissions on dirs app server needs to write to"
|
147
|
+
task :set_perms_and_make_writable_by_app, :roles => :app do
|
148
|
+
dirs = %W(
|
149
|
+
#{shared_path}/log
|
150
|
+
#{shared_path}/pids
|
151
|
+
#{shared_path}/uploads
|
152
|
+
#{current_path}/tmp
|
153
|
+
#{current_path}/public
|
154
|
+
).join(' ')
|
155
|
+
run "#{sudo} chgrp -Rf #{app_group} #{dirs}; exit 0"
|
156
|
+
run "#{sudo} chmod -Rf g+w #{dirs}; exit 0"
|
157
|
+
end
|
158
|
+
|
159
|
+
# database things
|
160
|
+
|
161
|
+
set :db_host, "localhost"
|
162
|
+
set :db_socket, "/var/run/mysqld/mysqld.sock"
|
163
|
+
set(:db_adapter) do
|
164
|
+
Capistrano::CLI.ui.ask("Enter database adapter") do |q|
|
165
|
+
q.default = "mysql2"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
set(:db_user) { application[0..15] }
|
169
|
+
set(:db_password) { Capistrano::CLI.ui.ask "Enter database password" }
|
170
|
+
set(:db_name) { application }
|
171
|
+
set :db_encoding, "utf8"
|
172
|
+
|
173
|
+
desc "Link in the production database.yml"
|
174
|
+
task :symlink_database_yml, :roles => :app do
|
175
|
+
run "#{sudo} ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml"
|
176
|
+
end
|
177
|
+
|
178
|
+
desc "Copy database.yml to shared/config/database.yml. Useful if not kept in scm."
|
179
|
+
task :push_database_yml, :roles => :app do
|
180
|
+
database_yml = ERB.new <<-EOF
|
181
|
+
#{rails_env}:
|
182
|
+
adapter: #{db_adapter}
|
183
|
+
username: #{db_user}
|
184
|
+
password: #{db_password}
|
185
|
+
database: #{db_name}
|
186
|
+
encoding: #{db_encoding}
|
187
|
+
host: #{db_host}
|
188
|
+
socket: #{db_socket}
|
189
|
+
EOF
|
190
|
+
std.su_put(database_yml.result, "#{shared_path}/config/database.yml", "/tmp/")
|
191
|
+
end
|
192
|
+
|
193
|
+
end # namespace :rails
|
194
|
+
|
195
|
+
namespace :database do
|
196
|
+
|
197
|
+
desc "Create database"
|
198
|
+
task :create, :roles => :app do
|
199
|
+
run "cd #{deploy_to}/current && rake db:create RAILS_ENV=#{rails_env}"
|
200
|
+
end
|
201
|
+
|
202
|
+
desc "Run database migrations"
|
203
|
+
task :migrate, :roles => :app do
|
204
|
+
run "cd #{deploy_to}/current && rake db:migrate RAILS_ENV=#{rails_env}"
|
205
|
+
end
|
206
|
+
|
207
|
+
desc "Run database migrations"
|
208
|
+
task :schema_load, :roles => :app do
|
209
|
+
run "cd #{deploy_to}/current && rake db:schema:load RAILS_ENV=#{rails_env}"
|
210
|
+
end
|
211
|
+
|
212
|
+
desc "Roll database back to previous migration"
|
213
|
+
task :rollback, :roles => :app do
|
214
|
+
run "cd #{deploy_to}/current && rake db:rollback RAILS_ENV=#{rails_env}"
|
215
|
+
end
|
216
|
+
|
217
|
+
end # namespace :database
|
218
|
+
|
219
|
+
end # namespace :deploify
|
220
|
+
|
221
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# Copyright 2012 by Richard Riman. All rights reserved.
|
2
|
+
|
3
|
+
Capistrano::Configuration.instance(:must_exist).load do
|
4
|
+
|
5
|
+
set :thin_applications_dir, "/var/www"
|
6
|
+
set :thin_servers, 2
|
7
|
+
set :thin_port, nil # port is optional, if not specified, thin is started as unix socket
|
8
|
+
|
9
|
+
namespace :deploify do
|
10
|
+
|
11
|
+
namespace :thin do
|
12
|
+
|
13
|
+
SYSTEM_CONFIG_FILES[:thin] = [
|
14
|
+
{ :template => "thinctl-lib.erb",
|
15
|
+
:path => "/usr/local/lib/thinctl",
|
16
|
+
:mode => 0644,
|
17
|
+
:owner => "root:root" }
|
18
|
+
]
|
19
|
+
|
20
|
+
PROJECT_CONFIG_FILES[:thin] = [
|
21
|
+
{ :template => "thinctl.erb",
|
22
|
+
:path => "thinctl",
|
23
|
+
:mode => 0754,
|
24
|
+
:owner => "root:root" },
|
25
|
+
|
26
|
+
{ :template => "logrotate.conf.erb",
|
27
|
+
:path => "logrotate.conf",
|
28
|
+
:mode => 0644,
|
29
|
+
:owner => "root:root" }
|
30
|
+
]
|
31
|
+
|
32
|
+
desc "Install Thin"
|
33
|
+
task :install, :roles => :app do
|
34
|
+
run "rvm gemset use global && gem install thin --no-ri --no-rdoc"
|
35
|
+
config_gen_system
|
36
|
+
config_system
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Generate Thin configs (system & project level)."
|
40
|
+
task :config_gen do
|
41
|
+
# config_gen_system
|
42
|
+
config_gen_project
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Generate Thin configs (system level) from template."
|
46
|
+
task :config_gen_system do
|
47
|
+
SYSTEM_CONFIG_FILES[:thin].each do |file|
|
48
|
+
_deploify.render_template(:thin, file)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Generate Thin configs (project level) from template."
|
53
|
+
task :config_gen_project do
|
54
|
+
PROJECT_CONFIG_FILES[:thin].each do |file|
|
55
|
+
_deploify.render_template(:thin, file)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
desc "Push Thin config files (system & project level) to server"
|
60
|
+
task :config, :roles => :app do
|
61
|
+
# config_system
|
62
|
+
config_project
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Push Thin configs (system level) to server"
|
66
|
+
task :config_system, :roles => :app do
|
67
|
+
_deploify.push_configs(:thin, SYSTEM_CONFIG_FILES[:thin])
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "Push Thin configs (project level) to server"
|
71
|
+
task :config_project, :roles => :app do
|
72
|
+
_deploify.push_configs(:thin, PROJECT_CONFIG_FILES[:thin])
|
73
|
+
symlink_logrotate_config
|
74
|
+
end
|
75
|
+
|
76
|
+
task :activate, :roles => :app do
|
77
|
+
activate_project
|
78
|
+
end
|
79
|
+
|
80
|
+
task :activate_project, :roles => :app do
|
81
|
+
symlink_and_activate_thinctl
|
82
|
+
top.deploify.app.restart
|
83
|
+
top.deploify.web.reload
|
84
|
+
end
|
85
|
+
|
86
|
+
task :symlink_and_activate_thinctl, :roles => :app do
|
87
|
+
run "#{try_sudo} ln -sf #{deploy_to}/thin/thinctl /etc/init.d/thin-#{application}"
|
88
|
+
run "#{try_sudo} update-rc.d thin-#{application} defaults"
|
89
|
+
end
|
90
|
+
|
91
|
+
task :symlink_logrotate_config, :roles => :app do
|
92
|
+
run "#{try_sudo} ln -sf #{deploy_to}/thin/logrotate.conf /etc/logrotate.d/thin-#{application}"
|
93
|
+
end
|
94
|
+
|
95
|
+
desc "Restart Application"
|
96
|
+
task :restart, :roles => :app do
|
97
|
+
run "test -d #{current_path} && #{sudo} service thin-#{application} restart; exit 0"
|
98
|
+
end
|
99
|
+
|
100
|
+
end # namespace :thin
|
101
|
+
|
102
|
+
end # namespace :deploify
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
unless Capistrano::Configuration.respond_to?(:instance)
|
2
|
+
abort "Deploify requires Capistrano ~> 2.13.3"
|
3
|
+
end
|
4
|
+
|
5
|
+
require "#{File.dirname(__FILE__)}/recipes/deploify"
|
6
|
+
# require "#{File.dirname(__FILE__)}/recipes/mongodb"
|
7
|
+
require "#{File.dirname(__FILE__)}/recipes/monit"
|
8
|
+
require "#{File.dirname(__FILE__)}/recipes/mysql"
|
9
|
+
require "#{File.dirname(__FILE__)}/recipes/nginx"
|
10
|
+
require "#{File.dirname(__FILE__)}/recipes/passenger"
|
11
|
+
# require "#{File.dirname(__FILE__)}/recipes/puma"
|
12
|
+
require "#{File.dirname(__FILE__)}/recipes/rails"
|
13
|
+
require "#{File.dirname(__FILE__)}/recipes/thin"
|
@@ -0,0 +1,5 @@
|
|
1
|
+
check process <%= app_server_type %>-<%= application %> with pidfile <%= shared_path %>/pids/<%= app_server_type %>.pid
|
2
|
+
start program = "/usr/sbin/service <%= app_server_type %>-<%= application %> start" with timeout <%= monit_timeout_interval %> seconds
|
3
|
+
stop program = "/usr/sbin/service <%= app_server_type %>-<%= application %> stop"
|
4
|
+
if 5 restarts within 5 cycles then timeout
|
5
|
+
group <%= app_server_type %>
|