Este tema cubre cómo configurar algunos proveedores comunes de almacenamiento de objetos compatibles con S3 (clones de S3). Consulta Set up file and image uploads to S3 para más detalles sobre la configuración de Amazon AWS S3, que es oficialmente compatible y utilizada internamente por Discourse para nuestros servicios de alojamiento.
| Proveedor | Nombre del servicio | ¿Funciona con Discourse? |
|---|---|---|
| Amazon AWS | S3 | Sí |
| Digital Ocean | Spaces | Sí |
| Linode | Almacenamiento de objetos | Sí |
| Google Cloud | Storage | Sí |
| Scaleway | Almacenamiento de objetos | Sí |
| Vultr | Almacenamiento de objetos | Sí |
| BackBlaze | Cloud Storage | Sí* |
| Autoalojado | MinIO | Sí |
| Azure Blob Storage | Flexify.IO | Sí |
| Oracle Cloud | Almacenamiento de objetos | No [1] |
| Wasabi | Almacenamiento de objetos | Quizás |
| Cloudflare | R2 | Sí |
| Contabo | Almacenamiento de objetos | No |
Si lograste que funcione un servicio diferente, por favor agrégalo a esta wiki.
Configuración
Para almacenar los activos estáticos de Discourse en tu almacenamiento de objetos, agrega esta configuración en tu archivo app.yml bajo la sección 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
Al utilizar almacenamiento de objetos, también necesitas una CDN para servir lo que se almacena en el bucket. Utilicé StackPath CDN en mis pruebas y, aparte de necesitar configurar Dynamic Caching By Header: Accept-Encoding en su configuración, funciona bien.
DISCOURSE_CDN_URL es una CDN que apunta a tu nombre de host de Discourse y almacena en caché las solicitudes. Se utilizará principalmente para activos descargables: CSS y otros activos de temas.
DISCOURSE_S3_CDN_URL es una CDN que apunta a tu bucket de almacenamiento de objetos y almacena en caché las solicitudes. Se utilizará principalmente para activos cargables: JS, imágenes y cargas de usuarios.
Recomendamos que sean diferentes y que los administradores configuren ambos.
No utilizar una CDN (o ingresar la URL del bucket como la URL de la CDN) probablemente cause problemas y no es compatible.
En los siguientes ejemplos, https://falcoland-files-cdn.falco.dev es una CDN configurada para servir los archivos bajo el bucket. El nombre del bucket se estableció en falcoland-files en mis ejemplos.
Se recomienda configurar estos ajustes en variables de entorno en tu app.yml, ya que es así como lo hace CDCK en su infraestructura, por lo que está bien probado. Además, la tarea de cargar activos ocurre después de que los activos se compilan, lo cual sucede en una reconstrucción. Si deseas iniciar un Discourse que funcione correctamente con almacenamiento de objetos desde el principio, necesitas establecer las variables de entorno para que los activos se carguen antes de que el sitio se inicie.
Elige tu proveedor de la lista de abajo y agrega estos ajustes a la sección env de tu archivo app.yml, ajustando los valores según corresponda:
AWS S3
Lo que oficialmente soportamos y usamos internamente. Su oferta de CDN Cloudfront también funciona para servir los archivos del bucket. Consulta Set up file and image uploads to S3 para saber cómo configurar los permisos correctamente.
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
La oferta de DO es buena y funciona sin problemas. Es correcto habilitar «Restrict File Listing». El único problema es que su oferta de CDN está terriblemente rota, por lo que necesitas usar una CDN diferente para los archivos. Además, no debes instalar la regla CORS, ya que se reinstala en cada reconstrucción.
Configuración de ejemplo:
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
Se requiere un parámetro de configuración adicional, HTTP_CONTINUE_TIMEOUT, para Linode.
Configuración de ejemplo:
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
Listar archivos está roto, por lo que necesitas una variable de entorno adicional para omitirlo para que los activos funcionen. También omite CORS y configúralo manualmente.
Dado que no puedes listar archivos, no podrás listar copias de seguridad y las copias de seguridad automáticas fallarán; no recomendamos usarlo para copias de seguridad. Sin embargo, algunos sugieren que si cambias el rol de «Storage Legacy Object Owner» a «Storage Legacy Bucket Owner», las copias de seguridad funcionan correctamente. Consulta este tema para una discusión específica de Google Cloud.
Existe un plugin de terceros para mejorar la integración en Discourse GCS Helper.
Configuración de ejemplo:
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
La oferta de Scaleway también es muy buena y, en su mayor parte, todo funciona bien.
Las cargas multipart de Scaleway solo admiten un máximo de 1.000 partes. Esto no coincide con Amazon S3, que admite un máximo de 10.000 partes. Para instancias más grandes, esto hará que las copias de seguridad de Discourse fallen y la carga incompleta puede necesitar ser eliminada manualmente antes de realizar nuevos intentos. Para instancias pequeñas, esto no es un problema. Scaleway parece bastante abierto a la retroalimentación, por lo que si deseas que se cambie este límite, debes contactarlos.
Ten en cuenta que para el parámetro DISCOURSE_S3_ENDPOINT, Discourse utiliza el punto de conexión de toda la región: https://s3.{region}.scw.cloud. El «Bucket endpoint» que aparece en tu panel de Scaleway tiene el formato https://{bucketName}.s3.{region}.scw.cloud. Omite el subdominio del nombre del bucket para evitar errores de conexión.
Configuración de ejemplo:
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
Se requiere un parámetro de configuración adicional, HTTP_CONTINUE_TIMEOUT, para Vultr.
Configuración de ejemplo:
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
Necesitas omitir CORS y configurarlo manualmente.
Hay informes de que «clean up orphan uploads» no funciona correctamente con BackBlaze. Debes cambiar las reglas de ciclo de vida de tu bucket para que la limpieza de huérfanos funcione.
Configuración de ejemplo:
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
Nota: Durante la migración inicial a B2, puedes alcanzar el límite gratuito diario de 2500 transacciones de clase C. Necesitarás agregar un método de pago para eliminar los límites.
MinIO Storage Server
Hay algunas advertencias y requisitos que debes asegurarte de cumplir antes de poder usar el servidor de almacenamiento MinIO como alternativa a S3:
- Tienes una instancia de servidor MinIO completamente configurada.
- Tienes la compatibilidad con dominios habilitada en la configuración de MinIO, para URLs de bucket impulsadas por dominio. Este es un requisito de configuración obligatorio para MinIO y Discourse, ya que MinIO aún admite los estilos «path» heredados de S3 que ya no son compatibles con Discourse.
- Tienes la configuración de DNS correctamente establecida para MinIO para que los subdominios de los buckets se resuelvan correctamente al servidor MinIO y el servidor MinIO esté configurado con un dominio base (en este caso,
minio.example.com). - El bucket
discourse-dataexiste en el servidor MinIO y tiene una política «pública» establecida en él. - Tu URL de CDN de S3 apunta a una CDN correctamente configurada que apunta al bucket y almacena en caché las solicitudes, como se indicó anteriormente en este documento.
- Tus CDNs están configuradas para usar realmente un encabezado «Host» de la URL principal de S3; por ejemplo,
discourse-data.minio.example.comcuando obtiene datos; de lo contrario, puede causar problemas de CORB.
Asumiendo que se cumplen las advertencias y los prerrequisitos anteriores, una configuración de ejemplo sería algo así:
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 seguirá estando habilitado en MinIO incluso si la regla no es instalada por el reconstructor de la aplicación; por defecto, parece, CORS está habilitado en todos los verbos HTTP en MinIO, y MinIO no admite BucketCORS (API S3) como resultado.
Azure Blob Storage con Flexify.IO
Azure Blob Storage no es un servicio compatible con S3, por lo que no se puede usar con Discourse. Hay un plugin, pero está roto.
La forma más fácil de exponer una interfaz compatible con S3 para Azure Blob Storage es agregar un servidor Flexify.IO que traduce el protocolo de almacenamiento de Azure a S3.
Al momento de escribir esto, el servicio es gratuito en Azure y solo necesitas una tier de VM muy básica (barata) para comenzar a ejecutarlo. Sin embargo, requiere un poco de configuración.
- En el portal de Azure, crea un nuevo recurso de
Flexify.IO - Amazon S3 API for Azure Blob Storage. - Para un uso ligero, la configuración mínima de VM parece funcionar bien. Puedes aceptar la mayoría de la configuración predeterminada. Recuerda guardar el archivo de clave PEM cuando crees la VM.
- Navega al enlace de la VM de Flexify.IO y entra al sistema. Sigue las instrucciones configurando el proveedor de datos de Azure Blob Storage y el punto de conexión S3 generado. Asegúrate de que la configuración del punto de conexión
Public read access to all objects in virtual bucketssea verdadera. Copia la URL y las claves del punto de conexión S3. - Presiona New Virtual Bucket y crea un bucket virtual. Puede tener el mismo nombre que tu contenedor de Azure Blob Storage o puede tener un nombre diferente. Enlaza cualquier contenedor para fusionarlo en este bucket virtual. Este bucket virtual se utiliza para exponer un bucket de lectura pública a través de S3.
- Por defecto, Flexify.IO instala un certificado SSL autofirmado, mientras que un punto de conexión S3 requiere HTTPS. Conéctate por SSH a la VM usando el archivo de clave (el nombre de usuario es
azureuserpor defecto) y reemplaza los siguientes archivos con los archivos correctos:
-
/etc/flexify/ssl/cert.pem- reemplaza con el archivo de certificado (codificación PEM) -
/etc/flexify/ssl/key.pem- reemplaza con el archivo de clave privada (codificación PKCS#8 PEM, es el que comienza conBEGIN PRIVATE KEYy noBEGIN RSA PRIVATE KEY, que es PKCS#1)Estos archivos son de root, por lo que tendrás que usar
sudopara reemplazarlos. Lo mejor es asegurarse de que los archivos de reemplazo tengan la misma propiedad y permisos que los originales, lo que significaroot:rooty permiso600.
- Por defecto, Flexify.IO crea un servicio S3 a nivel de raíz con múltiples buckets. Discourse requiere compatibilidad con subdominios para buckets. Ve a:
<tu IP de la VM de Flexify.IO>/flexify-io/manage/admin/engines/configs/1, lo que abrirá una página de configuración oculta. - Especifica el dominio base de S3 (digamos que es
s3.mydomain.com) en el campoEndpoint hostname, que debería estar en blanco por defecto. Presiona Save para guardar la configuración. - Reinicia la VM de Flexify.IO en el portal de Azure.
- En tu DNS, mapea
s3.mydomain.comy*.s3.mydomain.coma la IP de la VM de Flexify.IO. - En Discourse, configura lo siguiente en la página de administración (sí, no es necesario que las configuraciones estén en
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> (cualquier contenedor servirá, ya que no requiere acceso de lectura pública y Flexify.IO los expondrá automáticamente)
backup location: s3
No se recomienda usar el mismo bucket para producción y staging. Si lo haces de todos modos, toma medidas para asegurarte de que tu sitio de staging no elimine los activos de producción (configura s3 disable cleanup como mínimo y vigila que no elimine las copias de seguridad de producción).
Wasabi
@pfaffman probó Wasabi para copias de seguridad, pero parecía fallar intermitente y silenciosamente, dejando copias de seguridad en el disco duro y eventualmente llenando el disco. Ni Wasabi ni meta tenían pistas, por lo que no lo recomiendo, aunque tu experiencia puede variar. @pfaffman ahora está bastante seguro de que este problema se debía a que las copias de seguridad y los reinicios automáticos se programaban de alguna manera al mismo tiempo; solo se usaba para copias de seguridad, pero parecía funcionar bien. Si alguien quiere probarlo y reportarlo aquí, debería funcionar, al menos para copias de seguridad.
Oracle Cloud
Oracle Cloud carece de soporte para el acceso a buckets en estilo de host virtual y no funcionará
Cloudflare R2
Para configurar Cloudflare R2, deberás configurar los ajustes relevantes en el panel de control de Cloudflare bajo R2 Object Storage.
Dependiendo de tus necesidades (cargas, copias de seguridad o ambas), estos son los ajustes relevantes para insertar en tu archivo app.yml o en tu búsqueda de «Admin - Todos los ajustes del sitio» buscando S3:
DISCOURSE_ENABLE_S3_UPLOADS: true
DISCOURSE_S3_REGION: auto
DISCOURSE_S3_ENDPOINT: https://<tu-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 no deseas editar tu app.yml, puedes hacer esto en la interfaz de administración:
„Admin → Todos los ajustes del sitio

