Como funciona o armazenamento
Opcional — um bucket compatível com S3 pra que as pessoas possam anexar imagens no chat. Sem ele, todo o resto continua funcionando.
Esta seção inteira é opcional
Você consegue terminar o setup e rodar o OpenCall sem configurar armazenamento nenhum. Voz, vídeo, compartilhamento de tela e chat de texto funcionam. A única coisa que você perde é anexar imagem no chat — o botão de anexo não aparece.
Pular isso é uma escolha razoável numa demo. Volte quando quiser o recurso.
Pra que serve
Quando alguém anexa uma imagem numa mensagem, o arquivo precisa morar em algum lugar que não seja o disco do próprio app — o app reinicia e recebe deploy, e tudo que foi escrito no sistema de arquivos dele se perde.
Então a imagem vai pra um bucket de object storage: um lugar que guarda arquivos e os serve de volta por HTTPS. O app fala S3 puro, o que significa que qualquer provedor compatível com S3 serve. Dois estão documentados aqui.
Qual escolher
| Neon Object Storage | Cloudflare R2 | |
|---|---|---|
| Cartão pra habilitar | não pede | pede, mesmo no free (dentro da cota cobra US$ 0) |
| Armazenamento grátis | 5 GB por projeto | 10 GB por conta |
| Egress | conta na cota de 5 GB/mês de rede do projeto | livre, sem cobrança de egress |
| Conta a mais | nenhuma, se você já usa Neon pro Postgres | mais uma conta |
| Maturidade | beta | GA |
Demo → Neon: sem cartão, e sem nenhuma conta que você já não tenha (a demo já usa Neon pro Banco de dados).
Produção → Cloudflare R2: o egress livre é o que faz sentido pra servir imagem de chat pra uma comunidade de verdade.
No Neon, o egress acaba levando o banco junto
Os 5 GB/mês de tráfego são compartilhados pelo projeto inteiro, imagem e banco no mesmo balde — e quando acabam o Neon suspende o compute até o próximo ciclo. Pra uma demo de 5 pessoas sobra; pra uma comunidade de verdade é a troca errada.
Comum aos dois
Não há política de CORS pra configurar em nenhum dos dois caminhos: o upload
vai pro /api/chat/uploads no Next.js, que escreve no bucket com as
credenciais do servidor. O navegador nunca fala direto com o bucket.
Variáveis desta etapa
| Variável | Neon | Cloudflare R2 |
|---|---|---|
R2_BUCKET | Nome do bucket | Nome do bucket |
R2_ACCESS_KEY_ID | token_id da credential | Do API Token |
R2_SECRET_ACCESS_KEY | s3_secret_access_key | Do API Token |
NEXT_PUBLIC_R2_PUBLIC_BASE_URL | <endpoint>/<bucket> | URL pública do bucket |
R2_ENDPOINT | Endpoint de storage da branch | (vazia) |
R2_REGION | us-east-2 ou eu-central-1 | (vazia — default auto) |
R2_ACCOUNT_ID | (vazia) | Account ID da Cloudflare |
O prefixo R2_ é histórico — ele nomeia o slot de armazenamento, não o
provedor.