Este tópico aborda como configurar alguns provedores comuns de armazenamento de objetos compatíveis com S3 (clones do S3). Consulte Set up file and image uploads to S3 para mais detalhes sobre a configuração do Amazon AWS S3, que é oficialmente suportada e usada internamente pelo Discourse para nossos serviços de hospedagem.
| Provedor | Nome do Serviço | Funciona com o Discourse? |
|---|---|---|
| Amazon AWS | S3 | Sim |
| Digital Ocean | Spaces | Sim |
| Linode | Object Storage | Sim |
| Google Cloud | Storage | Sim |
| Scaleway | Object Storage | Sim |
| Vultr | Object Storage | Sim |
| BackBlaze | Cloud Storage | Sim* |
| Auto-hospedado | MinIO | Sim |
| Azure Blob Storage | Flexify.IO | Sim |
| Oracle Cloud | Object Storage | Não [1] |
| Wasabi | Object Storage | Talvez |
| Cloudflare | R2 | Sim |
| Contabo | Object Storage | Não |
Se você conseguiu fazer outro serviço funcionar, por favor, adicione-o a esta wiki.
Configuração
Para armazenar ativos estáticos do Discourse em seu armazenamento de objetos, adicione esta configuração no seu app.yml na seção 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
Ao usar armazenamento de objetos, você também precisará de uma CDN para servir o que é armazenado no bucket. Usei a CDN StackPath em meus testes e, além de precisar configurar Dynamic Caching By Header: Accept-Encoding em sua configuração, funciona bem.
DISCOURSE_CDN_URL é uma CDN que aponta para seu hostname do Discourse e armazena em cache solicitações. Será usada principalmente para ativos recuperáveis: CSS e outros ativos de tema.
DISCOURSE_S3_CDN_URL é uma CDN que aponta para seu bucket de armazenamento de objetos e armazena em cache solicitações. Será usada principalmente para ativos enviáveis: JS, imagens e uploads de usuários.
Recomendamos que esses sejam diferentes e que os administradores configurem ambos.
Não usar uma CDN (ou inserir a URL do bucket como a URL da CDN) provavelmente causará problemas e não é suportado.
Nos exemplos a seguir, https://falcoland-files-cdn.falco.dev é uma CDN configurada para servir os arquivos sob o bucket. O nome do bucket foi definido como falcoland-files em meus exemplos.
Configurar essas definições em variáveis de ambiente no seu app.yml é recomendado porque é assim que a CDCK faz em sua infraestrutura, então é bem testado. Além disso, a tarefa de enviar ativos ocorre após a compilação dos ativos, o que acontece em uma reconstrução. Se você quiser iniciar um Discourse que funcione corretamente com armazenamento de objetos desde o início, precisará definir as variáveis de ambiente para que os ativos sejam enviados antes que o site inicie.
Escolha seu provedor na lista abaixo e adicione essas configurações à seção env do seu arquivo app.yml, ajustando os valores conforme necessário:
AWS S3
O que suportamos oficialmente e usamos internamente. Sua oferta de CDN, a Cloudfront, também funciona para servir os arquivos do bucket. Consulte Set up file and image uploads to S3 para saber como configurar as permissões corretamente.
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
A oferta da DO é boa e funciona imediatamente. É seguro ativar a restrição de listagem de arquivos. O único problema é que sua oferta de CDN está terrivelmente quebrada, então você precisa usar uma CDN diferente para os arquivos. Além disso, não deve instalar a regra CORS, pois ela será reinstalada a cada reconstrução.
Exemplo de configuração:
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
Um parâmetro de configuração extra, HTTP_CONTINUE_TIMEOUT, é necessário para o Linode.
Exemplo de configuração:
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
A listagem de arquivos está quebrada, então você precisa de uma variável de ambiente extra para ignorar isso para que os ativos funcionem. Também ignore o CORS e configure-o manualmente.
Como você não pode listar arquivos, não poderá listar backups, e os backups automáticos falharão. Não recomendamos o uso para backups. No entanto, alguns sugerem que, se você alterar a função de Storage Legacy Object Owner para Storage Legacy Bucket Owner, os backups funcionarão corretamente. Consulte este tópico para discussão específica do Google Cloud.
Existe um plugin de terceiros para melhorar a integração em Discourse GCS Helper.
Exemplo de configuração:
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
A oferta da Scaleway também é muito boa e, na maior parte, tudo funciona bem.
Os uploads multipart da Scaleway suportam apenas um máximo de 1.000 partes. Isso não corresponde ao Amazon S3, que suporta um máximo de 10.000 partes. Para instâncias maiores, isso fará com que os backups do Discourse falhem e o upload incompleto pode precisar ser excluído manualmente antes de novas tentativas. Para instâncias pequenas, isso não é um problema. A Scaleway parece bastante aberta a feedback, então, se você quiser que esse limite seja alterado, deve entrar em contato com eles.
Observe que, para o parâmetro DISCOURSE_S3_ENDPOINT, o Discourse usa o endpoint de toda a região: https://s3.{region}.scw.cloud. O “Bucket endpoint” encontrado no seu painel da Scaleway vem no formato https://{bucketName}.s3.{region}.scw.cloud. Omita o subdomínio do nome do bucket para evitar erros de conexão.
Exemplo de configuração:
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
Um parâmetro de configuração extra, HTTP_CONTINUE_TIMEOUT, é necessário para o Vultr.
Exemplo de configuração:
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
Você precisa ignorar o CORS e configurá-lo manualmente.
Há relatos de que clean up orphan uploads não está funcionando corretamente com o BackBlaze. Você deve alterar as regras de ciclo de vida do seu bucket para que a limpeza de órfãos funcione.
Exemplo de configuração:
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 a migração inicial para o B2, você pode atingir o limite diário gratuito de 2500 transações da classe C. Você precisará adicionar um método de pagamento para remover os limites.
MinIO Storage Server
Existem algumas ressalvas e requisitos que você precisa garantir antes de poder usar o servidor de armazenamento MinIO como alternativa ao S3:
- Você tem uma instância do servidor MinIO totalmente configurada
- Você tem o suporte a domínio habilitado na configuração do MinIO, para URLs de bucket orientados a domínio. Isso é um requisito obrigatório de configuração para MinIO e Discourse, pois o MinIO ainda suporta os estilos de “caminho” S3 legados que não são mais suportados no Discourse.
- Você tem a configuração de DNS configurada corretamente para o MinIO, para que os subdomínios do bucket resolvam corretamente para o servidor MinIO e o servidor MinIO esteja configurado com um domínio base (neste caso,
minio.example.com) - O bucket
discourse-dataexiste no servidor MinIO e tem uma política “pública” definida nele - Sua URL da CDN S3 aponta para uma CDN configurada corretamente que aponta para o bucket e armazena em cache solicitações, conforme declarado anteriormente neste documento.
- Suas CDNs estão configuradas para realmente usar um cabeçalho “Host” da URL S3 principal — por exemplo,
discourse-data.minio.example.comquando busca dados — caso contrário, pode causar problemas de CORB.
Supondo que as ressalvas e pré-requisitos acima sejam atendidos, um exemplo de configuração seria algo assim:
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
O CORS ainda será habilitado no MinIO, mesmo que a regra não seja instalada pelo reconstrutor do app — por padrão, parece, o CORS está habilitado em todos os verbos HTTP no MinIO, e o MinIO não suporta BucketCORS (API S3) como resultado.
Azure Blob Storage com Flexify.IO
O Azure Blob Storage não é um serviço compatível com S3, portanto, não pode ser usado com o Discourse. Existe um plugin, mas está quebrado.
A maneira mais fácil de expor uma interface compatível com S3 para o Azure Blob Storage é adicionar um servidor Flexify.IO que traduz o protocolo de armazenamento do Azure para S3.
No momento da escrita, o serviço é gratuito no Azure, e você só precisa de uma tier de VM muito básica (barata) para começar a executá-lo. No entanto, requer um pouco de configuração.
- No portal do Azure, crie um novo recurso de
Flexify.IO - Amazon S3 API for Azure Blob Storage. - Para uso leve, a configuração mínima de VM parece funcionar muito bem. Você pode aceitar a maioria das configurações padrão. Lembre-se de salvar o arquivo de chave PEM ao criar a VM.
- Navegue até o link da VM Flexify.IO e entre no sistema. Siga as instruções configurando o provedor de dados do Azure Blob Storage e o endpoint S3 gerado. Certifique-se de que a configuração do endpoint
Public read access to all objects in virtual bucketsesteja definida como true. Copie a URL do endpoint S3 e as chaves. - Pressione New Virtual Bucket e crie um bucket virtual. Pode ter o mesmo nome que seu contêiner do Azure Blob Storage ou um nome diferente. Vincule qualquer contêiner para mesclar neste bucket virtual. Este bucket virtual é usado para expor um bucket publicamente legível via S3.
- Por padrão, o Flexify.IO instala um certificado SSL autofirmado, enquanto um endpoint S3 requer HTTPS. Conecte-se via SSH à VM usando o arquivo de chave (o nome de usuário é, por padrão,
azureuser) e substitua os seguintes arquivos pelos arquivos corretos:
-
/etc/flexify/ssl/cert.pem- substitua pelo arquivo de certificado (codificação PEM) -
/etc/flexify/ssl/key.pem- substitua pelo arquivo de chave privada (codificação PKCS#8 PEM, aquele que começa comBEGIN PRIVATE KEYe nãoBEGIN RSA PRIVATE KEY, que é PKCS#1)Esses arquivos são root, então você precisará usar
sudopara substituí-los. É melhor garantir que os arquivos de substituição tenham a mesma propriedade e permissões que os originais, o que significaroot:roote permissão600.
- Por padrão, o Flexify.IO cria um serviço S3 de nível raiz com vários buckets. O Discourse requer suporte a subdomínio para buckets. Vá para:
<IP da sua VM Flexify.IO>/flexify-io/manage/admin/engines/configs/1, o que abrirá uma página de configuração oculta! - Especifique o domínio base S3 (digamos que seja
s3.mydomain.com) no campoEndpoint hostname, que deve estar em branco por padrão. Pressione Save para salvar a configuração. - Reinicie a VM Flexify.IO no portal do Azure.
- No seu DNS, mapeie
s3.mydomain.come*.s3.mydomain.compara o IP da VM Flexify.IO. - No Discourse, defina o seguinte na página de administração (sim, não há necessidade de as configurações estarem em
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> (qualquer contêiner serve, pois não requer acesso de leitura pública e o Flexify.IO os exporá automaticamente)
backup location: s3
Não é recomendado usar o mesmo bucket para produção e staging. Se você fizer isso mesmo assim, tome medidas para garantir que seu site de staging não exclua seus ativos de produção (defina s3 disable cleanup como mínimo e fique atento à exclusão de backups de produção).
Wasabi
@pfaffman tentou usar o Wasabi para backups, mas parecia falhar intermitentemente e silenciosamente, deixando backups no disco rígido e eventualmente enchendo o disco. Nem o Wasabi nem o meta tinham pistas, então não recomendo, embora sua experiência possa variar. @pfaffman agora tem certeza de que esse problema foi devido a backups e reinicializações automáticas sendo agendados de alguma forma ao mesmo tempo; era usado apenas para backups, mas parecia funcionar bem. Se alguém quiser tentar e relatar aqui, deve funcionar, pelo menos para backups.
Oracle Cloud
O Oracle Cloud não oferece suporte ao acesso ao estilo de host virtual para buckets e não funcionará
Cloudflare R2
Para configurar o Cloudflare R2, você precisará configurar as configurações relevantes no painel do Cloudflare em R2 Object Storage.
Dependendo das suas necessidades (uploads, backups ou ambos), estas são as configurações relevantes para inserir no seu arquivo app.yml ou em suas Admin-All site settings pesquisando por 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
Se você não quiser editar seu app.yml, pode fazer isso na interface de administração:
“Admin → All site settings” (pesquise por S3):
- Enable S3 uploads =
true - Enable direct S3 uploads =
true - S3 access key ID =
"xxx" - S3 secret access key =
"xxx" - S3 region =
any - S3 upload bucket =
your upload bucket name - S3 endpoint =
https://<your-account-id>.r2.cloudflarestorage.com - S3 CDN URL =
https://uploads.yourdomain.com - S3 use ACLs =
false(desative isso!) - S3 backup bucket =
your backup bucket name - Backup location =
S3
Notas:
-
Permissões do Token de API: Como o Discourse tem apenas um conjunto de campos de credenciais, o token de API que você gera no Cloudflare deve ter permissão para acessar tanto seu bucket de upload quanto seu bucket de backup. Ao criar seu token, selecione “Apply to all buckets” ou use “Apply to specific buckets” e certifique-se de que ambos estejam marcados. Além disso, certifique-se de marcar
Object Read & Writeao criar a chave de API (o padrão é apenasObject Read only). -
Ao copiar a URL do endpoint do Cloudflare, pode anexar o nome do bucket à URL — você deve excluir o nome do bucket do final da string no seu arquivo
.ymlse for colado. -
Descomente
# DISCOURSE_S3_USE_CDN_URL_FOR_ALL_UPLOADS: truese quiser usar seu bucket de upload R2 para todos os uploads, incluindo arquivosPDFeZIP. (Observe que isso tornará todos os arquivos enviados publicamente disponíveis via link direto) -
Se ativar
DISCOURSE_ENABLE_DIRECT_S3_UPLOADS(true), você deve desativarDISCOURSE_S3_USE_ACLS(false). Isso ocorre porque o Cloudflare R2 usa permissões no nível do bucket; seu bucket de uploads deve ser público e o bucket de backup deve ser privado. Para uploads do Cloudflare R2, você NÃO precisa configurar as tarefas rake de regras CORS ou escrever IAM json, pois você configurará isso no painel do Cloudflare ao configurar suas permissões de bucket. O token “Object Read & Write” do Cloudflare concede automaticamente permissões de upload multipart, e colar a seguinte regra CORS diretamente nas configurações do bucket de uploads R2 no Painel do Cloudflare emCORS Policysubstitui a necessidade da tarefa rake.
[
{
"AllowedOrigins": [
"https://forum.yourdomain.com"
],
"AllowedMethods": [
"GET",
"PUT",
"POST",
"DELETE",
"HEAD"
],
"AllowedHeaders": [
"*"
],
"ExposeHeaders": [
"ETag"
],
"MaxAgeSeconds": 3000
}
]
Contabo
@tuxed tentou fazer o Contabo Object Storage funcionar para uploads compatíveis com S3. Parece que, ao fazer o upload, ele adiciona o prefixo do nome do repositório na URL e ele não conseguiu fazer funcionar.
Uploads Seguros
Uploads seguros são suportados apenas para AWS S3. Se o seu rake uploads:migrate_to_s3 falhar, você deve inserir esses comandos para primeiro contar e depois marcar como inseguros esses uploads, dado que você sabe que eles não precisam ser seguros, caso em que, você precisará usar AWS S3.
./launcher enter app
rails c
Upload.where(secure: true).count
Upload.where(secure: true).update_all(secure:false)

