This repository has been archived by the owner on Oct 26, 2018. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
uberspace.rb
258 lines (237 loc) · 8.24 KB
/
uberspace.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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# encoding: utf-8
#
# This recipe provides setup and maintenance tasks for Rails apps hosted on
# [Uberspace](http://uberspace.de). Most of this recipe has been inspired by
# [uberspacify](https://github.com/yeah/uberspacify), a gem which provides
# this functionality for Capistrano.
#
# Tasks:
#
# - vlad:uberspace:setup # all-in-one setup task
# - vlad:uberspace:setup_svscan
# - vlad:uberspace:setup_service
# - vlad:uberspace:setup_domain_symlink
# - vlad:uberspace:create_database_yml
# - vlad:uberspace:create_reverse_proxy_htaccess
# - vlad:uberspace:reload_service
# - vlad:uberspace:remove_service
# - vlad:start_app
# - vlad:restart_app
# - vlad:stop_app
#
# Hint: uberspace doesn't allow concurrent ssh connections.
# You will need to use shared ssh connections, otherwise vlad remote tasks won't work as expected.
# Add the followiwng lines at the top of your ~/.ssh/config to enable ssh shared connections:
# ControlMaster auto
# ControlPath /tmp/ssh_mux_%h_%p_%r
# ControlPersist 15m
#
# Example Configuration:
#
# set :app_server_port, 87654
# set :app_server_start_cmd, "#{bundle_cmd} exec thin start -p #{app_server_port} -e #{rails_env}"
#
# Notes:
#
# The deploy_to gets set for you, because the rails code needs to live somewhere
# under /var/www/virtual/ so that Apache can access it. It's got a sane default
# which you can override as long as you keep the above in mind.
# The uberspace_home and uberspace_service variables don't need to be touched.
#
# Your setup tasks may look like this, if you bring your own database.yml (usually
# with vlad:copy:shared) you can remove the vlad:uberspace:create_database_yml task:
#
# set :setup_tasks, %w(
# vlad:setup_app
# vlad:copy:shared
# vlad:assets:create_shared_dir
# vlad:uberspace:setup
# vlad:uberspace:create_database_yml
# )
#
# Unless you ship your own public/.htaccess file (which may include custom config)
# you should include the vlad:uberspace:create_reverse_proxy_htaccess after the
# vlad:update task, so that everything works as expected:
#
# set :deploy_tasks, %w(
# vlad:update
# vlad:uberspace:create_reverse_proxy_htaccess
# [...]
# )
set(:deploy_to) { "/var/www/virtual/#{user}/rails/#{application}" }
set(:uberspace_home) { "/home/#{user}" }
set(:uberspace_service) { "#{uberspace_home}/service/rails-#{application}" }
namespace :vlad do
namespace :uberspace do
desc 'Setup your Uberspace for deploying a Rails app'
remote_task :setup do
%w(svscan service domain_symlink).each do |task|
Rake::Task["vlad:uberspace:setup_#{task}"].invoke
end
end
desc 'Setup custom services for your user'
remote_task :setup_svscan do
puts '[Uberspace] Setup svscan'
run 'uberspace-setup-svscan ; echo' # echo to ensure non-error exit
end
desc 'Setup service script for the app'
remote_task :setup_service do
puts '[Uberspace] Setup service'
unless app_server_start_cmd
raise(Rake::ConfigurationError,
'Please specify the application server start command via the :app_server_start_cmd variable')
end
etc_dir = "#{uberspace_home}/etc/run-rails-#{application}"
# install
run "mkdir -p #{etc_dir}"
run "mkdir -p #{etc_dir}/log"
put "#{etc_dir}/run" do
<<-EOF
#!/bin/bash
export HOME=#{uberspace_home}
source $HOME/.bash_profile
cd #{current_path}
exec #{app_server_start_cmd} 2>&1
EOF
end
put "#{etc_dir}/log/run" do
<<-EOF
#!/bin/sh
exec multilog t ./main
EOF
end
run "chmod +x #{etc_dir}/run"
run "chmod +x #{etc_dir}/log/run"
run "ln -nfs #{etc_dir} #{uberspace_service}"
end
desc 'Symlink domain to current path'
remote_task :setup_domain_symlink do
puts '[Uberspace] Setup domain symlink'
# ensure that there is a current public path we can symlink to
Rake::Task['vlad:update'].invoke unless VladExtras::Remote.exists?(current_path)
public_path = "#{current_path}/public"
domain_path = "/var/www/virtual/#{user}/#{domain}"
run "mkdir -p #{public_path}" unless VladExtras::Remote.exists?(public_path)
run "ln -nfs #{public_path} #{domain_path}"
end
desc 'Creates shared/config/database.yml from your my.cnf'
remote_task :create_database_yml do
puts '[Uberspace] Create database.yml'
database_yml = "#{shared_path}/config/database.yml"
db_conf = run "cat #{uberspace_home}/.my.cnf"
db_port = db_conf.match(/^port=(\w+)/)[1]
db_username = db_conf.match(/^user=(\w+)/)[1]
db_password = db_conf.match(/^password=(\w+)/)[1]
db_socket = db_conf.match(/^socket=(.*)$/)[1]
content = <<-EOF
#{rails_env}:
adapter: mysql2
encoding: utf8
reconnect: false
pool: 5
host: localhost
port: #{db_port}
database: #{user}_#{application}
username: #{db_username}
password: #{db_password}
socket: #{db_socket}
EOF
# check for already existing htaccess
if VladExtras::Remote.exists?(database_yml)
puts "\nYou already have a custom database.yml, located at\n#{database_yml}"
puts "Please verify that it contains the following lines in order to work properly:"
puts "\n#{content}\n"
else
# otherwise install it
unless app_server_port
raise(Rake::ConfigurationError,
'Please specify the application server port via the :app_server_port variable')
end
run "mkdir -p #{File.dirname(database_yml)}"
put database_yml do
content
end
run "chmod +r #{database_yml}"
end
end
desc 'Creates .htaccess with Apache reverse proxy config'
remote_task :create_reverse_proxy_htaccess do
puts '[Uberspace] Setup Apache reverse proxy'
htaccess = "#{current_path}/public/.htaccess"
content = <<-EOF
RewriteEngine On
RewriteBase /
# ensure the browser supports gzip encoding
RewriteCond %{HTTP:Accept-Encoding} \\b(x-)?gzip\\b
RewriteCond %{REQUEST_FILENAME}.gz -s
RewriteRule ^(.+) $1.gz [L]
# ensure correct Content-Type and add encoding header
<FilesMatch \\.css\\.gz$>
ForceType text/css
Header set Content-Encoding gzip
</FilesMatch>
<FilesMatch \\.js\\.gz$>
ForceType text/javascript
Header set Content-Encoding gzip
</FilesMatch>
# cache assets like forever
<FilesMatch \\.(js|css|gz|jpe?g|gif|png|ico)$>
Header unset ETag
FileETag None
ExpiresActive On
ExpiresDefault "access plus 1 year"
</FilesMatch>
# maintenance mode
ErrorDocument 503 /system/maintenance.html
RewriteCond %{REQUEST_URI} !.(css|gif|jpg|png)$
RewriteCond #{current_path}/public/system/maintenance.html -f
RewriteCond %{SCRIPT_FILENAME} !maintenance.html
RewriteRule ^.*$ - [redirect=503,last]
# let rails handle everything else
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ http://localhost:#{app_server_port}/$1 [P]
EOF
# check for already existing htaccess
if VladExtras::Remote.exists?(htaccess)
puts "\nYou already have a custom .htaccess, located at\n#{htaccess}"
puts "Please verify that it contains the following lines in order to work properly:"
puts "\n#{content}\n"
else
# otherwise install it
unless app_server_port
raise(Rake::ConfigurationError,
'Please specify the application server port via the :app_server_port variable')
end
put htaccess do
content
end
run "chmod +r #{htaccess}"
end
end
desc 'Reloads service script'
remote_task :reload_service do
puts '[Uberspace] Reload service'
run "svc -h #{uberspace_service}"
end
desc 'Removes service script'
remote_task :remove_service do
puts '[Uberspace] Remove service'
run "cd #{uberspace_service}"
run "rm #{uberspace_service}"
run "svc -dx . log"
run "rm -rf #{uberspace_home}/etc/run-rails-#{application}"
end
end
desc 'Starts the application server'
remote_task :start_app, :roles => :app do
run "svc -u #{uberspace_service}"
end
desc 'Stops the application server'
remote_task :stop_app, :roles => :app do
run "svc -d #{uberspace_service}"
end
desc 'Restarts the application server'
remote_task :restart_app, :roles => :app do
run "svc -du #{uberspace_service}"
end
end