Dernière mise à jour le 08 mai 2018
Rails 5.2 a introduit le stockage actif comme moyen de gérer l’attachement et l’enregistrement de fichiers à des modèles d’enregistrements actifs. Ce guide expliquera comment utiliser le stockage actif sur Heroku.
Disque éphémère
Heroku a un disque dur « éphémère », cela signifie que vous pouvez écrire des fichiers sur le disque, mais ces fichiers ne persisteront pas après le redémarrage de l’application. Par défaut, le stockage actif utilise une option de stockage :local
, qui utilise le système de fichiers local pour stocker tous les fichiers téléchargés. Alors que les téléchargements de fichiers stockés avec l’option :local
sembleront fonctionner au début, les pièces jointes présenteront un comportement apparemment étrange et finiront par disparaître. Les fichiers disparaîtront lorsque l’application sera déployée ou lorsqu’elle sera automatiquement redémarrée (une fois toutes les 24 heures). Si l’application a plusieurs dynos, tous les fichiers ne seront pas présents sur chaque dyno. Cela signifie que le dyno qui sert une requête Web peut être différent d’un dyno qui contient un fichier téléchargé spécifique. Par exemple, si vous avez deux dynos et que vous téléchargez un fichier, il ne sera présent que sur un dyno. Lorsque vous actualisez la page Web, il y aura 50% de chances que la demande Web soit acheminée vers le dyno avec le fichier, et 50% de chances qu’elle semble être cassée. De plus, tous les fichiers stockés sur le disque ne seront pas visibles à partir de dynos uniques tels qu’une instance heroku run bash
ou une tâche de planificateur car ces commandes utilisent de nouveaux dynos.
Au lieu de stocker les fichiers téléchargés sur le disque, la meilleure pratique consiste à tirer parti d’un service de stockage de fichiers dans le cloud tel que S3 d’Amazon.
Pour utiliser un autre backend de stockage, vous devrez modifier le fichier config/storage.yml
. Si vous utilisez l’addon bucketeer pour gérer S3 pour vous, vous pouvez l’ajouter à votre config/storage.yml
:
amazon: service: S3 access_key_id: <%= ENV %> secret_access_key: <%= ENV %> region: <%= ENV %> bucket: <%= ENV %>
Une fois cela fait, vous devrez indiquer à votre application d’utiliser ce backend de stockage en production. Dans votre config/environments/production.rb
, assurez-vous que vous avez défini votre service de stockage actif sur amazon:
config.active_storage.service = :amazon
Enfin, vous devez également inclure la gemme AWS. Ajoutez ceci à votre Gemfile
:
gem "aws-sdk-s3", require: false
N’oubliez pas d’exécuter cette commande localement:
$ bundle install
Validez ensuite vos fichiers sur git avant d’essayer de les déployer sur Heroku.
Aperçus de pièces jointes
L’une des caractéristiques marquantes du stockage actif est la possibilité d’utiliser des « aperçus » de pièces jointes sans image. Plus précisément, vous pouvez prévisualiser des PDF et des vidéos. Pour utiliser cette fonctionnalité, votre application a besoin d’accéder aux ressources système qui savent comment travailler avec ces fichiers. Par défaut, Rails est livré avec le support avec poppler
pour les aperçus PDF et ffmpeg
pour les aperçus vidéo. Ces dépendances système ne sont pas disponibles par défaut sur Heroku.
Si vous souhaitez avoir la possibilité de prévisualiser ces types de fichiers avec un support actif, vous devez exécuter:
$ heroku buildpacks:add -i 1 https://github.com/heroku/heroku-buildpack-activestorage-preview
Une fois cela fait, vous devez déployer à nouveau pour obtenir les binaires. Vous pouvez vérifier que les dépendances sont installées en exécutant which ffmpeg
sur la ligne de commande. S’il n’y a pas de sortie, l’opération n’a pas été effectuée correctement. Si vous voyez un résultat, les binaires sont prêts à être utilisés:
$ heroku run bash~$ which ffmpeg/app/.heroku/activestorage-preview/usr/bin/ffmpeg
Si vous essayez de prévisualiser un PDF sans poppler
, la page sera une erreur et vous le verrez dans vos journaux:
ActionView::Template::Error (ActiveStorage::UnpreviewableError)
Si vous essayez de prévisualiser une vidéo sans ffmpeg
, l’aperçu apparaîtra comme cassé et vous verrez une erreur comme celle-ci dans vos journaux:
Errno::ENOENT (No such file or directory - ffmpeg):