Armazém

Conectar aplicações

O Armazém funciona com as ferramentas de linha de comando e os SDKs de armazenamento de objetos mais usados. Para conectar, você precisa de três coisas: o endereço, a região e uma chave de acesso criada no console.

Antes de começar

  1. Crie um bucket no menu Armazém do console.
  2. Crie uma chave de acesso para a aplicação e guarde o ID e o segredo. O segredo aparece uma única vez.
  3. Escolha o nível de acesso pelo que a aplicação faz: Leitura e envio lista, baixa e envia, mas não apaga arquivos; apagar arquivos e mudar configurações do bucket, como CORS e versões, exigem Completo.
  4. Se limitou a chave a algumas redes, confirme que a aplicação sai por uma delas.
DadoValor
Endereçohttps://armazem.zenifra.com
Regiãobr-sp1
Endereço de cada buckethttps://<bucket>.armazem.zenifra.com

Guarde a chave em variáveis de ambiente, nunca no código. Em projetos da Zenifra, use as variáveis de ambiente do projeto.

ACCESS_KEY_ID=...
SECRET_ACCESS_KEY=...

AWS CLI

aws configure set aws_access_key_id "$ACCESS_KEY_ID" --profile zenifra
aws configure set aws_secret_access_key "$SECRET_ACCESS_KEY" --profile zenifra
aws configure set default.s3.addressing_style virtual

aws --profile zenifra --endpoint-url https://armazem.zenifra.com --region br-sp1 s3 ls
aws --profile zenifra --endpoint-url https://armazem.zenifra.com --region br-sp1 s3 cp ./foto.png s3://fotos/2026/foto.png

JavaScript e TypeScript

npm install @aws-sdk/client-s3 @aws-sdk/lib-storage @aws-sdk/s3-request-presigner
import { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'

const client = new S3Client({
  endpoint: 'https://armazem.zenifra.com',
  region: 'br-sp1',
  credentials: { accessKeyId: process.env.ACCESS_KEY_ID!, secretAccessKey: process.env.SECRET_ACCESS_KEY! },
})

await client.send(new PutObjectCommand({ Bucket: 'fotos', Key: '2026/foto.png', Body: arquivo, ContentType: 'image/png' }))

const link = await getSignedUrl(client, new GetObjectCommand({ Bucket: 'fotos', Key: '2026/foto.png' }), { expiresIn: 3600 })

O PutObjectCommand manda o arquivo inteiro numa requisição só. Para arquivos grandes, como vídeos e backups, use o Upload do @aws-sdk/lib-storage, que divide o envio em partes e envia várias ao mesmo tempo:

import { createReadStream } from 'node:fs'
import { Upload } from '@aws-sdk/lib-storage'

const envio = new Upload({
  client,
  params: { Bucket: 'videos', Key: '2026/aula.mp4', Body: createReadStream('./aula.mp4'), ContentType: 'video/mp4' },
  partSize: 8 * 1024 * 1024,
  queueSize: 4,
})
envio.on('httpUploadProgress', ({ loaded, total }) => console.log(loaded, total))
await envio.done()

Python

pip install boto3
import os
import boto3
from botocore.config import Config

client = boto3.client(
    's3',
    endpoint_url='https://armazem.zenifra.com',
    region_name='br-sp1',
    aws_access_key_id=os.environ['ACCESS_KEY_ID'],
    aws_secret_access_key=os.environ['SECRET_ACCESS_KEY'],
    config=Config(s3={'addressing_style': 'virtual'}),
)

client.upload_file('backup.tar.gz', 'backups', '2026/backup.tar.gz')
link = client.generate_presigned_url('get_object', Params={'Bucket': 'backups', 'Key': '2026/backup.tar.gz'}, ExpiresIn=3600)

O upload_file já divide arquivos acima de 8 MB em partes. Para mudar o tamanho das partes, passe Config=TransferConfig(multipart_chunksize=...) (from boto3.s3.transfer import TransferConfig).

Django

Com o django-storages, os campos FileField e ImageField gravam direto no Armazém:

pip install django-storages boto3
# settings.py
import os

STORAGES = {
    'default': {
        'BACKEND': 'storages.backends.s3.S3Storage',
        'OPTIONS': {
            'bucket_name': os.environ['ARMAZEM_BUCKET'],
            'endpoint_url': 'https://armazem.zenifra.com',
            'region_name': 'br-sp1',
            'access_key': os.environ['ACCESS_KEY_ID'],
            'secret_key': os.environ['SECRET_ACCESS_KEY'],
            'addressing_style': 'virtual',
            'default_acl': None,
            'file_overwrite': False,
            'querystring_expire': 3600,
        },
    },
    # mantenha o backend de arquivos estáticos que você já usa, como o WhiteNoise
    'staticfiles': {'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage'},
}

Com essa configuração, os arquivos ficam privados, arquivo.url devolve um link assinado de 1 hora e um envio com nome repetido ganha um sufixo em vez de substituir o arquivo anterior.

Outras linguagens e ferramentas

Qualquer SDK ou ferramenta compatível com S3 funciona com a mesma configuração: o endereço https://armazem.zenifra.com, a região br-sp1, o ID e o segredo da chave. Se a ferramenta tiver a opção de estilo de endereço, use o endereço por bucket (virtual-hosted), e não por caminho (path-style).

Um link assinado dá acesso a um único arquivo por um tempo limitado, sem expor a chave. Use links para:

  • entregar um arquivo a um usuário final;
  • receber um envio direto do navegador do usuário, sem passar pelo seu servidor;
  • compartilhar um arquivo por e-mail ou chat.

Para receber envios direto do navegador, o bucket precisa de uma regra de CORS que libere o domínio do seu site. Veja o passo a passo em Exemplos de código. Um link vale no máximo 7 dias. No console, Copiar link gera um link de download de 7 dias; num arquivo público, copia o endereço público, que não expira.

Boas práticas

  • Uma chave por aplicação. Assim você revoga uma sem afetar as outras.
  • Limite as redes. Uma chave restrita às redes da aplicação não funciona se vazar.
  • Trate limites com nova tentativa. Acima do limite de tráfego da chave, o Armazém recusa a requisição com SlowDown (HTTP 503). Os SDKs já tentam de novo com espera; mantenha esse comportamento ligado.
  • Envie arquivos grandes em partes. O AWS CLI e o upload_file do boto3 dividem envios grandes automaticamente; em JavaScript, use o Upload do @aws-sdk/lib-storage. O limite é de 20 GB por arquivo.

Erros comuns

ErroCausa provável
403 AccessDeniedchave revogada, rede fora da lista da chave, nível de acesso da chave sem a operação (por exemplo, apagar com Leitura e envio), Armazém somente leitura ou operação não permitida, como tornar um arquivo público
403 SignatureDoesNotMatchsegredo errado, relógio da máquina fora de hora ou link assinado alterado
404 NoSuchBucketbucket inexistente ou nome digitado errado
404 NoSuchKeyarquivo inexistente no bucket
503 SlowDownlimite de tráfego da chave; tente de novo com espera

Próximos passos

Última atualização em

Nessa página