Le blog perso de Sam

Parce-que je le vaux bien

Mise en production de Rails sous Ubuntu 6.06

Ce document a pour objectif de préparer une mise en production d’un ou plusieurs sites développé(s) avec Ruby On Rails sous Ubuntu 6.06. Pour configurer un environnement de développement, se référer au document Installer Ruby et RoR sur Ubuntu 6.06 (Dapper) .

Le choix technique est ici d’utiliser Mongrel pour faire fonctionner des instances de Rails, et d’utiliser Apache 2.2 pour réceptionner les requêtes et les distribuer aux différentes instances. Apache servira également le contenu statique. Tout ceci est très bien explique ici : Scaling Rails with Apache 2.2, mod_proxy_balancer and Mongrel.

Certains choix ne sont en rien obligatoires : il n’y a pas une seule et unique manière de procéder. Par ailleurs l’installation décrite est une base pour une mise en production, mais n’est pas en soit totalement sécurisée. Il faut encore penser firewall, sauvegardes, rotation de logs, …

Ce qui suit est long (mais détaillé), inspirez profondément avant de continuer ;)

Pré-requis : il est préférable de savoir utiliser linux en ligne de commandes, de maitriser un éditeur en mode texte tel que vi (ou nano pour les newbies), et d’avoir des notions des divers outils utilisés tel que Apache, MySQL, … et bien entendu Ruby et Ruby On Rails ;)

Lors des téléchargements de RubyGems et Apache 2.2, des versions plus récentes peuvent être disponibles, à vérifier sur les sites correspondants.

Liens utiles :

Dernière remarque avant de rentrer dans le vif du sujet : certaines commandes utilisées peuvent demander confirmation, ou de faire un choix. Je vous déconseille fortement de faire des copier/coller d’un bloc entier de commandes à moins de savoir de quoi il s’agit.

===== Préparation du système =====

L’installation s’effectue sur Ubuntu 6.06 en mode serveur (texte), vierge de toute autre installation. Attention, il ne faut pas faire une installation de type LAMP ! Cette dernière installe Apache 2.0.x, or nous avons besoin d’Apache 2.2.x .

Une fois le système installé, il convient de modifier le fichier /etc/apt/sources.list afin de décommenter les lignes finissant par dapper universe et dapper-security universe . Il y a quatre lignes en tout. D’autre part il peut être utile de mettre en commentaire la ligne faisant référence au CD d’installation si on ne l’a pas sous la main. Une fois la modification effectuée, il faut procéder à la mise à jour des paquets, à la mise à jour du système fraichement installé, et enfin à un redémarrage du système dont le noyau a certainement été mis à jour. Pour la première partie, cela se résume à :

sudo vi /etc/apt/sources.list
sudo apt-get update
sudo apt-get dist-upgrade
sudo shutdown -r now

===== Installation de Ruby et MySQL =====

Une fois le système et la liste des paquets à jour, nous allons installer Ruby, MySQL et quelques bricoles utiles pour compiler. Au passage nous allons installer un serveur SSH ce qui facilite grandement la vie au quotidien, et sera potentiellement exploité plus loin lors de la mise en place d’un serveur ftp sécurisé.

Il est à noter que l’on installe explicitement la version 1.8.x de Ruby afin de garantir la compatibilité avec Rails, Mongrel, … Ici l’installation de Ruby se fait à partir des paquets, mais il est également possible de le faire à partir des sources.

sudo apt-get install build-essential mysql-server ssh
sudo mysql_secure_installation
sudo apt-get install ruby1.8 irb1.8 rdoc1.8 ri1.8 ruby1.8-dev libmysql-ruby1.8
sudo ln -s /usr/bin/ruby1.8 /usr/bin/ruby

===== Installer RubyGems et Mongrel =====

Ruby c’est bien, mais sans les gems c’est limité. Nous allons télécharger, compiler et installer RubyGems qui permettra par la suite d’installer Mongrel automatiquement, et bien d’autres outils dont vous pourriez avoir besoin par la suite. Au passage nous créons un répertoire de travail pour ne pas laisser trainer les fichiers n’importe où.

cd
mkdir telecharger_et_installer
cd telecharger_et_installer
wget http://rubyforge.org/frs/download.php/11289/rubygems-0.9.0.tgz
tar xzvf rubygems-0.9.0.tgz
cd rubygems-0.9.0
sudo ruby setup.rb
cd ..
sudo gem update --system
sudo gem install mongrel --include-dependencies
sudo gem install mongrel_cluster --include-dependencies

Pour que les applications démarrent au boot du serveur, il faut ajouter ce qui suit. Pensez à ajuster le chemin en fonction de la version (ici la 0.2.1) :

sudo mkdir /etc/mongrel_cluster
sudo cp /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-0.2.1/resources/mongrel_cluster /etc/init.d
sudo chmod +x /etc/init.d/mongrel_cluster
sudo /usr/sbin/update-rc.d mongrel_cluster defaults

===== Installer Apache 2.2 =====

Apache 2.2 n’étant pas à ce jour packagé pour Ubuntu, il va falloir en télécharger les sources, les compiler les l’installer. J’espère que bientôt la version 2.2 sera intégrée dans Ubuntu, cela facilite tout de même les mises à jour de sécurité. Nous sommes en principe toujours dans notre répertoire telecharger_et_installer .

Avant l’installation d’Apache, nous allons installer un petit complément à Ubuntu pour disposer de la compression et du cryptage si besoin.

sudo apt-get install libssl-dev openssl ssl-cert zlib1g-dev

Maintenant que l’on est bien chaud, on passe à Apache :

wget http://apache.multidist.com/httpd/httpd-2.2.3.tar.gz
tar xzf httpd-2.2.3.tar.gz
cd httpd-2.2.3
./configure --prefix=/usr/local/apache2 --enable-so --enable-ssl --enable-rewrite --enable-proxy --enable-proxy-balancer --enable-proxy-http --enable-deflate --enable-headers
make
sudo make install

===== Configurer Apache 2.2 =====

Apache est installé, mais il reste quelques bricoles à mettre en places pour qu’il démarre automatiquement et fonctionne de manière plus sécurisé.

Commençons pas la sécurité :

sudo adduser --system apache
sudo vi /usr/local/apache2/conf/httpd.conf

Il faut recherche les deux lignes suivantes contenant User daemon et Group daemon pour les remplacer par :

User apache
Group nogroup

Ensuite Apache doit démarrer automatiquement :

sudo cp /usr/local/apache2/bin/apachectl /etc/init.d/apachectl
sudo chmod +x /etc/init.d/apachectl
sudo /usr/sbin/update-rc.d apachectl defaults

Pour voir si tout est ok, il n’y a qu’à rebooter, et vérifier avec la commande ps -ef que des processus httpd appartiennent à l’utilisateur apache.

===== Mettre en place un FTP sécurisé =====

Comme il s’agit ici de mettre en place un serveur, et non pas un environnement de développement, il faut pouvoir transférer le fruit de son travail pour le mettre en production. Nous allons installer un service FTP, et afin d’éviter des vols de données il imposera de travailler de manière sécurisé.

sudo apt-get install vsftpd
sudo vi /etc/vsftpd.conf

Il faut éditer le fichier de configuration de manière à avoir les options suivantes (décommentez, modifiez, ajoutez…) :

anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=077

ssl_enable=YES
allow_anon_ssl=NO
force_local_logins_ssl=YES

Reste à redémarrer le demon :

sudo /etc/init.d/vsftpd restart

Ce serveur n’acceptera pas les connexions non sécurisée. Il est possible d’y accéder avec un cryptage SSH2 en ligne de commande sous windows avec PSFTP disponible à l’adresse suivante (avec PuTTY comme client SSH) : http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Avec FileZilla il est possible d’utiliser le cryptage SSH, FTP sur SSL ou FTP sur TSL.

===== Installer son application Rails =====

Maintenant que notre serveur est prêt, reste à déployer nos applications faites avec Rails. Nous allons les installer dans /var/www et les faire fonctionner avec l’utilisateur mongrel créé spécifiquement.

Ceci est à faire une fois pour toutes :

sudo adduser --system mongrel
sudo addgroup --system mongrel
sudo mkdir /var/www
sudo chmod 755 /var/www

Pour l’exemple nous allons déployer l’application mon_appli :

cd /var/www
sudo mkdir mon_appli

Placez l’ensemble de votre application dans le répertoire mon_appli que nous venons de créer. Par exemple faites un transfert via ftp depuis votre poste de développement puis déplacez ou copiez le tout dans /var/www/mon_appli .

Il faut également créer une base et un utilisateur dédié dans MySQL, et si nécessaire créer et importer tout ce qui est nécessaire à l’application. De plus, vérifiez bien le contenu de votre fichier database.yml et si besoin corrigez le. Tout ceci est hors du contexte de ce tuto (déjà assez long).

Attention : vous aurez noté que l’on a pas installé Rails. En principe vous devez fournir Rails avec votre application, ce qui permet de faire cohabiter pacifiquement plusieurs applications qui n’utilisent pas nécessairement la même version de Rails. Ceci est expliqué dans l’article Freeze il cool, so freeze for goodness sake . Pour résumer, sur votre poste de développement il faut utiliser rake rails:freeze:gems avant de transférer l’application sur le serveur.

Si votre application a besoin de gems particulier, il faudra les installer sur le serveur.

Ensuite il faut sécuriser la chose. Il faudra accorder des droits supplémentaires à d’autres répertoires en fonction de votre application, mais par défaut, on verrouille. Vous noterez que le chemin est dégagé vers le répertoire public pour permettre à Apache de servir le contenu statique.

sudo chown -R mongrel mon_appli
sudo chgrp -R mongrel mon_appli
sudo chmod -R 500 mon_appli
sudo chmod 555 mon_appli
sudo chmod -R 555 mon_appli/public
sudo chmod -R 700 mon_appli/tmp mon_appli/log mon_appli/db

Pour réaliser certaines opérations facilement, il peut être utile de démarrer un shell avec les droit de l’utilisateur mongrel. Par exemple, si votre application a besoin de préparer la base de donnée :

sudo -s -u mongrel
cd mon_appli
rake db:migrate RAILS_ENV=production
exit

Ensuite il faut préparer la configuration pour Mongrel et Mongrel Cluster. Nous allons prendre les ports 8000 à 8002 :

sudo mongrel_rails cluster::configure -e production -p 8000 -N 3 -c /var/www/mon_appli -C /var/www/mon_appli/config/mongrel_cluster.yml --user mongrel --group mongrel
sudo ln -s /var/www/mon_appli/config/mongrel_cluster.yml /etc/mongrel_cluster/mon_appli.yml

Viens le tour d’Apache. Les choses sont expliquées en détail dans la documentation de Mongrel. En ce qui nous concerne, nous allons simplement ajouter placer la configuration dans mon_appli.conf et demander sa prise en compte dans httpd.conf :

sudo vi /usr/local/apache2/conf/httpd.conf

Ajouter ceci en fin de fichier. Le commentaire est là pour faire simple, n’hésitez pas à ajouter plus d’information comme la date d’ajout, l’auteur du changement, …. :

#---
#--- Pour mon_appli (Ruby On Rails)
#---

Include conf/mon_appli.conf

Ensuite il faut éditer le fichier mon_appli.conf :

sudo vi /usr/local/apache2/conf/mon_appli.conf

Et maintenant il faut y ajouter ceci : mon_appli.conf . Pour ne pas perdre l’indentation et encore allourdir la mise en page c’est un fichier séparé. Sont à changer en fonction de vos besoin : le nom du serveur (ici ubuntu.vmware), les chemins de l’application et des logs, les ports utilisés, le nom du balancer (ici mon_appli_cluster) dans sa déclaration et son utilisation, et tout ce que j’ai pu oublier de mentionner ;).

Reste à prendre en compte les changements et vérifier avec un navigateur que tout est opérationnel :

sudo /etc/init.d/mongrel_cluster start
sudo /etc/init.d/apachectl graceful

===== Et si je veux un extranet avec SSL ? =====

Ajouter un accès SSL est assez simple. Concernant l’application RoR il n’y a rien à faire, tout se passe au niveau d’Apache. Il y a deux tâches : créer un certificat (à moins d’en faire l’acquisition) et changer le paramétrage. Nous allons commercer par créer un certificat. Dans ce qui suit, il faut bien veillez à indiquer le nom du domaine dans Common Name lorsqu’il sera demandé. A noter la création d’un sous-répertoire par domaine (ici ubuntu.vmware), pour bien ranger ses clés :

sudo mkdir /usr/local/apache2/ssl
cd /usr/local/apache2/ssl
sudo mkdir ubuntu.vmware
cd ubuntu.vmware
sudo openssl genrsa -des3 -out server.key.encrypted 1024
sudo openssl req -new -x509 -nodes -sha1 -days 365 -key server.key.encrypted -out server.crt
sudo openssl rsa -in server.key.encrypted -out server.key
sudo chmod 400 server.key

Passons à la configuration d’Apache, ajoutons ce qui suit au fichier httpd.conf (avant les inclusions des fichiers de paramètres de nos sites) :

Listen 443
NameVirtualHost *:443

Reste à modifier notre fichier mon_appli.conf. Il faut changer le port d’écoute, la ligne commençant la description de l’hôte virtuel doit faire mention du port 443 au lieu du 80. Puis il faut ajouter ceci au sein de la configuration (dans le VirtualHost) :

RequestHeader set X_FORWARDED_PROTO "https"
SSLEngine on
SSLCertificateKeyFile /usr/local/apache2/ssl/ubuntu.vmware/server.key
SSLCertificateFile /usr/local/apache2/ssl/ubuntu.vmware/server.crt

Pour faire simple, l’ensemble de la configuration est disponible ici : mon_appli.conf avec SSL .

Et… c’est tout ! Reste à redémarrer Apache et à tester.

===== Pour finir =====

J’ai mis du temps à écrire ce tuto, car j’ai pris soin de tout vérifier et re-vérifier. Mais une erreur ou une omission importante ont pu se glisser dans ma prose. N’hésitez pas à me le signaler.

Par ailleurs pour réaliser ce tutoriel et le valider j’ai utilisé des machines virtuelles. Avant de passer en production c’est un excellent moyen de se faire la main à peu de frais et sans risques. Je vous invites à en faire autant.

17 Responses to “Mise en production de Rails sous Ubuntu 6.06”

  1. Frederic Brunel Says:

    J’ai du faire une installation similaire sur une Dedibox et j’ai utilisé le tutorial “The Perfect Setup” (http://www.howtoforge.com/perfect_setup_ubuntu_6.06)…

    Par contre, un détail important, j’avais installé Ruby 1.8.5 depuis les sources ainsi que Mongrel… Bah ça plante carrément, Mongrel fait des segfaults dès qu’on le charge un peu… Vraiment pas cool…

    Il est donc important de rester sur Ruby 1.8.4!

  2. benm Says:

    Merci pour ce trés bon tutorial, ca serait sympa que tu le soumette dans http://tutmarks.com :)

  3. Sam. Says:

    @benm : je ne connaissais pas ce site, j’y ajouté 3 articles, et j’en profite pour voir s’il y a des choses utiles :)

  4. Frédéric Brunel Says:

    Contrairement à mon post précedent, j’ai encore des segfaults de Mongrel même avec Ruby 1.8.4.

    Est-ce que tu as eu un problème similaire?

  5. Sam. Says:

    Non car je n’ai pas l’occasion d’être en production. J’ai qq projets web qui sont toujours reportés pour cause de bricoles plus urgentes.

    Par contre une chose est certaine, c’est redémarrage des instances de Mongrel 1x / 24H ! Ca permet de remettre à zéro les compteurs de consommation de mémoire au cas où certaines requêtes auraient été gourmandes, voir en cas de fuite de mémoire. Si je peux me permettre, c’est redémarrage de tout service (MySQL, Apache, Zope, …), simple et efficace.

    Pour le reste…. le baptême du feu est pour plus tard. Ca va se préciser :)

  6. STef Says:

    Bonsoir,

    J’ai encore un problème :

    Comment puis-je connaître (ou définir) cette valeur (qui revient également dans la ligne RewriteRule ^/(.*)$ balancer://mon_appli_cluster%{REQUEST_URI} [P,QSA,L])

    En ce qui me concerne j’utilise ubuntu 7.04 64 bits + apache2.2 + rails 1.2 + postgresql

    J’utilise aussi un utilisateur standard pr mon appli :
    /home/lambda/public_html/super_appli_rails

    Merci,

    STef

  7. Sam. Says:

    @Stef : je n’avais pas compris ton message au départ… mais ayant fait le lien avec le sujet suivant, je pense avoir collé les morceaux :
    http://www.railsfrance.org/node/978#comment-2014

    Le nom est librement choisit, il faut simplement que dans le nom mentionné dans le RewriteRule corresponde au nom utilisé pour le Proxy / Load Balancer.

  8. STef Says:

    Ca marche maintenant, merci pour l’aide et merci pour ton site !

    STef

  9. STef Says:

    Bonjour,

    Je voulais savoir comment faire pour héberger plusieurs applis rails (avec des utilisateurs differents) sur le meme serveur avec apache et mongrel.

    Est-ce que les 3 instances mongrel (cas de figure décrit dans l’exemple) peuvent servir 2 applis ruby ou bien faut il en créer une ou des nouvelles ?

    Quid au niveau de la config apache ?

    Merci

    STef

  10. Antoine Says:

    Bonjour ..

    Merci beaucoup pour ce tutorial … par contre je pose des questions pour installer phpmyadmin pour controler la base de données de ruby on rails … ???

    merci beaucoup si vous pouviez apporter ces prévisions

    Bonne osiré,e
    Antoine

  11. Sam. Says:

    Je te conseille d’aller faire un tour sur les forums & tuto relatifs à Ubuntu, je travaille peu avec phpmyadmin, la ligne de commande est mon amies ;) Je ne l’installe donc jamais.

    Dans ce cas mieux vaut partir d’une 7.04, installer en mode LAMP (ne pas installer Apache à la main), et installer phpmyadmin (sudo apt-get ….). La version 7.04 d’Ubuntu intégrant Apache 2.2 pas défaut, tout ça se fait les doigts dans le nez (c’est sale, je sais).

    Attention, avec la 7.04 il faut autoriser l’usage du proxy en modifiant un fichier d’apache. Je n’ai plus les détails en tête (ça se trouve facilement sur le net), mais il vaut mieux le savoir pour éviter de perdre beaucoup de temps.

  12. STef Says:

    Bonjour,

    Juste pour ré-itérer une question déjà posée : Je voudrais savoir comment faire un cluster mongrel sur une seule machine (je n’en ai qu’une seule pour le moment) qui héberge plusieurs applis ror avec la collaboration d’apache pour le contenu statique.
    La seule info utile que j’ai trouvé à ce sujet est que la dernière version de mongrel permet de le faire par contre je ne trouve pas de tuto qui explique comment mettre en place un serveur mongrel-apache qui peut héberger plusieurs applis ror (chacune étant associée à un nom de domaine )

    Merci

    STef

  13. Sam. Says:

    Ayant réussi à introduire RoR dans mon boulot, nous avons plusieurs projets en cours. Comme le trafic par site sera plutôt faible, une seule machine pour l’instant. Mais chaque appli a son propre cluster ! C’est simple à mettre en place, et surtout cela permet d’intervenir sur chaque appli isolément (on arrête ce que l’on veut sans gêner le reste). En prod je suis assez partisan de séparer les choses (et donc les problèmes).

    Par contre avoir plusieurs appli une un seul jeu de process mongrel, je ne sais pas faire. J’avais bien vu des trucs qui parlaient de quelque chose d’approchant (c’est vague, je sais), mais jamais de détails.

    Désolé de ne pas t’aider, mais si tu trouve (de concret) sur le sujet, alors un p’tit commentaire indiquant où sera le bienvenu ;-)

  14. STef Says:

    En fait je me suis peut etre mal exprimé…

    En ce moment j’ai une seule appli, un seul cluster et apache. Je veux dire par là qu’à l’époque j’avais 3 instances de mongrel (j’avais mixé plein de tutos et là je sais plus trop cmt j’avais fait).

    J’aimerais rajouter une appli. S’il faut créer un nouveau cluster, pas de problème, à la limite je préfère avoir un cluster par appli pour pouvoir les arreter une à la fois…

    Donc un apache, 2 clusters mongrel et 2 applis ça me va très bien :-)

    Merci pour les infos

    STef

  15. Sam. Says:

    OK. Alors c’est effectivement un nouveau cluster qu’il faut créer.

    Attention toutefois à la consommation mémoire, chaque process Mongrel a potentiellement bon appétit pour certaines appli.

  16. STef Says:

    Ok, mais comment créer un nouveau cluster ? quid de la config apache pour cette appli et cette nouvelle URL ?

    Comment faire pour avoir clustrer1 et cluster2 que je peux démarrer automatiquement au démarrage du serveur et aussi manipuler séparément ?

    Merci

  17. Sam. Says:

    Chaque appli a sa propre config apache (virtual host), et son prope fichier de paramétrage pour mongrel.

    Pour chaque appli devant démarrer automatiquement, le fichier de config de mongrel a alors son propre lien dans /etc/mongrel_cluster.

Leave a Reply