Finalist

Finalist Developers Blog

Ruby on Rails Deployment for Dummies

30 August 2008 17:25 · Stefan Borsje · Ruby

Van lastig te beheren Mongrel cluster setups tot trage FastCGI configuraties, het wordt er niet simpeler van. Waarom lijkt “webdevelopment that doesn’t hurt” toch niet samen te gaan met “deployment that doesn’t hurt”? Het neerzetten van een volledige Ruby on Rails stack is een tijd lang een flinke uitdaging gebleven. Totdat opeens Passenger, een module voor de Apache webserver, op het toneel verscheen. In deze tutorial laat ik je zien hoe je binnen no-time een kant-en-klare Ruby on Rails stack op Ubuntu Server installeert.

Het opzetten van de Ruby on Rails server bestaat uit de volgende stappen:

  1. Het voorbereiden van de Ubuntu installatie zodat deze volledig up-to-date is en beschikt over de benodigde paketten.
  2. Het installeren van Ruby on Rails.
  3. Het installeren van MySQL.
  4. Het installeren van Apache en Passenger.
  5. En als kersje op de taart, het deployen van een bestaande Rails applicatie met behulp van Capistrano.

Benodigdheden:

  • Een verse Ubuntu installatie.
  • Voldoende rechten om het sudo-commando te gebruiken.

Ubuntu 8.04

Zorg dat de Ubuntu machine up-to-date is en installeer een aantal benodigde tools:

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install build-essential make gcc subversion openssh-server

Ruby 1.8 & Rails 2.1.0

Installeer Ruby, Rubygems en nog een aantal handige pakketten:

$ sudo apt-get install ruby rdoc irb ruby1.8-dev rubygems libopenssl-ruby

Omdat de Rubygems uit de apt-repository iets achterloopt, is het handig om deze eerst te updaten:

$ sudo gem update
$ sudo gem update --system

Tijdens deze update wordt een compleet nieuwe versie van Rubygems geïnstalleerd. De oude versie kan dus verwijderd worden en er kan een verwijzing gemaakt worden naar de nieuwe versie:

$ sudo apt-get remove rubygems libgems-ruby1.8
$ sudo ln -s /usr/bin/gem1.8 /usr/bin/gem

Nu kan Rails geïnstalleerd worden:

$ sudo gem install rails

MySQL 5

Als je gebruik wilt maken van MySQL heb je de client libraries en de MySQL gem nodig:

$ sudo apt-get install libmysqlclient15-dev
$ sudo gem install mysql

Indien je mysql-server op dezelfde server wilt gebruiken, dien je deze uiteraard ook te installeren:

$ sudo apt-get install mysql-server

Apache 2.2 + Passenger 2.0.2

En dan nu het spannendste gedeelte: de Apache installatie! In plaats van gebruik te maken van een ingewikkelde proxy setup met meerdere Mongrel servers houden we het zo simpel mogelijk door Passenger te gebruiken. Om Passenger te kunnen installeren heb je alleen nog Apache nodig, alle andere afhankelijkheden zijn als het goed is ondertussen al aanwezig op de server:

$ sudo apt-get install apache2 apache2-threaded-dev

En vervolgens installeer je de Passenger Gem zodat je de Apache module kunt bakken:

$ sudo gem install passenger
$ sudo passenger-install-apache2-module

Het installatiescript geeft een vrolijk welkomstbericht en zal een aantal afhankelijkheden op hun aanwezigheid controleren. Als het goed is is alles al aanwezig en zal het script na een druk op de Enter-knop automagisch beginnen met het bakken van de Apache module.

Volg de instructies die het installatiescript geeft.

Het aanpassen van de configuratie vindt in Ubuntu niet plaats in apache2.conf of httpd.conf, maar in speciale module configuratiebestanden die in /etc/apache2/mods-available staan. Kopieer de configuratie zoals die door het installatie script gegeven wordt, en maak vervolgens 2 configuratiebestanden aan:

$ sudo touch /etc/apache2/mods-available/passenger.load
$ sudo touch /etc/apache2/mods-available/passenger.conf

Plaats in passenger.load de LoadModule instructie zoals door het installatiescript gegeven, bijvoorbeeld:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2/ext/apache2/mod_passenger.so

En plaats in passenger.conf de overige instructies, bijvoorbeeld:

PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.2
PassengerRuby /usr/bin/ruby1.8

Deze configuratie-instellingen verschillen per Passenger versie, dus neem de bovenstaande instellingen niet 1-op-1 over maar gebruik die uit het installatiescript.

De module is nu te gebruiken met de standaard a2enmod en a2dismod commando’s. Schakel de module in en herstart Apache:

$ sudo a2enmod passenger
$ sudo /etc/init.d/apache2 restart

Bonusronde: Deployment met Capistrano 2.4

Tijd om de server en Ruby on Rails applicatie helemaal deploy-klaar te maken en de setup te testen!

Maak op de server een deploy gebruiker aan, die in dezelfde groep als Apache (www-data) zit:

$ sudo adduser deploy --ingroup www-data

Dit wordt de gebruiker waarmee de Ruby on Rails applicatie gedeployed gaat worden. Het voordeel van een extra deploy gebruiker is dat meerdere developers gebruik kunnen maken van dit account, zonder dat je verstrikt raakt in ingewikkelde ruzies over owners en permissions.

Maak vervolgens een directory aan waar alle Rails applicaties leven, bijvoorbeeld /var/rails:

$ sudo mkdir /var/rails

Je Rails applicatie zal zich dus bevinden in /var/rails/applicatie-naam, dus voor het gemak nemen we als testproject ‘foobar’ en maken we hiervoor een directory en Apache configuratie aan:

$ sudo mkdir /var/rails/foobar
$ sudo chown deploy:www-data /var/rails/foobar
$ sudo touch /etc/apache2/sites-available/foobar

In de Apache configuratiefile kun je nu vervolgens een VirtualHost aanmaken en de lokatie van je Rails project instellen. Dit werkt gewoon op de standaard manier zoals Apache die gebruikt, namelijk door middel van het instellen van de DocumentRoot. Zorg dat je DocumentRoot altijd naar de public directory binnen de Rails applicatie wijst.

<virtualhost>
  ServerName foobar.local
  DocumentRoot /var/rails/foobar/current/public
</virtualhost>

Vervolgens schakel je de configuratie in:

$ sudo a2ensite foobar

Wacht nog even met het herstarten van Apache, want de public directory bestaat nog niet.

Voor het uitrollen van de Rails applicatie kun je gebruik maken van Capistrano. Capistrano is een Gem waarmee het mogelijk is een applicatie dusdanig in te richten dat deze met één enkele handeling te deployen is. Om gebruik te maken van Capistrano moet je op je ontwikkelomgeving eerst de Capistrano Gem installeren, en vervolgens het project geschikt maken voor Capistrano.
LET OP! Deze commandos moet je dus niet op je server uitvoeren, maar op je ontwikkelomgeving.

$ sudo gem install capistrano
$ cd foobar
$ capify .

Er worden nu 2 files aan je applicatie toegevoegd, Capfile en config/deploy.rb. Om de deployment configuratie aan te passen open je config/deploy.rb. Als voorbeeld kun je de volgende configuratie gebruiken:

set :application,   "foobar"
set :repository,    "http://path-to-svn-repository"
set :deploy_to,     "/var/rails/#{application}"
set :user,          "deploy"
set :password,      "secret"
set :host_ip,       "10.0.0.1"
set :restart_file,  "#{current_path}/tmp/restart.txt"
 
role :app, host_ip
role :web, host_ip
role :db,  host_ip, :primary =&gt; true
 
namespace :deploy do
  desc "Disable spinner"
  task :start do; end
 
  desc "Restart Passenger"
  task :restart do
    run "touch #{restart_file}"
  end
end

Controleer alle variabelen even en vervang waar nodig de waarden door de instellingen die voor je applicatie van toepassing zijn. Het ‘password’ is het wachtwoord dat je tijdens de setup aan de deploy user gegeven hebt.

In principe is je applicatie nu bijna klaar om uitgerold te worden. In de normale workflow van Capistrano zou je nu het cap deploy:setup commando uit moeten voeren. Echter heeft je deploy gebruiker hier sudo voor nodig op de productiemachine, en aangezien de deploy user door meerdere ontwikkelaars gebruikt kan worden is het niet echt wenselijk dat deze over root rechten beschikt.

Om dit op te lossen kun je handmatig een aantal directories aanmaken, zodat je deploy gebruiker geen sudo meer nodig heeft:

$ sudo mkdir /var/rails/foobar/releases
$ sudo mkdir /var/rails/foobar/shared
$ sudo mkdir /var/rails/foobar/shared/log
$ sudo chown -R deploy:www-data /var/rails/foobar

Controleer of het wachtwoord van de deploy user zowel in de subversion repository als op de server gelijk zijn, zodat Capistrano maar één gebruikersnaam/wachtwoord combinatie nodig heeft.
Test de setup door vanaf je ontwikkelomgeving het volgende commando uit te voeren:

$ cap deploy

Als je geen foutmeldingen gekregen hebt kun je nu Apache herstarten:

$ sudo /etc/init.d/apache2 reload

Als alles goed gegaan is staat je Rails applicatie nu live!

Share and Enjoy:
  • E-mail this story to a friend!
  • Print this article!
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Blogosphere News
  • Fleck
  • NuJIJ
  • Slashdot
  • StumbleUpon
  • LinkedIn
  • Twitter

6 reacties »

  1. Ik heb het vermoeden dat je voorbeeld voor het werken _zonder_ sudo rechten nog een extra parameter nodig heeft:

    set :sudo, false
    

    In een productie setup zou ik er trouwens voor kiezen om te werken met public-key authenticatie voor zowel subversion als het deployment proces, dan hoef je geen plaintext passwords in je deployment configuratie op te nemen.

    Lekker compleet artikel trouwens!

    Peter Maas - September 1, 2008 20:09

  2. Ik kan toch nog steeds niet zeggen dat het deployen van RoR apps nou zo simpel is. Laatst moest op een Debian server een eigen Ruby gecompileerd worden, omdat Passenger anders constant 20% CPU stond te eten. Het is gewoon nog niet erg ‘mature’ allemaal. Maargoed, het gaat de goede kant op.

    Nils Breunese - September 1, 2008 20:25

  3. Briljant! Het duurde maarliefst vijf minuten (nou ok… bijna dan… zeven volle minuten) om de boel aan de praat te krijgen op mijn Ubuntu server. Mature genoeg voor mij ;-)

    Diederick Lawson - September 1, 2008 20:54

  4. Stefan

    Voor windows gebruikers gewoon instant rails (http://instantrails.rubyforge.org/wiki/wiki.pl) blijven gebruiken?

    Ernst-Jan - September 2, 2008 9:22

  5. @Stefan / @Ernst-Jan (van wie is dat comment nou?)

    instant rails heeft niet echt iets te maken met een deployment procedure naar een OTAP server. dit artikel geeft een aanzet tot het inrichten van een server en het deployen naar deze server.

    Peter Maas - September 2, 2008 19:43

  6. Very good guide, nice to see -great for those who need to get into Ruby / Rails. You might like to consider adding enterprise ruby as an option!!

    Brett Dawkins - November 5, 2008 14:15

Reageer

RSS feed for comments on this post · TrackBack URI