-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcapistrano.rb
227 lines (205 loc) · 6.44 KB
/
capistrano.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
APPLICATION ||= File.split(root).last
capify!
file 'config/deploy.rb', <<-CODE
require 'fileutils'
require 'capistrano/ext/multistage'
set :application, "#{APPLICATION}"
set :domain, "#{SERVER_DOMAIN}"
set :staging_domain, "#{STAGING_DOMAIN}"
set :real_host, "#{REAL_HOST}"
set :git_server, "#{GIT_SERVER}"
set :git_folder, "#{GIT_CAPISTRANO_FOLDER}"
set :repository, "#{GIT_CAPISTRANO_REPO}"
set :deploy_to, "#{DEPLOY_PATH}"
set :template_dir, "#{SERVER_TEMPLATES_PATH}" # where you have database.yml, mailer.yml, nginx-production.conf.erb, nginx-staging.conf.erb
set :nginx_conf, "#{SERVER_NGINX_APPS_PATH}/\#{domain}.conf"
set :god_path, "#{GOD_PATH}"
set :user, "#{SERVER_USER}"
set :scm, :git
set :branch, "master"
set :stages, %w(staging production)
set :default_stage, "staging"
set :use_sudo, false
default_run_options[:pty] = true
server real_host, :app, :web, :db, :primary => true
def remote_file_exists?(full_path)
'true' == capture("if [ -e \#{full_path} ]; then echo 'true'; fi").strip
end
def read_remote(location)
tmp = "~tmp-\#{rand(9999999)}"
get(location, tmp)
file = File.read(tmp)
FileUtils.rm(tmp)
return file
end
def sudo_put(data, target)
tmp = "\#{shared_path}/~tmp-\#{rand(9999999)}"
put data, tmp
on_rollback { run "rm \#{tmp}" }
sudo "cp -f \#{tmp} \#{target} && rm \#{tmp}"
end
def rake(command, options={})
sudo_option = options[:sudo] ? "sudo" : ""
ignore_output = options[:ignore_output] ? ";true" : ""
path = options[:path] || release_path
run "cd \#{path} && \#{sudo_option} rake RAILS_ENV=\#{rails_env} \#{command}\#{ignore_output}"
end
def god(command)
sudo "/opt/ruby/bin/god \#{command} \#{application}-\#{rails_env}"
end
def nxconf_path
rails_env=='staging' ? nginx_conf.gsub(domain, staging_domain) : nginx_conf
end
def current_domain
rails_env=='staging' ? staging_domain : domain
end
namespace :deploy do
desc "Start the server"
task :start do
sudo "nxenable \#{current_domain}"
god :start
end
desc "Stop the server"
task :stop do
sudo "nxdisable \#{current_domain}"
god :stop
end
desc "Restart the server"
task :restart, :roles => :app, :except => { :no_release => true } do
run "\#{try_sudo} touch \#{File.join(current_path,'tmp','restart.txt')}"
god :restart
end
desc "Completely remove deployment from the server"
task :destroy do
stop
sudo "rm -f \#{nxconf_path}"
update_code unless remote_file_exists?(current_path)
rake "db:drop", :path => current_path, :ignore_output => true
run "rm -rf \#{deploy_to}"
god :stop
god :remove
end
desc "Update, load schema, and start the server"
task :cold do # Overriding the default deploy:cold
update
load_schema # My own step, replacing migrations.
start
end
task :load_schema, :roles => :app do
rake "db:create"
# if remote_file_exists?(release_path + '/db/schema.rb')
# rake "db:schema:load"
# else
rake "db:migrate"
# end
end
task :verify_setup do
unless remote_file_exists?(deploy_to)
setup
set :new_setup, true
else
set :new_setup, false
end
end
task :finish_new_deploy do
if new_setup
load_schema
start
sudo "\#{god_path} load \#{current_path}/config/god/*.rb"
end
end
task :touch_logs do
run "touch \#{shared_path}/log/#\{rails_env}.log"
run "touch \#{shared_path}/log/nginx-access.log"
run "touch \#{shared_path}/log/nginx-error.log"
run "touch \#{shared_path}/log/god.log"
end
task :setup_shared, :except => { :no_release => true } do
run "mkdir -p \#{shared_path}/config"
run "cp \#{template_dir}/mailer.yml \#{shared_path}/config"
end
task :symlink_shared, :except => { :no_release => true } do
run "ln -nfs \#{shared_path}/config/mailer.yml \#{release_path}/config/mailer.yml"
end
end
before "deploy:update", "deploy:verify_setup"
after "deploy:update", "deploy:finish_new_deploy"
after "deploy:setup", "deploy:touch_logs"
after "deploy:setup", "deploy:setup_shared"
after "deploy:finalize_update", "deploy:symlink_shared"
namespace :nginx do
desc "Creates the Nginx site file"
task :create_site do
template = read_remote("\#{template_dir}/nginx-\#{rails_env}.conf.erb")
sudo_put(ERB.new(template).result(binding), "\#{shared_path}/config/nginx.conf")
sudo "ln -nfs \#{shared_path}/config/nginx.conf \#{nxconf_path}"
end
end
after "deploy:setup", "nginx:create_site"
namespace :db do
task :setup, :except => { :no_release => true } do
template = read_remote(template_dir + '/database.yml.erb')
put ERB.new(template).result(binding), "\#{shared_path}/config/database.yml"
end
task :symlink, :except => { :no_release => true } do
run "ln -nfs \#{shared_path}/config/database.yml \#{release_path}/config/database.yml"
end
task :create do
rake "db:create db:migrate db:seed", :path => current_path
end
task :migrate do
rake "db:migrate", :path => current_path
end
task :seed do
rake "db:seed", :path => current_path
end
task :reset do
rake "db:drop db:create db:migrate db:seed", :path => current_path
end
end
after "deploy:setup_shared", "db:setup" unless fetch(:skip_db_setup, false)
after "deploy:finalize_update", "db:symlink"
namespace :gems do
desc "Installs gems"
task :install, :roles => :app do
rake "gems:install", :sudo => true
end
end
after "db:symlink", "gems:install"
namespace :util do
task :remove_mkmf do
`rm -rf mkmf.log`
end
end
after "deploy:update_code", "util:remove_mkmf"
namespace :git do
desc "Creates the git repository"
task :create do
`ssh \#{git_server} "mkdir \#{git_folder} && cd \#{git_folder} && git init --bare"`
`git push origin master`
end
desc "Deletes the git repository"
task :destroy do
`ssh \#{git_server} "rm -rf \#{git_folder}"`
end
task :submodules do
run "cd \#{release_path}; git submodule update --init"
end
end
before "gems:install", "git:submodules"
before "deploy:setup", "git:create"
CODE
file 'config/deploy/production.rb', <<-CODE
set :rails_env, "production"
CODE
file 'config/deploy/staging.rb', <<-CODE
set :deploy_to, "\#{deploy_to}-staging"
set :rails_env, "staging"
CODE
run "cp config/environments/production.rb config/environments/staging.rb"
gsub_file 'config/environments/staging.rb', "# config.log_level = :debug", <<-CODE
config.log_level = :debug
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
CODE
gsub_file 'config/environments/staging.rb', SERVER_DOMAIN, STAGING_DOMAIN