Usar MinIO no Node.js permite armazenar arquivos em uma plataforma compatível com a API do Amazon S3, executada em infraestrutura própria, cloud privada ou ambiente local. A aplicação pode trabalhar com buckets, objects, URLs assinadas, multipart upload, versionamento e políticas de acesso.
A compatibilidade facilita reutilizar bibliotecas e padrões do ecossistema S3, mas não significa que toda configuração seja idêntica. Endpoint, path style, certificados, credenciais, recursos suportados e operação do cluster precisam ser validados. Também é necessário proteger buckets, rotacionar access keys, configurar TLS, quotas, lifecycle, replicação e observabilidade.
Neste guia, você aprenderá a conectar o Node.js ao MinIO, criar cliente com SDK oficial ou AWS SDK, enviar streams, gerar URLs assinadas, configurar segurança, executar multipart, usar Docker, aplicar multi-tenancy e testar o fluxo.
O que é MinIO?
MinIO oferece object storage compatível com a API S3. A documentação de desenvolvedores do MinIO descreve SDKs e integração. A documentação de compatibilidade S3 ajuda a identificar operações suportadas.
Quando usar?
- object storage on-premises;
- ambientes sem acesso ao S3 público;
- desenvolvimento local;
- cloud privada;
- data lake;
- arquivos de aplicações;
- backups e artefatos.
MinIO não é filesystem compartilhado
Objetos são acessados por API. Não dependa de operações POSIX, locks de arquivo ou renomeações atômicas como em um disco local.
Compatibilidade S3
Aplicações que usam o AWS SDK podem apontar para um endpoint MinIO com poucas alterações, mas recursos específicos da AWS podem não existir.
SDK oficial
npm install minioCriando o cliente MinIO
import * as Minio from 'minio';
const client = new Minio.Client({
endPoint: process.env.MINIO_HOST,
port: Number(process.env.MINIO_PORT || 443),
useSSL: true,
accessKey: process.env.MINIO_ACCESS_KEY,
secretKey: process.env.MINIO_SECRET_KEY
});Não coloque as credenciais no código. Consulte Gestão de Segredos no Node.js.
AWS SDK v3
import { S3Client } from '@aws-sdk/client-s3';
const s3 = new S3Client({
endpoint: process.env.MINIO_ENDPOINT,
region: 'us-east-1',
forcePathStyle: true,
credentials: {
accessKeyId: process.env.MINIO_ACCESS_KEY,
secretAccessKey: process.env.MINIO_SECRET_KEY
}
});forcePathStyle costuma ser necessário quando o ambiente não configura DNS por bucket.
Endpoint
Use HTTPS e hostname confiável:
https://storage.example.internalNão desabilite validação TLS para resolver certificado interno. Instale a CA apropriada.
Certificados internos
Configure a CA no processo, imagem ou sistema. Evite NODE_TLS_REJECT_UNAUTHORIZED=0, pois isso desabilita validação para várias conexões.
Bucket
const exists = await client.bucketExists('uploads');
if (!exists) {
await client.makeBucket('uploads');
}Em produção, buckets geralmente são provisionados pela infraestrutura, não criados automaticamente por toda instância.
Upload de Buffer
await client.putObject(
'uploads',
objectKey,
buffer,
buffer.length,
{
'Content-Type': detectedMimeType
}
);Upload de stream
await client.putObject(
'uploads',
objectKey,
readableStream,
size,
metadata
);Use streams para evitar carregar arquivos grandes em memória. Consulte Streams no Node.js.
Key do objeto
tenants/{tenantId}/documents/{documentId}A key deve ser criada pela aplicação. Não concatene caminho fornecido pelo usuário.
Nome original
Salve no banco ou metadata depois de limitar tamanho. Não use como identificador único.
Content-Type
Detecte o formato real. O header enviado pelo cliente pode ser falso.
Limite de tamanho
Defina limites no parser, stream, API e quota do tenant. Não confie apenas no Content-Length.
Download
const stream = await client.getObject(
'uploads',
objectKey
);
stream.pipe(response);Aplique autorização antes de acessar o object storage.
Presigned GET
const url = await client.presignedGetObject(
'uploads',
objectKey,
60
);Use prazo curto e não registre a URL completa.
Presigned PUT
const url = await client.presignedPutObject(
'uploads',
objectKey,
300
);O cliente envia diretamente ao MinIO. A API deve confirmar tamanho e metadata depois.
Upload pendente
Crie um registro no banco:
id | tenant_id | object_key | status | expires_atDepois do upload, consulte statObject e marque como confirmado.
statObject
const stat = await client.statObject(
'uploads',
objectKey
);Compare tamanho, ETag e metadata esperados.
Bucket privado
Não use acesso anônimo amplo. Downloads devem passar por autorização ou URLs temporárias.
Policies
MinIO permite políticas compatíveis com IAM. Uma credencial deve acessar apenas buckets e prefixos necessários.
Access key por serviço
Não compartilhe uma root key entre aplicações. Crie identidade por workload, com política mínima.
Root access
Credenciais administrativas não devem ser usadas pelo runtime da API. Proteja e limite o root.
STS
Quando disponível no desenho, use credenciais temporárias emitidas por STS. Elas reduzem o impacto de vazamento.
OpenID Connect
MinIO pode integrar identidade e políticas com provedores OIDC. Avalie para usuários e workloads sem chaves permanentes.
Multi-tenancy
Opções de isolamento:
- prefixo por tenant;
- bucket por tenant;
- credencial por tenant;
- deployment separado para requisitos fortes.
Consulte Multi-Tenancy no Node.js.
Prefixo por tenant
É simples, mas políticas e consultas devem sempre incluir o prefixo. O tenant vem da identidade autenticada.
Bucket por tenant
Facilita quotas e lifecycle isolados, mas milhares de buckets aumentam operação. Verifique limites e governança.
Quotas
Defina limites de armazenamento por bucket ou tenant. A API também deve controlar tamanho diário e quantidade de objetos.
Versionamento
Habilite quando precisar recuperar sobrescritas ou exclusões. Lifecycle deve remover versões antigas conforme a política.
Object Lock
Imutabilidade ajuda em backups e auditoria. Planeje retenção, legal hold e capacidade antes de ativar.
Lifecycle
Regras podem expirar objetos temporários, versões antigas e multipart incompletos.
Multipart upload
Arquivos grandes são divididos em partes. O SDK pode gerenciar o fluxo, mas você deve limitar concorrência e abortar falhas.
Uploads incompletos
Configure lifecycle para limpar partes abandonadas. Elas consomem espaço mesmo sem objeto final.
Checksums
Não presuma que ETag é sempre MD5. Multipart e configurações de criptografia alteram o significado.
Criptografia em trânsito
Use TLS entre cliente, load balancer e servidores MinIO. Em redes internas, não trate HTTP como seguro por padrão.
Criptografia em repouso
Configure server-side encryption e KMS conforme a edição e o ambiente. Separe chaves dos dados.
MinIO KMS
Um serviço de chaves permite rotação e auditoria. A indisponibilidade do KMS pode afetar acesso aos objetos, portanto monitore.
Docker para desenvolvimento
services:
minio:
image: minio/minio
command: server /data --console-address :9001
environment:
MINIO_ROOT_USER: devadmin
MINIO_ROOT_PASSWORD: devpasswordUse apenas valores de desenvolvimento e não exponha portas publicamente.
Volumes
Um container sem volume perde dados ao ser recriado. Para produção, siga a arquitetura distribuída e os requisitos oficiais.
Produção não é Docker Compose simples
Object storage precisa de discos, erasure coding, rede, capacidade, backup e procedimento de recuperação. Não trate um container único como serviço durável.
Erasure coding
MinIO distribui dados e paridade entre discos. O desenho de hardware influencia tolerância a falhas e desempenho.
Replicação
Bucket e site replication podem proteger contra falha de local, conforme a edição e topologia. Teste recuperação, não apenas configuração.
Load balancer
Distribua tráfego para os nós conforme as recomendações. Preserve headers e aumente limites de upload de maneira controlada.
Timeouts
Configure conexão, upload e resposta. Arquivos grandes precisam de prazos compatíveis, sem permitir sockets infinitos.
Keep-alive
Reutilize conexões para reduzir handshake. Consulte HTTP Agent no Node.js.
Retries
Use retry com backoff para falhas transitórias, mas não repita indefinidamente. Consulte Retry com Backoff no Node.js.
SSRF
Se endpoint MinIO é configurável, não aceite URL do usuário. Use configuração fixa e proteja contra SSRF no Node.js.
Processamento de arquivos
Coloque novos objetos em quarentena, analise malware e valide formato antes de liberar download.
Eventos
Bucket notifications podem publicar eventos em Kafka, NATS, webhook e outros destinos. Consumidores precisam ser idempotentes.
Consulte Idempotência em APIs Node.js.
Logs
Registre operação, bucket lógico, key parcial, tamanho e duração. Não registre secret key ou URL assinada.
Veja Logs com Pino no Node.js.
Audit logs
MinIO oferece auditoria de operações. Proteja o destino e correlacione com request ID da aplicação.
Métricas
Monitore capacidade, erros, latência, tráfego, healing, discos, uploads incompletos, KMS e replication lag.
Health checks
Use endpoints de readiness e liveness apropriados. Não marque todo o cluster saudável apenas porque uma porta responde.
Backup
Replicação não substitui backup imutável em todos os cenários. Defina recuperação contra exclusão, corrupção e comprometimento.
Teste de compatibilidade
Se a aplicação precisa funcionar com S3 e MinIO, execute a mesma suíte contra ambos. Não assuma compatibilidade completa.
Teste de URL assinada
Gere upload, envie objeto, confirme e depois teste expiração e alteração da key.
Teste de policy
A credencial do serviço deve falhar ao acessar outro bucket ou prefixo.
Teste de TLS
Um certificado inválido deve causar falha. Não aceite fallback para HTTP.
Teste de multipart
Interrompa partes, retome e aborte. Verifique limpeza de uploads incompletos.
Teste de falha de nó
Em ambiente distribuído, simule perda de nó e disco conforme procedimento seguro.
Erros comuns
- Usar root key na aplicação: comprometimento ganha controle total.
- Desabilitar TLS: credenciais trafegam expostas.
- Assumir compatibilidade completa: recursos falham em produção.
- Container único como produção: não há resiliência.
- Bucket público: objetos vazam.
- Sem lifecycle: versões e partes crescem.
- URL assinada longa: acesso temporário vira persistente.
Boas práticas
- Use HTTPS.
- Crie credencial por serviço.
- Aplique policy mínima.
- Mantenha buckets privados.
- Gere keys no servidor.
- Use streams.
- Configure versioning e lifecycle.
- Monitore capacidade e healing.
- Teste S3 e MinIO.
- Planeje recuperação.
Conclusão
Usar MinIO no Node.js oferece object storage compatível com S3 em infraestrutura controlada. O SDK oficial e o AWS SDK permitem trabalhar com streams, buckets e URLs assinadas.
A operação segura exige TLS, credenciais mínimas, buckets privados, quotas, lifecycle e cluster resiliente. Com testes de compatibilidade, observabilidade e recuperação, MinIO pode atender aplicações Node.js sem transformar um storage local em um ponto único de falha.




