--- categories: web title: Howto Rails ... * Documentation : * YAML Cookbook for Ruby : * Rôle Ansible : [Ruby On Rails](https://rubyonrails.org/) est un framework web libre écrit en Ruby appliquant le principe MVC (Modèle-Vue-Contrôleur). Nous l'utilisons notamment dans le logiciel [Chexpire](https://chexpire.org/). ## Installation ### Installation avec rbenv [rbenv](https://github.com/rbenv/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* : vous devez mettre les droits `exec` sur la partition */home* pour cette installation ~~~ # apt install rbenv build-essential libssl-dev libreadline-dev zlib1g-dev # apt install liblzma-dev libmariadbclient-dev $ eval "$(rbenv init -)" $ mkdir ~/.rbenv/plugins $ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build $ rbenv install --list $ TMPDIR=~/tmp rbenv install 2.5.1 $ rbenv global 2.5.1 $ gem install bundler rails $ echo 'eval "$(rbenv init -)"' >> ~/.bashrc $ ruby -v ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux] $ gem list *** LOCAL GEMS *** actioncable (5.2.1) actionmailer (5.2.1) actionpack (5.2.1) actionview (5.2.1) activejob (5.2.1) activemodel (5.2.1) activerecord (5.2.1) activestorage (5.2.1) activesupport (5.2.1) arel (9.0.0) bigdecimal (default: 1.3.4) builder (3.2.3) bundle (0.0.1) bundler (1.16.3) […] ~~~ ### Installation avec ruby système Cela permet de bénéficier des mises à jour de sécurité de Ruby, tout en gérant les Gems par utilisateur. ~~~ # apt install ruby ruby-dev ruby-bundler # apt install liblzma-dev libmariadbclient-dev $ export PATH="$HOME/.gem/ruby/2.3.0/bin:$PATH" $ gem install bundler $ echo 'PATH="$HOME/.gem/ruby/2.3.0/bin:$PATH"' >> ~/.bashrc $ ruby -v ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu] $ gem list *** LOCAL GEMS *** actionmailer (4.2.7.1) actionpack (4.2.7.1) actionview (4.2.7.1) activejob (4.2.7.1) activemodel (4.2.7.1) activerecord (4.2.7.1) activesupport (4.2.7.1) arel (6.0.3) atomic (1.1.16) bigdecimal (1.2.8) binding_of_caller (0.7.2) blankslate (3.1.3) builder (3.2.2) bundle (0.0.1) bundler (1.16.3, 1.13.6) […] ~~~~ ## Utilisation ### Démarrer un projet Rails ~~~ $ rails --version Rails 4.2.7.1 $ rails new foo $ cd foo ~~~ On peut alors ajuster la configuration (routes, base de données, etc.), coder son projet, le stocker dans un repository Git, etc. Pour voir en local le résultat : ~~~ $ cd foo $ ./bin/rails server => Booting WEBrick => Rails 4.2.7.1 application starting in development on http://localhost:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server [2018-08-12 11:43:15] INFO WEBrick 1.3.1 [2018-08-12 11:43:15] INFO ruby 2.3.3 (2016-11-21) [x86_64-linux-gnu] [2018-08-12 11:43:15] INFO WEBrick::HTTPServer#start: pid=12383 port=3000 ~~~ On peut alors le visualiser sur ### 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. 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 optimisé Pour redémarrer une application Rails de façon optimisée, 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. ### Unité systemd TODO, cf https://wiki.evolix.org/HowtoSystemd#systemd-par-utilisateur ### Les Gems et Bundler Les [Gems](https://rubygems.org/) sont des paquets contentant des librairies et/ou des applications écrites en Ruby. Elles sont souvent utilisées, notamment dans Rails. ~~~ $ gem -v 2.5.2.1 $ gem list $ gem env RubyGems Environment: - RUBYGEMS VERSION: 2.5.2.1 - RUBY VERSION: 2.3.3 (2016-11-21 patchlevel 222) [x86_64-linux-gnu] […] ~~~ Les Gems peuvent se trouver à plusieurs endroits : * installée par un paquet Debian (`/usr/lib/ruby/2.3.0/`) * installée en temps que Gem système (`/var/lib/gems/2.3.0/`) * installée en temps que Gem utilisateur (`~/.gem/ruby/2.3.0/`) Une application Rails contient un fichier `Gemfile` qui précise les Gems nécessaires et leurs versions : ~~~ source 'https://rubygems.org' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2.7.1' # Use sqlite3 as the database for Active Record gem 'sqlite3' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' […] ~~~ [Bundler](https://bundler.io/) est l'outil de prédilection pour installer les Gems nécessaires. Avec la présence d'un fichier `Gemfile`, il suffit de lancer la commande : ~~~ $ bundle install ~~~ Un snapshot des Gems installées est aussi gardé dans un fichier `Gemfile.lock` permettant d'accélérer la résolution des dépendances. En général, on inclut les fichiers `Gemfile` et `Gemfile.lock` dans le repository du projet. ### Capistrano [Capistrano](https://capistranorb.com/) est un outil de déploiement populaire, notamment pour les applications Rails. TODO ## Serveur web Pour une utilisation en production d'une application Rails, on peut utiliser plusieurs solutions : Puma, Unicorn, Passenger, etc. ### Puma [Puma](http://puma.io/) est... TODO ### Unicorn [Unicorn](https://bogomips.org/unicorn/) est... TODO ### Passenger TODO : à tester / ajuster [Passenger](https://www.phusionpassenger.com/) est un serveur d'application qui propose des fonctionnalités avancées. On peut l'installer sous forme de Gem pour le développement : ~~~ $ gem install passenger $ passenger start =============== Phusion Passenger Standalone web server started =============== Environment: development Accessible via: http://0.0.0.0:3000/ You can stop Phusion Passenger Standalone by pressing Ctrl-C. ~~~ On peut l'installer pour [Apache](HowtoApache) ainsi : ~~~ # apt install libapache2-mod-passenger ~~~ 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` ainsi que d'autres ajustements : ~~~ PassengerRoot /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini PassengerDefaultRuby /usr/bin/ruby # On ajoute les lignes suivantes: PassengerEnabled off RailsAutoDetect off RackAutoDetect off PassengerFriendlyErrorPages off PassengerTempDir /var/tmp/ PassengerUploadBufferDir /var/tmp # S'assurer que les permissions sur le dossier permettent à Apache d'écrire dedans # cf. # C'est surtout important avec Apache ITK ! ~~~ > *Note* : 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`. Et voici un VirtualHost minimal pour Apache : ~~~ ServerName foo.example.com PassengerEnabled on RailsAutoDetect on #RailsEnv development DocumentRoot /home/foo/www/current Allow from all Options -MultiViews # Pour Apache ITK AssignUserID foo foo ~~~ > *Note* : 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. Pour Apache ITK, il faut donc y placer un propriétaire identique à celui utilisé dans `AssignUserID`. > *Note* : par défaut, Passenger fait tourner l'application en mode *production*. On peut forcer un certain environnement en ajustant la directive `RailsEnv` dans le VirtualHost. ## FAQ ### GEM_HOME On peut forcer l'environnement des Gems (pour ignorer `/var/lib/gems/2.3.0` par exemple) : ~~~ $ export GEM_HOME=/$HOME/.gem/ruby/2.3.0 ~~~ ### rbenv via Github Si l'on souhaite installer rbenv sans utiliser le paquet Debian, il suffit de commencer la procédure ainsi : ~~~ $ git clone git://github.com/sstephenson/rbenv.git .rbenv $ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build $ eval "$(rbenv init -)" $ rbenv install --list ~~~ puis de suivre les instructions [décrites plus haut](HowtoRails#installation-avec-rbenv) ### Ruby Enterprise Edition (REE) [REE](http://rubyenterpriseedition.com/) est une version patchée de Ruby optimisée pour les applications Web et créée par les mêmes développeurs que Passenger. On peut l'installer en le compilant à la main (par défaut il s'installera dans e dossier `/opt` en totale isolation du reste du système) Il suffit de récupérer [les sources](http://rubyenterpriseedition.com/download.html), 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. Les dépendances classiques de compilations seront nécessaires (`apt install build-essential libssl-dev libreadline-dev zlib1g-dev`). Si l'on utilise avec Passenger, on pourra forcer l'utilisation de REE ainsi : ~~~ PassengerRoot /opt/ruby-enterprise-/lib/ruby/gems/1.8/gems/passenger-3.0.0 PassengerRuby /opt/ruby-enterprise-/bin/ruby ~~~ ### 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 (un script `list_gems` doit traîner dans un coin…). ### É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 ~~~ ### rails_env ~~~ rails_env = `head -1 $(HOME}/www/current/config/database.yml | tr ':' ' '` ~~~ ### 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).