Deploying a Merb app with Capistrano, monit and nginx

Friday, February 27, 2009

For the second time this morning, we’ve deployed a merb app on a server, and even if it’s quite simple once you’ve got the logic in the head, it’s surely necessary to have this little note for future deploys.
I hope it’ll help other merb dev to fill the documentation hole about this process, feel free to complete or debug it in the comments. More documentation about this process is available on the Merb Open Source Book

Let’s suppose you all know how to use Capistrano, and that your project is already deployed with it, you now want Nginx to serve request to your merb app.

Nginx

First, you need to configure nginx to act as a proxy to send requests to your merb servers. In /etc/nginx/conf.d/merb.conf:


upstream merb_app {
  server 127.0.0.1:4000;
  server 127.0.0.1:4001;
}

And in /etc/nginx/sites-enabled/domain.conf_, the most important line is "*proxy_pass http://merbapp;*":


server {
    listen 80;
    server_name domain.com;

    root /home/deploy/merb_app/current/public;

    access_log /home/deploy/merb_app/shared/log/access.log;
    error_log /home/deploy/merb_app/shared/log/error.log;

    location / {

      proxy_set_header  X-Real-IP       $remote_addr;
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header  Host            $http_host;

      proxy_redirect false;
      proxy_max_temp_file_size 0;

      if (-f $request_filename) {
        break;
      }

      if (-f $request_filename.html) {
        rewrite (.*) $1.html break;
      }

      if (!-f $request_filename) {
        proxy_pass http://merb_app;
        break;
      }

    } # location

} # server


We surely can merge this 2 files in the same configuration file, but it’s just working this way today, let’s change it later.

Monit and monit_merb_mpc

Thats the tricky part, you need to start a master merb that’ll monitor workers on your app ports.

First, the /etc/monit.d/domain.monit file, that’ll be call to start/stop/restart all these processes:

And the monit_merb_mpc script from “Engine Yard”:, the original was too buggy for our server, so here is a working version:

It’s surely still buggy, and all this long configuration surely will be replaced by a lighter god script that’ll at the same time generate and monitor the master/workers processes.

Restart with Capistrano

The easiest part of all, you just need to tell your monit to start/stop/restart the group defined in the monit preferences:


namespace :deploy do
  # Redefine the application server controls to use monit.
  %W(restart start stop).each do |event|
    desc "#{event} using Monit"
    task event, :except => { :no_release => true } do
      sudo "/usr/sbin/monit -c /etc/monit/monitrc -g #{application} #{event} all"
    end
  end
end

This entry was published on Friday, February 27, 2009. Articles published around the same time can be found in the archive.