Ce sujet explique comment configurer certains fournisseurs de stockage d’objets compatibles S3 (clones S3). Consultez Set up file and image uploads to S3 pour plus de détails sur la configuration d’Amazon AWS S3, qui est officiellement prise en charge et utilisée en interne par Discourse pour nos services d’hébergement.
| Fournisseur | Nom du service | Fonctionne avec Discourse ? |
|---|---|---|
| Amazon AWS | S3 | Oui |
| Digital Ocean | Spaces | Oui |
| Linode | Object Storage | Oui |
| Google Cloud | Storage | Oui |
| Scaleway | Object Storage | Oui |
| Vultr | Object Storage | Oui |
| BackBlaze | Cloud Storage | Oui* |
| Auto-hébergé | MinIO | Oui |
| Azure Blob Storage | Flexify.IO | Oui |
| Oracle Cloud | Object Storage | Non [1] |
| Wasabi | Object Storage | Peut-être |
| Cloudflare | R2 | Oui |
| Contabo | Object Storage | Non |
Si vous avez réussi à faire fonctionner un autre service, veuillez l’ajouter à cette wiki.
Configuration
Pour stocker les actifs statiques de Discourse dans votre stockage d’objets, ajoutez cette configuration dans votre fichier app.yml sous la section hooks :
after_assets_precompile:
- exec:
cd: $home
cmd:
- sudo -E -u discourse bundle exec rake s3:upload_assets
- sudo -E -u discourse bundle exec rake s3:expire_missing_assets
Lors de l’utilisation d’un stockage d’objets, vous avez également besoin d’un CDN pour servir ce qui est stocké dans le bucket. J’ai utilisé le CDN StackPath lors de mes tests, et à part avoir besoin de définir Dynamic Caching By Header: Accept-Encoding dans leur configuration, cela fonctionne correctement.
DISCOURSE_CDN_URL est un CDN qui pointe vers le nom d’hôte de votre Discourse et met en cache les requêtes. Il sera utilisé principalement pour les actifs récupérables (pullable) : CSS et autres actifs de thème.
DISCOURSE_S3_CDN_URL est un CDN qui pointe vers votre bucket de stockage d’objets et met en cache les requêtes. Il sera principalement utilisé pour les actifs poussables (pushable) : JS, images et uploads d’utilisateurs.
Nous recommandons qu’ils soient différents et que les administrateurs définissent les deux.
Ne pas utiliser de CDN (ou entrer l’URL du bucket comme URL du CDN) est susceptible de causer des problèmes et n’est pas pris en charge.
Dans les exemples suivants, https://falcoland-files-cdn.falco.dev est un CDN configuré pour servir les fichiers sous le bucket. Le nom du bucket a été défini sur falcoland-files dans mes exemples.
La configuration de ces paramètres dans les variables d’environnement de votre app.yml est recommandée car c’est ainsi que CDCK le fait dans leur infrastructure, ce qui est donc bien testé. De plus, la tâche de téléchargement des actifs a lieu après la compilation des actifs, ce qui se produit lors d’une reconstruction (rebuild). Si vous souhaitez lancer un Discourse qui fonctionne correctement avec le stockage d’objets dès le début, vous devez définir les variables d’environnement afin que les actifs soient téléchargés avant le démarrage du site.
Choisissez votre fournisseur dans la liste ci-dessous et ajoutez ces paramètres à la section env de votre fichier app.yml, en ajustant les valeurs en conséquence :
AWS S3
Ce que nous prenons officiellement en charge et utilisons en interne. Leur offre CDN Cloudfront fonctionne également pour servir les fichiers du bucket. Consultez Set up file and image uploads to S3 pour savoir comment configurer correctement les permissions.
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: us-west-1
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backups
DISCOURSE_BACKUP_LOCATION: s3
Digital Ocean Spaces
L’offre de DO est bonne et fonctionne immédiatement. Il est possible d’activer la restriction de la liste des fichiers. Le seul problème est que leur offre CDN est très mal conçue, vous devez donc utiliser un autre CDN pour les fichiers. De plus, vous ne devez pas installer la règle CORS, car elle se réinstalle à chaque reconstruction.
Exemple de configuration :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: whatever
DISCOURSE_S3_ENDPOINT: https://nyc3.digitaloceanspaces.com
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backups
DISCOURSE_BACKUP_LOCATION: s3
DISCOURSE_S3_INSTALL_CORS_RULE: false
Linode Object Storage
Un paramètre de configuration supplémentaire, HTTP_CONTINUE_TIMEOUT, est requis pour Linode.
Exemple de configuration :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: us-east-1
DISCOURSE_S3_HTTP_CONTINUE_TIMEOUT: 0
DISCOURSE_S3_ENDPOINT: https://us-east-1.linodeobjects.com
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backup
DISCOURSE_BACKUP_LOCATION: s3
Google Cloud Platform Storage
La liste des fichiers est cassée, vous avez donc besoin d’une variable ENV supplémentaire pour la contourner afin que les actifs fonctionnent. Contournez également CORS et configurez-le manuellement.
Comme vous ne pouvez pas lister les fichiers, vous ne pourrez pas lister les sauvegardes, et les sauvegardes automatiques échoueront ; nous ne recommandons pas de l’utiliser pour les sauvegardes. Cependant, certains suggèrent que si vous changez le rôle de Storage Legacy Object Owner à Storage Legacy Bucket Owner, les sauvegardes fonctionnent correctement. Consultez ce sujet pour une discussion spécifique à Google Cloud.
Il existe un plugin tiers pour améliorer l’intégration sur Discourse GCS Helper.
Exemple de configuration :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: us-east1
DISCOURSE_S3_INSTALL_CORS_RULE: false
FORCE_S3_UPLOADS: 1
DISCOURSE_S3_ENDPOINT: https://storage.googleapis.com
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
#DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backup
#DISCOURSE_BACKUP_LOCATION: s3
Scaleway Object Storage
L’offre Scaleway est également très bonne, et tout fonctionne bien dans la plupart des cas.
Les uploads multipart de Scaleway ne supportent qu’un maximum de 1 000 parties. Cela ne correspond pas à Amazon S3, qui supporte un maximum de 10 000 parties. Pour les instances plus grandes, cela causera l’échec des sauvegardes Discourse et l’upload incomplet devra peut-être être supprimé manuellement avant de nouvelles tentatives. Pour les petites instances, ce n’est pas un problème. Scaleway semble assez ouvert aux retours, donc si vous souhaitez que cette limite soit modifiée, vous devriez les contacter.
Notez que pour le paramètre DISCOURSE_S3_ENDPOINT, Discourse utilise l’endpoint de la région entière : https://s3.{region}.scw.cloud. L’“Endpoint du bucket” trouvé dans votre tableau de bord Scaleway est sous la forme https://{bucketName}.s3.{region}.scw.cloud. Omettez le sous-domaine du nom du bucket pour éviter les erreurs de connexion.
Exemple de configuration :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: fr-par
DISCOURSE_S3_ENDPOINT: https://s3.fr-par.scw.cloud
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backups
DISCOURSE_BACKUP_LOCATION: s3
Vultr Object Storage
Un paramètre de configuration supplémentaire, HTTP_CONTINUE_TIMEOUT, est requis pour Vultr.
Exemple de configuration :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: whatever
DISCOURSE_S3_HTTP_CONTINUE_TIMEOUT: 0
DISCOURSE_S3_ENDPOINT: https://ewr1.vultrobjects.com
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backup
DISCOURSE_BACKUP_LOCATION: s3
Backblaze B2 Cloud Storage
Vous devez contourner CORS et le configurer manuellement.
Il y a des rapports indiquant que le nettoyage des uploads orphelins ne fonctionne pas correctement avec BackBlaze. Vous devez modifier les règles de cycle de vie de votre bucket pour que le nettoyage des orphelins fonctionne.
Exemple de configuration :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: "us-west-002"
DISCOURSE_S3_INSTALL_CORS_RULE: false
DISCOURSE_S3_CONFIGURE_TOMBSTONE_POLICY: false
DISCOURSE_S3_ENDPOINT: https://s3.us-west-002.backblazeb2.com
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://falcoland-files-cdn.falco.dev
DISCOURSE_S3_BUCKET: falcoland-files
DISCOURSE_S3_BACKUP_BUCKET: falcoland-files/backup
DISCOURSE_BACKUP_LOCATION: s3
Remarque : Lors de la migration initiale vers B2, vous pouvez atteindre la limite de 2500 transactions de classe C gratuites par jour. Vous devrez ajouter un moyen de paiement pour lever les plafonds.
MinIO Storage Server
Il y a quelques avertissements et exigences que vous devez vous assurer d’avoir respectés avant de pouvoir utiliser le serveur de stockage MinIO comme alternative à S3 :
- Vous disposez d’une instance de serveur MinIO entièrement configurée
- Vous avez activé le support de domaine dans la configuration MinIO, pour les URLs de buckets basées sur les domaines. C’est une exigence de configuration obligatoire pour MinIO et Discourse, car MinIO supporte encore les styles “path” S3 legacy qui ne sont plus supportés dans Discourse.
- Vous avez correctement configuré le DNS pour MinIO afin que les sous-domaines des buckets résolvent correctement vers le serveur MinIO et que le serveur MinIO soit configuré avec un domaine de base (dans ce cas,
minio.example.com) - Le bucket
discourse-dataexiste sur le serveur MinIO et a une politique “publique” définie dessus - Votre URL CDN S3 pointe vers un CDN correctement configuré pointant vers le bucket et mettant en cache les requêtes, comme indiqué plus haut dans ce document.
- Vos CDNs sont configurés pour utiliser réellement un en-tête “Host” de l’URL S3 de base - par exemple,
discourse-data.minio.example.comlorsqu’il récupère les données - sinon cela peut causer des problèmes CORB.
En supposant que les avertissements et prérequis ci-dessus sont respectés, une configuration exemple serait quelque chose comme ceci :
DISCOURSE_USE_S3: true
DISCOURSE_S3_REGION: anything
DISCOURSE_S3_ENDPOINT: https://minio.example.com
DISCOURSE_S3_ACCESS_KEY_ID: myaccesskey
DISCOURSE_S3_SECRET_ACCESS_KEY: mysecretkey
DISCOURSE_S3_CDN_URL: https://discourse-data-cdn.example.com
DISCOURSE_S3_BUCKET: discourse-data
DISCOURSE_S3_BACKUP_BUCKET: discourse-backups
DISCOURSE_BACKUP_LOCATION: s3
DISCOURSE_S3_INSTALL_CORS_RULE: false
CORS sera toujours activé sur MinIO même si la règle n’est pas installée par le recompileur d’application - par défaut, il semble, CORS est activé sur tous les verbes HTTP dans MinIO, et MinIO ne supporte pas BucketCORS (API S3) par conséquent.
Azure Blob Storage avec Flexify.IO
Azure Blob Storage n’est pas un service compatible S3, il ne peut donc pas être utilisé avec Discourse. Il existe un plugin, mais il est cassé.
La façon la plus simple d’exposer une interface compatible S3 pour Azure Blob Storage est d’ajouter un serveur Flexify.IO qui traduit le protocole de stockage Azure en S3.
À ce jour, le service est gratuit sur Azure, et vous n’avez besoin que d’une couche VM très basique (bon marché) pour commencer à l’exécuter. Cela nécessite cependant un peu de configuration.
- Dans le portail Azure, créez une nouvelle ressource de type
Flexify.IO - Amazon S3 API for Azure Blob Storage. - Pour une utilisation légère, la configuration VM minimale semble fonctionner très bien. Vous pouvez accepter la plupart des configurations par défaut. N’oubliez pas de sauvegarder le fichier de clé PEM lorsque vous créez la VM.
- Accédez au lien de la VM Flexify.IO, et entrez dans le système. Suivez les instructions en configurant le fournisseur de données Azure Blob Storage et l’endpoint S3 généré. Assurez-vous que le paramètre de configuration de l’endpoint
Public read access to all objects in virtual bucketsest vrai. Copiez l’URL de l’endpoint S3 et les clés. - Appuyez sur New Virtual Bucket et créez un bucket virtuel. Il peut porter le même nom que votre conteneur Azure Blob Storage, ou un nom différent. Liez n’importe quel conteneur(s) à fusionner dans ce bucket virtuel. Ce bucket virtuel est utilisé pour exposer un bucket lisible publiquement via S3.
- Par défaut, Flexify.IO installe un certificat SSL auto-signé, tandis qu’un endpoint S3 nécessite HTTPS. Connectez-vous en SSH à la VM en utilisant le fichier de clé (le nom d’utilisateur est par défaut
azureuser), et remplacez les fichiers suivants par les fichiers corrects :
-
/etc/flexify/ssl/cert.pem- remplacez par le fichier de certificat (encodage PEM) -
/etc/flexify/ssl/key.pem- remplacez par le fichier de clé privée (encodage PEM PKCS#8, c’est celui commençant parBEGIN PRIVATE KEYet nonBEGIN RSA PRIVATE KEYqui est PKCS#1)Ces fichiers sont root, donc vous devrez utiliser
sudopour les remplacer. Il est préférable de s’assurer que les fichiers de remplacement ont la même propriété et les mêmes permissions que les originaux, c’est-à-direroot:rootet permission600.
- Par défaut, Flexify.IO crée un service S3 de niveau racine avec plusieurs buckets. Discourse nécessite le support de sous-domaines pour les buckets. Allez à :
<votre IP VM Flexify.IO>/flexify-io/manage/admin/engines/configs/1qui ouvrira une page de configuration cachée ! - Spécifiez le domaine de base S3 (disons qu’il est
s3.mydomain.com) dans le champEndpoint hostname, qui devrait être vide par défaut. Appuyez sur Save pour sauvegarder le paramètre. - Redémarrez la VM Flexify.IO dans le portail Azure.
- Dans votre DNS, mappez
s3.mydomain.comet*.s3.mydomain.comvers l’IP de la VM Flexify.IO. - Dans Discourse, définissez ce qui suit dans la page administrateur (oui, il n’y a pas besoin que les paramètres soient dans
app.yml) :
use s3: true
s3 region: anything
s3 endpoint: https://s3.mydomain.com
s3 access key: myaccesskey
s3 secret assess key: mysecret key
s3 cdn url: https://<azure-blob-account>.blob.core.windows.net/<container>
s3 bucket: <virtual bucket>
s3 backup bucket: <backup bucket> (n'importe quel conteneur conviendra, car il ne nécessite pas d'accès en lecture publique et Flexify.IO les exposera automatiquement)
backup location: s3
L’utilisation du même bucket pour la production et la préproduction (staging) n’est pas recommandée. Si vous le faites quand même, prenez des mesures pour vous assurer que votre site de préproduction ne supprime pas vos actifs de production (définissez s3 disable cleanup au minimum, et faites attention à ce qu’il ne supprime pas les sauvegardes de la production).
Wasabi
@pfaffman a essayé wasabi pour les sauvegardes, mais cela semblait échouer de manière intermittente et silencieuse, laissant les sauvegardes sur le disque dur et remplissant éventuellement le disque. Ni wasabi ni meta n’avaient d’indices, donc je ne le recommande pas, bien que vos résultats puissent varier. @pfaffman est maintenant assez certain que ce problème était dû au fait que les sauvegardes et les redémarrages automatiques étaient planifiés en même temps ; il n’était utilisé que pour les sauvegardes, mais semblait fonctionner correctement. Si quelqu’un veut essayer et en faire le rapport ici, cela devrait fonctionner, du moins pour les sauvegardes.
Oracle Cloud
Oracle Cloud ne prend pas en charge l’accès aux buckets en style virtual-host et ne fonctionnera pas
Cloudflare R2
Cloudflare R2 est compatible avec le stockage d’objets S3 lors de l’utilisation du CDN Cloudflare. Le plan gratuit de Cloudflare offre 10 Go de stockage, ce qui devrait être largement suffisant pour les besoins de la plupart des forums.
Pour configurer Cloudflare R2, vous devrez configurer les paramètres pertinents dans le tableau de bord Cloudflare sous R2 Object Storage.
Selon vos besoins (uploads ou sauvegardes ou les deux), voici les paramètres pertinents à insérer dans votre fichier app.yml ou dans votre recherche Admin-Tous les paramètres du site pour S3 :
DISCOURSE_ENABLE_S3_UPLOADS: true
DISCOURSE_S3_REGION: auto
DISCOURSE_S3_ENDPOINT: https://<your-account-id>.r2.cloudflarestorage.com
DISCOURSE_S3_ACCESS_KEY_ID: "xxx"
DISCOURSE_S3_SECRET_ACCESS_KEY: "xxx"
DISCOURSE_S3_UPLOAD_BUCKET: your-upload-bucket-name
DISCOURSE_S3_CDN_URL: https://uploads.yourdomain.com
# DISCOURSE_S3_USE_CDN_URL_FOR_ALL_UPLOADS: true
DISCOURSE_ENABLE_DIRECT_S3_UPLOADS: true
DISCOURSE_S3_USE_ACLS: false
DISCOURSE_BACKUP_LOCATION: s3
DISCOURSE_S3_BACKUP_BUCKET: your-backup-bucket-name
Si vous ne souhaitez pas modifier votre app.yml, vous pouvez le faire dans l’interface administrateur :
“Admin → Tous les paramètres du site” (recherchez S3) :
- Activer les uploads S3 =
true - Activer les uploads S3 directs =
true - ID de clé d’accès S3 =
"xxx" - Clé secrète d’accès S3 =
"xxx" - Région S3 =
any - Bucket d’upload S3 =
nom de votre bucket d'upload - Endpoint S3 =
https://<your-account-id>.r2.cloudflarestorage.com - URL CDN S3 =
https://uploads.yourdomain.com - Utiliser les ACLs S3 =
false(désactivez ceci !) - Bucket de sauvegarde S3 =
nom de votre bucket de sauvegarde - Emplacement de sauvegarde =
S3
Notes importantes sur la configuration de Cloudflare R2 :
- Lors de la configuration de votre
app.ymlouweb_only.ymlpour Cloudflare R2, définissez uniquement leDISCOURSE_S3_CDN_URL. Ne définissez PASDISCOURSE_CDN_URL. Si vous proxyez votre domaine principal via Cloudflare, il met déjà en cache et sert vos actifs d’application automatiquement. Si vous tentez de configurer unDISCOURSE_CDN_URLséparé en utilisant DNS Cloudflare, le routage strict d’hôte NGINX de Discourse rejettera les requêtes, entraînant des boucles de redirection 301 infinies, des blocages de politique CORS et un site cassé.
- Laissez
DISCOURSE_CDN_URLcommenté. - Définissez
DISCOURSE_S3_CDN_URL: https://your-r2-custom-domain.com
-
Permissions du jeton API : Comme Discourse n’a qu’un seul ensemble de champs de credentials, le jeton API que vous générez dans Cloudflare doit avoir la permission d’accéder à la fois à votre bucket d’upload et à votre bucket de sauvegarde. Lors de la création de votre jeton, sélectionnez soit “Appliquer à tous les buckets” ou utilisez “Appliquer à des buckets spécifiques” et assurez-vous que les deux sont cochés. Assurez-vous également de cocher
Lecture & Écriture d'objetslors de la création de la clé API (la valeur par défaut est uniquementLecture d'objets). -
Lors de la copie de l’URL de l’endpoint depuis Cloudflare, il peut ajouter le nom du bucket à l’URL - vous devriez supprimer le nom du bucket de la fin de la chaîne dans votre fichier
.yml(ou paramètres administrateur) s’il est collé. -
Décommentez
# DISCOURSE_S3_USE_CDN_URL_FOR_ALL_UPLOADS: truesi vous souhaitez utiliser votre bucket d’upload R2 pour tous les uploads, y compris les fichiersPDFetZIP. (Notez que cela rendra tous les fichiers uploadés accessibles publiquement via un lien direct) -
Si vous activez
DISCOURSE_ENABLE_DIRECT_S3_UPLOADS(true), vous devriez désactiverDISCOURSE_S3_USE_ACLS(false). C’est parce que Cloudflare R2 utilise des permissions au niveau du bucket ; votre bucket d’upload devrait être public et le bucket de sauvegarde devrait être privé. Pour les uploads Cloudflare R2, vous NE DEVEZ PAS configurer les tâches rake des règles CORS ou écrire du json IAM, car vous les configurerez dans le tableau de bord Cloudflare lors de la configuration des permissions de votre bucket. Le jeton “Lecture & Écriture d’objets” de Cloudflare accorde automatiquement les permissions d’upload multipart, et le collage de la règle CORS suivante directement dans les paramètres du bucket d’uploads R2 du tableau de bord Cloudflare sousPolitique CORSremplace le besoin de la tâche rake.
[
{
"AllowedOrigins": [
"https://forum.yourdomain.com"
],
"AllowedMethods": [
"GET",
"PUT",
"POST",
"DELETE",
"HEAD"
],
"AllowedHeaders": [
"*"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3000
}
]
Consultez également ce sujet pour plus d’informations sur la configuration de Cloudflare : Using Discourse with Cloudflare: Best Practices
Contabo
@tuxed a essayé de faire fonctionner Contabo Object Storage pour les uploads compatibles S3. Il semble que lors de l’upload, il préfixe le nom du dépôt dans l’URL et il n’a pas réussi à le faire fonctionner.
Uploads sécurisés
Les uploads sécurisés ne sont pris en charge que pour AWS S3. Si votre rake uploads:migrate_to_s3 échoue, vous devriez entrer ces commandes pour d’abord compter, puis marquer comme non sécurisés ces uploads, étant donné que vous savez qu’ils n’ont pas besoin d’être sécurisés, auquel cas, vous devrez utiliser AWS S3.
./launcher enter app
rails c
Upload.where(secure: true).count
Upload.where(secure: true).update_all(secure:false)