410 lines
13 KiB
Markdown
410 lines
13 KiB
Markdown
---
|
|
categories: web
|
|
title: Howto Rails
|
|
...
|
|
|
|
* Documentation : <https://guides.rubyonrails.org/>
|
|
* YAML Cookbook for Ruby : <http://www.yaml.org/YAML_for_ruby.html>
|
|
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/show/rbenv>
|
|
|
|
[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
|
|
|
|
<https://guides.rubyonrails.org/getting_started.html>
|
|
|
|
~~~
|
|
$ 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 <http://127.0.0.1:3000>
|
|
|
|
### 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 un serveur web pour Ruby orienté pour la performance et le traitement en parallèle.
|
|
Il peut s'installer par package (`apt install puma`) ou par Gem.
|
|
|
|
~~~
|
|
$ gem install puma
|
|
|
|
$ cd projet
|
|
$ puma -S puma.state -b tcp://127.0.0.1:3042 -b unix:///tmp/puma.sock
|
|
Puma starting in single mode...
|
|
* Version 3.6.0 (ruby 2.3.3-p222), codename: Sleepy Sunday Serenity
|
|
* Min threads: 5, max threads: 5
|
|
* Environment: development
|
|
* Listening on tcp://127.0.0.1:3042
|
|
* Listening on unix:///tmp/puma.sock
|
|
Use Ctrl-C to stop
|
|
|
|
^C- Gracefully stopping, waiting for requests to finish
|
|
=== puma shutdown: 2018-08-25 23:15:36 +0200 ===
|
|
- Goodbye!
|
|
~~~
|
|
|
|
On peut également créer un fichier de paramètres *puma.rb* que l'on indiquera via `-F puma.rb` :
|
|
|
|
~~~
|
|
#!/usr/bin/env puma
|
|
|
|
directory '/home/foo/project'
|
|
environment 'production'
|
|
bind 'unix:///tmp/puma.sock'
|
|
port ENV.fetch("PORT") { 3042 }
|
|
[…]
|
|
~~~
|
|
|
|
On peut créer des unités systemd pour gérer cela : <https://github.com/puma/puma/blob/master/docs/systemd.md>
|
|
|
|
### Unicorn
|
|
|
|
[Unicorn](https://bogomips.org/unicorn/) est un serveur web pour applications Rack conçu pour les clients rapides et optimisé pour Unix.
|
|
Il peut s'installer par package (`apt install unicorn`) ou par Gem.
|
|
|
|
~~~
|
|
$ gem install unicorn
|
|
|
|
$ cd projet
|
|
$ unicorn -l 127.0.0.1:3042
|
|
I, [2018-08-26T00:05:09.967114 #2133] INFO -- : listening on addr=127.0.0.1:3042 fd=9
|
|
I, [2018-08-26T00:05:09.967275 #2133] INFO -- : worker=0 spawning...
|
|
I, [2018-08-26T00:05:09.967786 #2133] INFO -- : master process ready
|
|
I, [2018-08-26T00:05:09.968015 #2135] INFO -- : worker=0 spawned pid=2135
|
|
I, [2018-08-26T00:05:09.968129 #2135] INFO -- : Refreshing Gem list
|
|
[…]
|
|
~~~
|
|
|
|
### Passenger
|
|
|
|
[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
|
|
|
|
$ cd projet
|
|
$ 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 :
|
|
|
|
~~~
|
|
<IfModule mod_passenger.c>
|
|
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. http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerUploadBufferDir
|
|
# C'est surtout important avec Apache ITK !
|
|
</IfModule>
|
|
~~~
|
|
|
|
> *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 :
|
|
|
|
~~~
|
|
<VirtualHost>
|
|
ServerName foo.example.com
|
|
PassengerEnabled on
|
|
RailsAutoDetect on
|
|
#RailsEnv development
|
|
|
|
DocumentRoot /home/foo/www/current
|
|
<Directory /home/redmine/www/current>
|
|
Allow from all
|
|
Options -MultiViews
|
|
</Directory>
|
|
|
|
# Pour Apache ITK
|
|
AssignUserID foo foo
|
|
</VirtualHost>
|
|
~~~
|
|
|
|
> *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)
|
|
|
|
<http://rubyenterpriseedition.com/documentation.html>
|
|
|
|
[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 :
|
|
|
|
~~~
|
|
<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
|
|
</IfModule>
|
|
~~~
|
|
|
|
### 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).
|
|
|
|
|