MinIO self-hosted na VPS
MinIO é o storage de objetos S3-compatível open-source mais rápido do mundo — substitui o Amazon S3 para arquivos, backups e assets da aplicação rodando inteiramente na sua VPS. Com a mesma API do S3, você troca apenas o endpoint e continua usando o AWS SDK sem mudar código.
Instalar MinIO com Docker Compose
Stack completa com MinIO e configuração de produção:
yaml
# docker-compose.yml
services:
minio:
image: minio/minio:latest
restart: always
command: server /data --console-address ":9001"
ports:
- "127.0.0.1:9000:9000" # API S3
- "127.0.0.1:9001:9001" # Console web
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
MINIO_BROWSER_REDIRECT_URL: https://minio-console.seudominio.com.br
volumes:
- minio_data:/data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 20s
retries: 3
volumes:
minio_data:Configurar Nginx para API e Console
Dois virtual hosts: um para a API S3 e outro para o console web:
nginx
# /etc/nginx/conf.d/minio.conf
# API S3 (para as aplicações)
server {
listen 443 ssl http2;
server_name s3.seudominio.com.br;
ssl_certificate /etc/letsencrypt/live/s3.seudominio.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/s3.seudominio.com.br/privkey.pem;
ignore_invalid_headers off;
client_max_body_size 0; # sem limite de tamanho
proxy_buffering off;
proxy_request_buffering off;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300s;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
chunked_transfer_encoding off;
}
}
# Console web (restrito por IP)
server {
listen 443 ssl http2;
server_name minio-console.seudominio.com.br;
ssl_certificate /etc/letsencrypt/live/minio-console.seudominio.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/minio-console.seudominio.com.br/privkey.pem;
allow 177.10.0.1;
deny all;
location / {
proxy_pass http://127.0.0.1:9001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
}
}Criar buckets e políticas via mc (MinIO Client)
CLI do MinIO para gerenciar buckets e permissões:
bash
# Instalar mc (MinIO Client)
curl -O https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/
# Configurar alias para o servidor
mc alias set myminio https://s3.seudominio.com.br \
SEU_ROOT_USER SEU_ROOT_PASSWORD
# Verificar conexão
mc ready myminio
# Criar buckets
mc mb myminio/uploads # uploads de usuários
mc mb myminio/backups # backups de banco de dados
mc mb myminio/assets # assets públicos
# Tornar bucket público (para assets estáticos acessíveis sem autenticação):
mc anonymous set public myminio/assets
# Criar usuário específico para a aplicação (menor privilégio):
mc admin user add myminio app_user senha_app_user
mc admin policy attach myminio readwrite --user app_user
# Listar buckets e objetos:
mc ls myminio
mc ls myminio/uploads/Integrar com Node.js (AWS SDK)
Usar o MinIO como drop-in replacement do S3 na aplicação:
typescript
// Node.js — usando AWS SDK v3 com MinIO
import { S3Client, PutObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
const s3 = new S3Client({
endpoint: 'https://s3.seudominio.com.br', // URL do MinIO
region: 'us-east-1', // qualquer valor
credentials: {
accessKeyId: process.env.MINIO_ACCESS_KEY!,
secretAccessKey: process.env.MINIO_SECRET_KEY!,
},
forcePathStyle: true, // OBRIGATÓRIO para MinIO
})
// Upload de arquivo
async function uploadFile(key: string, body: Buffer, contentType: string) {
await s3.send(new PutObjectCommand({
Bucket: 'uploads',
Key: key,
Body: body,
ContentType: contentType,
}))
return `https://s3.seudominio.com.br/uploads/${key}`
}
// URL pré-assinada para download temporário (1 hora)
async function getPresignedUrl(key: string) {
return getSignedUrl(s3, new GetObjectCommand({
Bucket: 'uploads',
Key: key,
}), { expiresIn: 3600 })
}Dica
forcePathStyle: true é obrigatório com MinIO self-hosted — o S3 da AWS usa virtual-hosted style (bucket.s3.amazonaws.com) mas o MinIO usa path style (s3.dominio.com/bucket).
Backup e monitoramento do MinIO
Monitorar uso de storage e configurar replicação de bucket:
bash
# Ver uso de storage por bucket:
mc du myminio/uploads
mc du myminio/backups
# Replicação para outro MinIO ou S3 (DR):
mc replicate add myminio/backups \
--remote-bucket s3://meu-bucket-aws/backups \
--arn "arn:minio:replication::..." \
--priority 1
# Lifecycle policy — deletar objetos antigos automaticamente:
mc ilm rule add myminio/backups \
--expiry-days 30 # deletar após 30 dias
# Backup do volume MinIO com rsync para armazenamento externo:
rsync -av --progress /var/lib/docker/volumes/minio_data/_data/ \
usuario@backup-server:/backups/minio/
# Métricas com Prometheus:
mc admin prometheus generate myminio
# Adicionar o scrape config gerado ao prometheus.yml$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o MinIO em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.