327 lines
12 KiB
Markdown
327 lines
12 KiB
Markdown
**Cette page a été importée automatiquement de notre ancien wiki mais n'a pas encore été révisée.**
|
||
|
||
# Howto Rails
|
||
|
||
<http://blog.phusion.nl/2012/09/21/the-right-way-to-deal-with-frozen-processes-on-unix/>
|
||
|
||
Mettre en place un environnement de production "Ruby On Rails" exige de trouver les bons compromis
|
||
entre les composants système - stable et robuste par nature - et l'environnement de développement
|
||
"Ruby On Rails" très volatile et changeant. Voici comment nous mettons cela en oeuvre.
|
||
|
||
## Cas 1 : utilisation avec Passenger
|
||
|
||
* [Documentation de Passenger pour Apache](http://modrails.com/documentation/Users%20guide%20Apache.html)
|
||
* [Documentation de Ruby Enterprise Edition](http://www.rubyenterpriseedition.com/documentation.html)
|
||
* [Un howto pour Yaml](http://www.yaml.org/YAML_for_ruby.html) (en parallèle avec Ruby, mais simple à comprendre)
|
||
|
||
### Installation
|
||
|
||
On installe d'abord Ruby 1.8 et ses dépendances utiles (`irb`, `rdoc`, `ri`, …).
|
||
|
||
~~~
|
||
# aptitude install ruby-full irb rubygems rails libactionpack-ruby1.8 libactionmailer-ruby1.8
|
||
~~~
|
||
|
||
Installer les bindings MySQL et OpenSSL (voir [#les-gems Les gems]) :
|
||
|
||
~~~
|
||
# aptitude install libmysql-ruby libopenssl-ruby libmysqlclient15-dev
|
||
~~~
|
||
|
||
### Les gems #les-gems
|
||
|
||
Les gems sont des paquets contentant des librairies et/ou des applications écrites en Ruby. Elles sont énormément utilisées, notamment dans Rails.
|
||
|
||
Par défaut, aucune librairie n'est installée sous forme de gem à part les bindings MySQL et Rack (qui est une dépendance de Passenger)
|
||
Il est préférable d'installer les bindings MySQL à la main (`libmysql-ruby`) car ils nécessitent la compilation d'extensions en C et
|
||
risquent d'être utilisés par tous les utilisateurs.
|
||
|
||
OpenSSL fait normalement partie de la librairie standard Ruby, mais n'est pas inclus dans Debian. Rails en a besoin pour fonctionner, il convient
|
||
donc d'installer `libopenssl-ruby` manuellement.
|
||
|
||
### Ruby Enterprise Edition (REE)
|
||
|
||
REE est une version patchée de Ruby optimisée pour les applications Web et créée par les mêmes développeurs que Passenger.
|
||
REE est donc censé s'intégrer parfaitement avec Passenger.
|
||
|
||
Des paquets (ubuntu) existent pour REE, mais le plus simple est de le compiler à la main.
|
||
Par défaut il s'installera dans le dossier `/opt`, en totale isolation du reste du système.
|
||
Rubygems est livré avec REE, et est placé dans le dossier de ce dernier.
|
||
|
||
Il suffit de récupérer une [archive des sources sur le site de REE](http://rubyenterpriseedition.com),
|
||
de la décompresser et de lancer le script `./installer --no-dev-docs` en tant que root. Le reste de la procédure est indiqué
|
||
par l'installateur.
|
||
|
||
À noter qu'il faut avoir installé les paquets `libreadline-dev`, `libz-dev`, `libssl-dev` et avoir une suite de
|
||
compilation fonctionnelle (gcc, g++, make, patch, …)
|
||
|
||
### Utilisation avec Passenger
|
||
|
||
Passenger est livré avec REE sous forme de gem, on peut donc l'installer juste après REE. Le mode d'installation est alors quelque peu différent :
|
||
|
||
Avant tout on installe toutes les librairies nécessaires : celles de REE listées précédemment, plus les libs de développement d'Apache
|
||
|
||
~~~
|
||
# aptitude install libreadline-dev libz-dev libssl-dev apache2-prefork-dev libcurl4-openssl-dev
|
||
~~~
|
||
|
||
On installe ensuite REE selon la procédure définie ci-dessus, et une fois cette installation terminée, on lance la commande :
|
||
|
||
~~~
|
||
/opt/ruby-enterprise-<version>/bin/passenger-install-apache2-module
|
||
~~~
|
||
|
||
L'installateur nous guide dans la procédure. Dans le cas ou le MPM d'Apache est ITK, il préviendra :
|
||
|
||
~~~
|
||
WARNING: Apache doesn't seem to be compiled with the 'prefork' or 'worker' MPM
|
||
~~~
|
||
|
||
On peut cependant continuer l'installation en ignorant l'avertissement. Une fois terminée, l'installateur donne la configuration pour Apache
|
||
|
||
Dans `/etc/apache2/mods-available/passenger.load` on mettra la ligne :
|
||
|
||
~~~
|
||
LoadModule passenger_module /opt/ruby-enterprise-1.8.7-2010.02/lib/ruby/gems/1.8/gems/passenger-3.0.0/ext/apache2/mod_passenger.so
|
||
~~~
|
||
|
||
et dans `/etc/apache2/mods-available/passenger.conf` :
|
||
|
||
~~~
|
||
<IfModule passenger_module>
|
||
PassengerRoot /opt/ruby-enterprise-<version>/lib/ruby/gems/1.8/gems/passenger-3.0.0
|
||
PassengerRuby /opt/ruby-enterprise-<version>/bin/ruby
|
||
|
||
PassengerEnabled off
|
||
#RailsAutoDetect off
|
||
#RackAutoDetect off
|
||
PassengerFriendlyErrorPages off
|
||
|
||
</IfModule>
|
||
~~~
|
||
|
||
Puis : `a2enmod passenger`
|
||
|
||
Une fois REE installé il reste un dernier soucis, les binaires sont dans `/opt/ruby-enterprise-<version>/bin`,
|
||
et pour que les utilisateurs puissent les utiliser il y a deux options possibles :
|
||
|
||
1. Rajouter ce chemin dans le PATH par défaut de tous les utilisateurs.
|
||
1. Créer des liens symboliques dans `/usr/bin`.
|
||
|
||
Pour la deuxième solution, le script suivant permet d'automatiser la tâche :
|
||
|
||
~~~
|
||
#!/bin/bash
|
||
cd /usr/bin
|
||
for i in `ls -1d /opt/ruby-enterprise-*/bin/*`; do
|
||
ln -s $i
|
||
done
|
||
~~~
|
||
|
||
|
||
### Configuration de Passenger/mod_rails
|
||
|
||
Par défaut, Passenger est activé pour tous les sites d'Apache et propose une auto-détection des environnements Rails et Rack,
|
||
on commence par désactiver ce comportement dans `/etc/apache2/mods-available/passenger.conf` :
|
||
|
||
~~~
|
||
<IfModule mod_passenger.c>
|
||
PassengerRoot /usr
|
||
PassengerRuby /usr/bin/ruby1.8
|
||
|
||
# On ajoute les lignes suivantes:
|
||
PassengerEnabled off
|
||
RailsAutoDetect off
|
||
RackAutoDetect off
|
||
|
||
PassengerTempDir /var/tmp/
|
||
PassengerUploadBufferDir /var/tmp
|
||
# S'assurer que les permissions sur le dossier permettent à Apache d'écrire dedans
|
||
# cf. <http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerUploadBufferDir>
|
||
# C'est surtout important avec Apache ITK !
|
||
</IfModule>
|
||
~~~
|
||
|
||
### Exemple de VirtualHost pour Rails
|
||
|
||
~~~
|
||
<VirtualHost *:80>
|
||
ServerName redmine.evolix.net
|
||
PassengerEnabled on
|
||
RailsAutoDetect on
|
||
|
||
DocumentRoot /home/redmine/www/public
|
||
<Directory /home/redmine/www/public>
|
||
Allow from all
|
||
Options -MultiViews
|
||
</Directory>
|
||
|
||
# Pour Apache 2 ITK
|
||
AssignUserID {user} {group}
|
||
</VirtualHost>
|
||
~~~
|
||
|
||
* [#apache-itk-users Information complémentaire sur Apache ITK]
|
||
* [Script de génération de VHost](http://forge.evolix.org/scm/viewvc.php/trunk/scripts/create_rails_vhost?view=markup&root=packweb)
|
||
|
||
### Trucs, astuces et détails
|
||
|
||
#### Apache ITK #apache-itk-users
|
||
|
||
Passenger détermine sous quel utilisateur il va lancer l'application en se basant sur le propriétaire du fichier
|
||
`config/environment.rb` de l'application Rails.
|
||
|
||
Il faut donc y placer un propriétaire identique à celui utilisé dans AssignUserID
|
||
|
||
#### Les environnements de Rails
|
||
|
||
Rails propose trois environnements d'exécution distincts : `production`, `development` et `test`.
|
||
|
||
Chacun a un but précis facilement devinable depuis son nom.
|
||
|
||
Par défaut, Passenger fait tourner l'application en mode production. On peut forcer un certain environnement
|
||
en plaçant la directive `RailsEnv <env>` dans le fichier de configuration du VHost.
|
||
|
||
Pour lancer dans un certain environnement les commandes qui agissent avec l'application (par exemple les
|
||
tâches [Rake](http://guides.rubyonrails.org/command_line.html#rake-is-ruby-make)), il suffit de définir la
|
||
variable d'environnement RAILS_ENV, par exemple :
|
||
|
||
~~~
|
||
$ RAILS_ENV=production rake db:migrate
|
||
~~~
|
||
|
||
#### Redémarrage de l'application
|
||
|
||
Pour redémarrer une application Rails, il suffit de créer ou de mettre à jour le timestamp du fichier
|
||
`tmp/restart.txt` (avec la commande `touch` par exemple). À la prochaîne requête, l'application sera
|
||
redémarrée et tout l'environement chargé de nouveau.
|
||
|
||
Pour que l'application redémarre à chaque requête on peut aussi créer un fichier `tmp/always_restart.txt`
|
||
et le supprimer une fois qu'on ne souhaite plus ce comportement.
|
||
|
||
#### `umask`s spéciaux
|
||
|
||
Sur certains système, l'umask par défaut rend les fichiers installés par root non lisibles par le commun des utilisateurs.
|
||
Si celà est une bonne idée, combinée avec Rubygems et Apache ITK, celà devient moins évident, et il faut veiller
|
||
à `chmod`er correctement le dossier de Ruby pour que tous les utilisateurs puissent l'utiliser.
|
||
|
||
Un exemple avec REE :
|
||
|
||
~~~
|
||
# chmod -R u=rwX,g=rX,o=rX /opt/ruby-enterprise-1.8.7-2010.02/
|
||
~~~
|
||
|
||
#### Priorités de chargement
|
||
|
||
Par défaut, même lorsque `rubygems` est activé, Ruby utilisera en priorité les librairies système
|
||
(celles installées par les paquets) plutôt que les gems. On peut cependant forcer l'utilisation d'une gem,
|
||
et même fixer la version désirée (sinon c'est la plus récente qui est automatiquement utilisée).
|
||
|
||
Cette gestion des versions doit être faite par le développeur, qui peut installer les librairies qu'il souhaite indépendamment du système.
|
||
L'important est de savoir qu'il y a trois endroits ou on peut trouver une librairie Ruby :
|
||
|
||
* Installée par un paquet (`/usr/lib/ruby/1.8/`)
|
||
* Installée en temps que gem système (`/var/lib/gems/1.8/`)
|
||
* Installée en temps que gem utilisateur (`~/.gem/ruby/1.8/`)
|
||
|
||
#### Lister les gems
|
||
|
||
Il n'existe pas de moyen de lister les gems installées uniquement sur le système, la commande `gem` cherche
|
||
à la fois dans le dossier `.gem` de l'utilisateur et le dossier système. La solution est d'utiliser un script
|
||
spécialisé qui fait cette recherche.
|
||
|
||
Le script est disponible dans le dépôt Subversion du Pack Web Evolix, dans
|
||
[trunk/scripts/list_gems](http://forge.evolix.org/scm/viewvc.php/trunk/scripts/list_gems?view=markup&root=packweb).
|
||
|
||
#### Économiser un peu d'espace
|
||
|
||
Par défaut, `gem` installe la documentation aux formats RDoc (documentation html) et RI (documentation console)
|
||
pour les gems installées. Pour éviter celà, créer un fichier `.gemrc` dans la `$HOME` de l'utilisateur avec le
|
||
contenu suivant :
|
||
|
||
~~~
|
||
gem: --no-rdoc --no-ri
|
||
~~~
|
||
|
||
À mettre aussi dans la `$HOME` de `root` si c'est lui qui installe les gems.
|
||
|
||
#### Rails 2.3.2->2.3.5 & Passenger & les logs
|
||
|
||
Une petite erreur en environnement de production affecte les versions 2.3.2 à 2.3.5 (incluse) de Rails. Les logs
|
||
de l'application ne sont pas écrits dans le fichier `log/production.log`. Pour pallier cette erreur, il faut appliquer
|
||
le patch qu'on trouve [ici](https://rails.lighthouseapp.com/projects/8994/tickets/3577-failsafe-middleware-should-flush-the-logger)
|
||
(deuxième fichier).
|
||
|
||
#### Répertoire temporaire de Passenger
|
||
|
||
Passenger stocke tous ses fichiers temporaires dans le répertoire /tmp/ par défaut. Pour diverses raisons (de place, de droits voire de performance), il peut être intéressant d'en définir un autre. Cela ce fait via la directive Apache du module Passenger _PassengerTempDir_. Par exemple, nous mettons :
|
||
|
||
~~~
|
||
PassengerTempDir /var/tmp/
|
||
~~~
|
||
|
||
### Mise à jour de Passenger
|
||
|
||
Passenger est installé en tant que gem dans _/opt/ruby-enterprise-<version-ree>/lib/ruby/gems/1.8/gems/_.
|
||
Voici la procédure pour le mettre à jour :
|
||
|
||
~~~
|
||
gem update passenger
|
||
~~~
|
||
|
||
~~~
|
||
/opt/ruby-enterprise-<version-ree>/lib/ruby/gems/1.8/gems/passenger-<nouvelle-version-passenger>/bin/passenger-install-apache2-module
|
||
|
||
~~~
|
||
Puis modifier les chemins vers mod_passenger dans la conf d'Apache _/etc/apache2/mod-available/passenger_.{conf,load} pour pointer vers la nouvelle version (notamment les directives _LoadModule_ et _PassengerRoot_).
|
||
Enfin, redémarrer Apache pour prendre en compte le nouveau module.
|
||
|
||
### Mise à jour de REE
|
||
|
||
Pour mettre à jour REE, il suffit de recommencer la procédure d'installation, la nouvelle version sera installé dans /opt/ruby-enterprise-<nouvelle-version> et ne perturbera donc pas la prod existante.
|
||
|
||
Pour prendre en compte la nouvelle installation de REE, il faut modifier les chemins vers REE dans la configuration d'Apache.
|
||
|
||
*Important :* pour la migration de REE 1.8.7-2010.02 vers 1.8.7-2011.01, il faut ajouter cette directive dans la configuration d'Apache :
|
||
|
||
~~~
|
||
RackBaseURI /
|
||
~~~
|
||
|
||
Et enlever les éventuelles directives `RailkBaseURI`.
|
||
|
||
|
||
## Cas 2 : utilisation avec rbenv + Unicorn
|
||
|
||
*rbenv* permet d'avoir un environnement compilé par utilisateur.
|
||
C'est donc le développeur qui gère sa version de Ruby, ses Gems, etc...
|
||
on ne lui installe même pas Ruby !
|
||
|
||
Note préalable : mettre les droits _exec_ sur la partition /home
|
||
|
||
~~~
|
||
# aptitude install build-essential curl mg
|
||
~~~
|
||
|
||
~~~
|
||
# aptitude install python-pygments zlib1g-dev libxml2-dev \
|
||
libxslt1-dev libmysqlclient-dev libcurl4-openssl-dev \
|
||
libmagickcore-dev libmagickwand-dev libreadline-dev imagemagick
|
||
~~~
|
||
|
||
~~~
|
||
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
|
||
$ git clone git://github.com/sstephenson/ruby-build.git .rbenv/plugins/ruby-build
|
||
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
|
||
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
|
||
$ . .bash_profile
|
||
$ rbenv install 1.9.2-p290
|
||
$ rbenv global 1.9.2-p290
|
||
~~~
|
||
|
||
Astuces diverses :
|
||
|
||
~~~
|
||
rails_env = `head -1 $(HOME}/www/current/config/database.yml | tr ':' ' '`
|
||
~~~
|