mirroir readonly du Gitit wiki.evolix.org (attention, ne rien commiter/merger sur ce dépôt) https://wiki.evolix.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HowtoRails.md 15 KiB

2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. ---
  2. categories: web
  3. title: Howto Rails
  4. ...
  5. * Documentation : <https://guides.rubyonrails.org/>
  6. * YAML Cookbook for Ruby : <http://www.yaml.org/YAML_for_ruby.html>
  7. * Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/show/rbenv>
  8. [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/).
  9. ## Installation
  10. ### Installation avec rbenv
  11. [rbenv](https://github.com/rbenv/rbenv) permet d'avoir un environnement compilé par utilisateur.
  12. C'est donc le développeur qui gère sa version de Ruby, ses Gems, etc... on ne lui installe même pas Ruby !
  13. > *Note* : vous devez mettre les droits `exec` sur la partition */home* pour cette installation
  14. ~~~
  15. # apt install rbenv build-essential libssl-dev libreadline-dev zlib1g-dev
  16. # apt install liblzma-dev libmariadbclient-dev
  17. $ eval "$(rbenv init -)"
  18. $ mkdir ~/.rbenv/plugins
  19. $ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
  20. $ rbenv install --list
  21. $ TMPDIR=~/tmp rbenv install 2.5.1
  22. $ rbenv global 2.5.1
  23. $ gem install bundler rails
  24. $ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  25. $ ruby -v
  26. ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
  27. $ gem list
  28. *** LOCAL GEMS ***
  29. actioncable (5.2.1)
  30. actionmailer (5.2.1)
  31. actionpack (5.2.1)
  32. actionview (5.2.1)
  33. activejob (5.2.1)
  34. activemodel (5.2.1)
  35. activerecord (5.2.1)
  36. activestorage (5.2.1)
  37. activesupport (5.2.1)
  38. arel (9.0.0)
  39. bigdecimal (default: 1.3.4)
  40. builder (3.2.3)
  41. bundle (0.0.1)
  42. bundler (1.16.3)
  43. […]
  44. ~~~
  45. ### Installation avec ruby système
  46. Cela permet de bénéficier des mises à jour de sécurité de Ruby, tout en gérant les Gems par utilisateur.
  47. ~~~
  48. # apt install ruby ruby-dev ruby-bundler
  49. # apt install liblzma-dev libmariadbclient-dev
  50. $ export PATH="$HOME/.gem/ruby/2.3.0/bin:$PATH"
  51. $ gem install bundler
  52. $ echo 'PATH="$HOME/.gem/ruby/2.3.0/bin:$PATH"' >> ~/.bashrc
  53. $ ruby -v
  54. ruby 2.3.3p222 (2016-11-21) [x86_64-linux-gnu]
  55. $ gem list
  56. *** LOCAL GEMS ***
  57. actionmailer (4.2.7.1)
  58. actionpack (4.2.7.1)
  59. actionview (4.2.7.1)
  60. activejob (4.2.7.1)
  61. activemodel (4.2.7.1)
  62. activerecord (4.2.7.1)
  63. activesupport (4.2.7.1)
  64. arel (6.0.3)
  65. atomic (1.1.16)
  66. bigdecimal (1.2.8)
  67. binding_of_caller (0.7.2)
  68. blankslate (3.1.3)
  69. builder (3.2.2)
  70. bundle (0.0.1)
  71. bundler (1.16.3, 1.13.6)
  72. […]
  73. ~~~~
  74. ## Utilisation
  75. ### Démarrer un projet Rails
  76. <https://guides.rubyonrails.org/getting_started.html>
  77. ~~~
  78. $ rails --version
  79. Rails 4.2.7.1
  80. $ rails new foo
  81. $ cd foo
  82. ~~~
  83. On peut alors ajuster la configuration (routes, base de données, etc.), coder son projet, le stocker dans un repository Git, etc.
  84. Pour voir en local le résultat :
  85. ~~~
  86. $ cd foo
  87. $ ./bin/rails server
  88. => Booting WEBrick
  89. => Rails 4.2.7.1 application starting in development on http://localhost:3000
  90. => Run `rails server -h` for more startup options
  91. => Ctrl-C to shutdown server
  92. [2018-08-12 11:43:15] INFO WEBrick 1.3.1
  93. [2018-08-12 11:43:15] INFO ruby 2.3.3 (2016-11-21) [x86_64-linux-gnu]
  94. [2018-08-12 11:43:15] INFO WEBrick::HTTPServer#start: pid=12383 port=3000
  95. ~~~
  96. On peut alors le visualiser sur <http://127.0.0.1:3000>
  97. ### Les environnements de Rails
  98. Rails propose trois environnements d'exécution distincts·: `production`, `development` et `test`.
  99. Chacun a un but précis facilement devinable depuis son nom.
  100. Pour lancer dans un certain environnement les commandes qui agissent avec l'application (par exemple les
  101. tâches [Rake](http://guides.rubyonrails.org/command_line.html#rake-is-ruby-make)), il suffit de définir la
  102. variable d'environnement RAILS_ENV, par exemple·:
  103. ~~~
  104. $ RAILS_ENV=production rake db:migrate
  105. ~~~
  106. ### Redémarrage optimisé
  107. Pour redémarrer une application Rails de façon optimisée, il suffit de créer ou de mettre à jour le timestamp du fichier
  108. `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.
  109. 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.
  110. ### Unité systemd
  111. TODO, cf https://wiki.evolix.org/HowtoSystemd#systemd-par-utilisateur
  112. ### Les Gems et Bundler
  113. Les [Gems](https://rubygems.org/) sont des paquets contentant des librairies et/ou des applications écrites en Ruby.
  114. Elles sont souvent utilisées, notamment dans Rails.
  115. ~~~
  116. $ gem -v
  117. 2.5.2.1
  118. $ gem list
  119. $ gem env
  120. RubyGems Environment:
  121. - RUBYGEMS VERSION: 2.5.2.1
  122. - RUBY VERSION: 2.3.3 (2016-11-21 patchlevel 222) [x86_64-linux-gnu]
  123. […]
  124. ~~~
  125. Les Gems peuvent se trouver à plusieurs endroits :
  126. * installée par un paquet Debian (`/usr/lib/ruby/2.3.0/`)
  127. * installée en temps que Gem système (`/var/lib/gems/2.3.0/`)
  128. * installée en temps que Gem utilisateur (`~/.gem/ruby/2.3.0/`)
  129. Une application Rails contient un fichier `Gemfile` qui précise les Gems nécessaires et leurs versions :
  130. ~~~
  131. source 'https://rubygems.org'
  132. # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
  133. gem 'rails', '4.2.7.1'
  134. # Use sqlite3 as the database for Active Record
  135. gem 'sqlite3'
  136. # Use SCSS for stylesheets
  137. gem 'sass-rails', '~> 5.0'
  138. # Use Uglifier as compressor for JavaScript assets
  139. gem 'uglifier', '>= 1.3.0'
  140. […]
  141. ~~~
  142. [Bundler](https://bundler.io/) est l'outil de prédilection pour installer les Gems nécessaires.
  143. Avec la présence d'un fichier `Gemfile`, il suffit de lancer la commande :
  144. ~~~
  145. $ bundle install
  146. ~~~
  147. 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.
  148. En général, on inclut les fichiers `Gemfile` et `Gemfile.lock` dans le repository du projet.
  149. ### Capistrano
  150. [Capistrano](https://capistranorb.com/) est un outil de déploiement particulièrement adapté aux développements en Ruby (dont Rails) mais parfaitement compatible avec d'autres langages ou frameworks (PHP, Java…).
  151. Il est généralement exécuté depuis un poste de développement ou d'intégration. Il se connecte alors en SSH à un ou plusieurs serveurs (via SSH) pour y exécuter des tâches selon les rôles du serveur (application, base de données…).
  152. Il est recommandé d'installer Capistrano via Bundler (dans le cadre d'un projet), mais il est évidemment possible de l'utiliser indépendamment (`# gem install capistrano`). Sa commande principale est `cap`.
  153. À l'initialisation, Capistrano créé plusieurs fichiers, dont ceux nécessaires à gérer plusieurs envvironnements (production, staging…) :
  154. ~~~
  155. ├── Capfile
  156. ├── config
  157. │ ├── deploy
  158. │ │ ├── production.rb
  159. │ │ └── staging.rb
  160. │ └── deploy.rb
  161. └── lib
  162. └── capistrano
  163. └── tasks
  164. ~~~
  165. * `Capfile` est lu par l'exécutable au chargement pour déterminer les modules à charger ;
  166. * `config/deploy.rb` contient la configuration générale ;
  167. * `config/deploy/*.rb` contiennent les particularités de chaque environnement ;
  168. * `lib/capistrano/tasks/*` permet de créer ses propres tâches à exécuter lors du déploiement.
  169. Il existe de nombreux modules additionnels pour Capistrano afin d'apporter le support de frameworks ou bibliothèques : rails, rbenv, sidekiq, whenever… Il s'agit de gems à installer manuellement ou via Bundler.
  170. Capistrano s'appuie massivement sur Rake, qui est une implémentation en Ruby du principe de Make (et des Makefile). Tout se passe donc sous forme de taches exécutées dans un ordre défini par un arbre de dépendance. De fait toutes les tâches peuvent être surchargées pour en personnaliser l'exécution.
  171. Dans la plupart des cas (surtout avec Rails ou d'autres frameworks supportés) le déploiement en production se fait via la commande `[bundle exec] cap production deploy`. Un déploiement classique d'application Rails va faire :
  172. * mise à jour du code source (via Git)
  173. * création d'une "release" avec copie du code, liaison de fichiers/dossiers clés…
  174. * pré-compilation des assets (images, JS, CSS…)
  175. * migration de la base de données
  176. * activation de la release
  177. * relance du serveur d'application
  178. ## Serveur web
  179. Pour une utilisation en production d'une application Rails, on peut utiliser plusieurs solutions : Puma, Unicorn, Passenger, etc.
  180. ### Puma
  181. [Puma](http://puma.io/) est un serveur web pour Ruby orienté pour la performance et le traitement en parallèle.
  182. Il peut s'installer par package (`apt install puma`) ou par Gem.
  183. ~~~
  184. $ gem install puma
  185. $ cd projet
  186. $ puma -S puma.state -b tcp://127.0.0.1:3042 -b unix:///tmp/puma.sock
  187. Puma starting in single mode...
  188. * Version 3.6.0 (ruby 2.3.3-p222), codename: Sleepy Sunday Serenity
  189. * Min threads: 5, max threads: 5
  190. * Environment: development
  191. * Listening on tcp://127.0.0.1:3042
  192. * Listening on unix:///tmp/puma.sock
  193. Use Ctrl-C to stop
  194. ^C- Gracefully stopping, waiting for requests to finish
  195. === puma shutdown: 2018-08-25 23:15:36 +0200 ===
  196. - Goodbye!
  197. ~~~
  198. On peut également créer un fichier de paramètres *puma.rb* que l'on indiquera via `-F puma.rb` :
  199. ~~~
  200. #!/usr/bin/env puma
  201. directory '/home/foo/project'
  202. environment 'production'
  203. bind 'unix:///tmp/puma.sock'
  204. port ENV.fetch("PORT") { 3042 }
  205. […]
  206. ~~~
  207. On peut créer des unités systemd pour gérer cela : <https://github.com/puma/puma/blob/master/docs/systemd.md>
  208. ### Unicorn
  209. [Unicorn](https://bogomips.org/unicorn/) est un serveur web pour applications Rack conçu pour les clients rapides et optimisé pour Unix.
  210. Il peut s'installer par package (`apt install unicorn`) ou par Gem.
  211. ~~~
  212. $ gem install unicorn
  213. $ cd projet
  214. $ unicorn -l 127.0.0.1:3042
  215. I, [2018-08-26T00:05:09.967114 #2133] INFO -- : listening on addr=127.0.0.1:3042 fd=9
  216. I, [2018-08-26T00:05:09.967275 #2133] INFO -- : worker=0 spawning...
  217. I, [2018-08-26T00:05:09.967786 #2133] INFO -- : master process ready
  218. I, [2018-08-26T00:05:09.968015 #2135] INFO -- : worker=0 spawned pid=2135
  219. I, [2018-08-26T00:05:09.968129 #2135] INFO -- : Refreshing Gem list
  220. […]
  221. ~~~
  222. ### Passenger
  223. [Passenger](https://www.phusionpassenger.com/) est un serveur d'application qui propose des fonctionnalités avancées.
  224. On peut l'installer sous forme de Gem pour le développement :
  225. ~~~
  226. $ gem install passenger
  227. $ cd projet
  228. $ passenger start
  229. =============== Phusion Passenger Standalone web server started ===============
  230. Environment: development
  231. Accessible via: http://0.0.0.0:3000/
  232. You can stop Phusion Passenger Standalone by pressing Ctrl-C.
  233. ~~~
  234. On peut l'installer pour [Apache](HowtoApache) ainsi :
  235. ~~~
  236. # apt install libapache2-mod-passenger
  237. ~~~
  238. 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 :
  239. ~~~
  240. <IfModule mod_passenger.c>
  241. PassengerRoot /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini
  242. PassengerDefaultRuby /usr/bin/ruby
  243. # On ajoute les lignes suivantes:
  244. PassengerEnabled off
  245. RailsAutoDetect off
  246. RackAutoDetect off
  247. PassengerFriendlyErrorPages off
  248. PassengerTempDir /var/tmp/
  249. PassengerUploadBufferDir /var/tmp
  250. # S'assurer que les permissions sur le dossier permettent à Apache d'écrire dedans
  251. # cf. http://modrails.com/documentation/Users%20guide%20Apache.html#PassengerUploadBufferDir
  252. # C'est surtout important avec Apache ITK !
  253. </IfModule>
  254. ~~~
  255. > *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`.
  256. Et voici un VirtualHost minimal pour Apache :
  257. ~~~
  258. <VirtualHost>
  259. ServerName foo.example.com
  260. PassengerEnabled on
  261. RailsAutoDetect on
  262. #RailsEnv development
  263. DocumentRoot /home/foo/www/current
  264. <Directory /home/redmine/www/current>
  265. Allow from all
  266. Options -MultiViews
  267. </Directory>
  268. # Pour Apache ITK
  269. AssignUserID foo foo
  270. </VirtualHost>
  271. ~~~
  272. > *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`.
  273. > *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.
  274. ## FAQ
  275. ### GEM_HOME
  276. On peut forcer l'environnement des Gems (pour ignorer `/var/lib/gems/2.3.0` par exemple) :
  277. ~~~
  278. $ export GEM_HOME=/$HOME/.gem/ruby/2.3.0
  279. ~~~
  280. ### rbenv via Github
  281. Si l'on souhaite installer rbenv sans utiliser le paquet Debian, il suffit de commencer la procédure ainsi :
  282. ~~~
  283. $ git clone git://github.com/sstephenson/rbenv.git .rbenv
  284. $ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
  285. $ eval "$(rbenv init -)"
  286. $ rbenv install --list
  287. ~~~
  288. puis de suivre les instructions [décrites plus haut](HowtoRails#installation-avec-rbenv)
  289. ### Ruby Enterprise Edition (REE)
  290. <http://rubyenterpriseedition.com/documentation.html>
  291. [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.
  292. 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)
  293. 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.
  294. Les dépendances classiques de compilations seront nécessaires (`apt install build-essential libssl-dev libreadline-dev zlib1g-dev`).
  295. Si l'on utilise avec Passenger, on pourra forcer l'utilisation de REE ainsi :
  296. ~~~
  297. <IfModule passenger_module>
  298. PassengerRoot /opt/ruby-enterprise-<version>/lib/ruby/gems/1.8/gems/passenger-3.0.0
  299. PassengerRuby /opt/ruby-enterprise-<version>/bin/ruby
  300. </IfModule>
  301. ~~~
  302. ### Lister les Gems
  303. Il n'existe pas de moyen de lister les Gems installées uniquement sur le système, la commande `gem` cherche
  304. à la fois dans le dossier `.gem` de l'utilisateur et le dossier système. La solution est d'utiliser un script
  305. spécialisé qui fait cette recherche (un script `list_gems` doit traîner dans un coin…).
  306. ### Économiser un peu d'espace
  307. Par défaut, `gem` installe la documentation aux formats RDoc (documentation html) et RI (documentation console)
  308. pour les Gems installées. Pour éviter celà, créer un fichier `.gemrc` dans la `$HOME` de l'utilisateur avec le
  309. contenu suivant :
  310. ~~~
  311. gem: --no-rdoc --no-ri
  312. ~~~
  313. ### rails_env
  314. ~~~
  315. rails_env = `head -1 $(HOME}/www/current/config/database.yml | tr ':' ' '`
  316. ~~~
  317. ### Rails 2.3.2->2.3.5 & Passenger & les logs
  318. 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).