Rails App维护而不妨碍访客
Phusion Passenger错误消息不是我希望访问者在我更新后端时登陆我的网站时看到的内容。
那么我该如何解决这个问题呢? 我的部署过程从一开始就存在缺陷吗? 还是有什么我错过了?
这是我的部署过程,所以你得到了图片:
- 提交对git仓库的新更新并推送到远程
- 上限部署
- ssh [ip]
- 耙gem:安装
- rake db:migrate
- 黄瓜
cap部署和db:migrate或gems:install之间的时间是出现错误消息或更长时间的维护期间。
在我写这篇文章时,一个想法让我感到震惊:我可以将这些命令放入我的部署配方中吗?
但是,如果维护需要30分钟或一小时,这些命令将无法解决问题。 如何在这段时间内向访问者提供维护启动页面?
提前致谢。
如果应用程序暂时不可用,您应该建立一个维护页面。 我使用这个Capistrano任务:
namespace :deploy do namespace :web do desc <<-DESC Present a maintenance page to visitors. Disables your application's web \ interface by writing a "maintenance.html" file to each web server. The \ servers must be configured to detect the presence of this file, and if \ it is present, always display it instead of performing the request. By default, the maintenance page will just say the site is down for \ "maintenance", and will be back "shortly", but you can customize the \ page by specifying the REASON and UNTIL environment variables: $ cap deploy:web:disable \\ REASON="a hardware upgrade" \\ UNTIL="12pm Central Time" Further customization will require that you write your own task. DESC task :disable, :roles => :web do require 'erb' on_rollback { run "rm #{shared_path}/system/maintenance.html" } reason = ENV['REASON'] deadline = ENV['UNTIL'] template = File.read('app/views/admin/maintenance.html.erb') page = ERB.new(template).result(binding) put page, "#{shared_path}/system/maintenance.html", :mode => 0644 end end end
app/views/admin/maintenance.html.erb
文件应包含:
We're currently offline for <%= reason ? reason : 'maintenance' %> as of <%= Time.now.utc.strftime('%H:%M %Z') %>.
Sorry for the inconvenience. We'll be back <%= deadline ? "by #{deadline}" : 'shortly' %>.
最后一步是使用一些指令配置Apache虚拟主机以查找maintenance.html
文件,并将所有请求重定向到它(如果存在):
RewriteEngine On # Redirect all requests to the maintenance page if present RewriteCond %{REQUEST_URI} !\.(css|gif|jpg|png)$ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /system/maintenance.html [L]
要将应用程序置于维护模式,请运行cap deploy:web:disable
并再次使其生效。执行cap deploy:web:enable
。