views:

93

answers:

4

I have a ruby on rails app running a server and sometimes it needs to be taken down for updates/etc. As of now, one way I see to have a general display screen during update periods (when the app is down) is to substitute the files within /srv/www/ directory to just have it display a general screen everywhere that the user could possibly navigate to. I also thought of having a central controller file that connects all others (essentially a main) but this seems counter intuitive for rails.

There are many external links to these different components of the site that the user could navigate to from outside and I need to make sure that they always receive this general update screen when the app is taken down for a little.

I was wondering if anyone had any other ideas.... maybe a library or something like that, I can't seem to find anything online. any suggestions would be appreciated.

Thanks

+3  A: 

I would configure your webserver (nginx or apache) to look for a maintenance.html page and serve that up with a 503 status if it exists. So, taking every URL of your app down is as simple as uploading an .html file and deleting it when it's done.

See here and here for more info.

Callmeed
A: 

Capistrano has a bunch of built-in recipes for displaying maintenance pages and is fully integrated with git/subversion. Makes deployment and management a breeze.

Toby Hede
A: 

I use this Capistrano task:

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

The app/views/admin/maintenance.html.erb file should contain:

<p>We’re currently offline for <%= reason ? reason : 'maintenance' %> as of <%= Time.now.utc.strftime('%H:%M %Z') %>.</p>
<p>Sorry for the inconvenience. We’ll be back <%= deadline ? "by #{deadline}" : 'shortly' %>.</p>

The final step is to configure the Apache virtual host with some directives to look for the maintenance.html file and redirect all requests to it if it's present:

<IfModule mod_rewrite.c>
  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]
</IfModule>

To put the application into maintenance mode, run cap deploy:web:disable and to make it live again do cap deploy:web:enable.

John Topley
Thanks John, please see my comment below
john chan
I tried to set this up and having some issues. The apache does not seem to redirect to the maintenance page. I am running the app using mongrel + apache and after reading many websites I am still not sure. As you said I have a virtual host in apache configured to sit on the specific port and for some reason whether apache is running or not it still displays the app page regardless if I allow or deny access. Therefore, I obviously cannot make it rewrite to the maintenance page. Any ideas? Thanks in advance
john chan
A: 

Thanks for your responses guys I really appreciate it. I have another question though, is it possible to incorporate user rights into this as well? So for example, suppose I only want admins to have a look at the site and all others to see the maintenance page. Is something like that possible?

Thanks again,

John

john chan
You should ask this as a separate question. You should also consider accepting one of the answers to your question here if it helped you. Click the tick to the left of the answer that was most helpful.
John Topley