Cài MinIO S3 Object Storage Trên VPS TrumVPS - Tự Host S3-Compatible, Thay Thế AWS S3 Tiết Kiệm 95%
AWS S3 là tiêu chuẩn vàng cho object storage. Nhưng chi phí có thể leo thang nhanh chóng: 100GB dữ liệu với 500GB bandwidth/tháng tốn khoảng $15-25/tháng (~375K-625K). Chưa kể phí request (PUT/GET/LIST), phí data transfer ra ngoài, và chi phí tăng theo thời gian.
MinIO là giải pháp object storage mã nguồn mở, hoàn toàn tương thích S3 API. Bạn có thể cài lên VPS TrumVPS chỉ từ 80K/tháng và có ngay bộ lưu trữ đối tượng mạnh mẽ, không giới hạn request, không phí egress — tiết kiệm đến 95% so với AWS S3 cho nhu cầu 100GB+.
MinIO Là Gì? Tại Sao Dev Team Nào Cũng Cần?
MinIO là high-performance object storage mã nguồn mở, tương thích hoàn toàn với Amazon S3 API. Điều này có nghĩa: mọi tool, SDK, thư viện đang dùng với AWS S3 đều hoạt động với MinIO mà không cần sửa code.
Điểm nổi bật của MinIO:
- S3 API Compatible 100%: Dùng AWS SDK (boto3, aws-sdk, minio client) không cần thay đổi
- Hiệu năng cực cao: 183 GB/s GET, 171 GB/s PUT trên 32 node NVMe — nhanh nhất trong các giải pháp open-source
- Nhẹ: Binary chỉ ~100MB, chạy được trên VPS 1GB RAM
- Erasure Coding: Bảo vệ dữ liệu như RAID nhưng linh hoạt hơn, chịu lỗi disk mà không mất data
- Bucket Versioning + Object Locking: Bảo vệ chống xóa nhầm, ransomware, tuân thủ quy định lưu trữ
- Web UI quản lý: Upload, download, preview file, quản lý bucket qua giao diện web đẹp
- IAM + Policy: Quản lý user, access key, bucket policy chi tiết như AWS IAM
- Replication + Tiering: Đồng bộ dữ liệu giữa nhiều region, tự động tier xuống cold storage
So Sánh MinIO vs AWS S3 vs CloudFlare R2 vs Backblaze B2
| Tiêu chí | MinIO (VPS TrumVPS 320K) | AWS S3 Standard | CloudFlare R2 | Backblaze B2 |
|---|---|---|---|---|
| Giá lưu trữ /TB/tháng | 320K VNĐ (cố định) | $23 (~575K) + phí | $15 (~375K) | $6 (~150K) + phí |
| Phí egress | 0đ (unmetered VPS) | $0.09/GB đầu tiên | Miễn phí | Miễn phí 3x storage |
| Phí PUT/GET request | 0đ (không giới hạn) | $0.005/1000 PUT | Miễn phí Class A | Miễn phí Class A |
| S3 API | ✅ 100% compatible | ✅ Chuẩn | ✅ Tương thích | ✅ Tương thích |
| Dữ liệu nằm ở | VPS của bạn | AWS data centers | CloudFlare edge | Backblaze DC |
| Web UI quản lý | ✅ Có sẵn | ✅ AWS Console | ✅ CloudFlare Dash | ✅ Có |
| Versioning | ✅ | ✅ | ❌ | ✅ |
| Object Locking | ✅ | ✅ | ❌ | ✅ |
| IAM/Policy | ✅ Chi tiết | ✅ IAM đầy đủ | ⚠ Token API | ⚠ Key đơn giản |
| Multi-site Replication | ✅ | ✅ Cross-region | ❌ | ❌ |
| On-premise / Hybrid | ✅ | ❌ (Cloud-only) | ❌ (Cloud-only) | ❌ (Cloud-only) |
Yêu Cầu Hệ Thống
- VPS TrumVPS gói 80K (2GB RAM, 2 CPU) — đủ cho development/testing
- VPS TrumVPS 160K+ (4GB RAM, 4 CPU) — khuyến nghị cho production
- Ubuntu 22.04 hoặc 24.04
- Ổ cứng: Tùy nhu cầu, tối thiểu 30GB cho testing, 100GB+ cho production
- Domain: 1 domain hoặc subdomain (vd: s3.yourdomain.com)
Bước 1: Cài Docker & Docker Compose
Cài Docker nếu VPS chưa có:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
Kiểm tra cài đặt:
docker --version
docker compose version
Bước 2: Tạo Docker Compose Cho MinIO
Tạo thư mục và file compose:
mkdir -p ~/minio/data
cd ~/minio
nano docker-compose.yml
Nội dung docker-compose.yml:
version: '3.8'
services:
minio:
image: quay.io/minio/minio:latest
container_name: minio
restart: always
ports:
- "9000:9000" # S3 API
- "9001:9001" # Web Console
volumes:
- ./data:/data
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: YOUR_STRONG_PASSWORD_CHANGE_ME
MINIO_BROWSER_REDIRECT_URL: https://s3.yourdomain.com
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3
YOUR_STRONG_PASSWORD_CHANGE_ME thành mật khẩu mạnh (tối thiểu 8 ký tự, có chữ hoa, chữ thường, số, ký tự đặc biệt). Đây là root credentials cho MinIO của bạn!
Bước 3: Khởi Động MinIO & Kiểm Tra
docker compose up -d
docker compose ps
docker compose logs -f
Sau khi khởi động, truy cập:
- Web Console:
http://YOUR_VPS_IP:9001— đăng nhập bằng admin / mật khẩu đã đặt - S3 API:
http://YOUR_VPS_IP:9000
brew install minio/stable/mc (macOS) hoặc wget https://dl.min.io/client/mc/release/linux-amd64/mc && chmod +x mc (Linux). Rồi: mc alias set myminio http://YOUR_VPS_IP:9000 admin YOUR_PASSWORD → mc mb myminio/test-bucket → mc ls myminio
Bước 4: Cấu Hình Nginx Reverse Proxy + SSL Let's Encrypt
Tạo file cấu hình Nginx:
sudo nano /etc/nginx/sites-available/minio
server {
listen 80;
server_name s3.yourdomain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name s3.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/s3.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/s3.yourdomain.com/privkey.pem;
client_max_body_size 10G;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
# Web Console
location / {
proxy_pass http://127.0.0.1:9001;
proxy_set_header Host $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_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# S3 API
location /api/ {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Kích hoạt site và cài SSL:
sudo ln -s /etc/nginx/sites-available/minio /etc/nginx/sites-enabled/
sudo certbot --nginx -d s3.yourdomain.com
sudo nginx -t && sudo systemctl reload nginx
Bước 5: Tạo Bucket, User & Access Key
Qua Web Console (https://s3.yourdomain.com):
- Đăng nhập → vào Buckets → Create Bucket → đặt tên (vd:
app-uploads) - Vào Access Keys → Create Access Key → tạo key cho ứng dụng
- Lưu
Access KeyvàSecret Key— chỉ hiện 1 lần! - Vào Policies → tạo policy giới hạn quyền cho bucket cụ thể
Qua CLI (mc):
# Tạo bucket
mc mb myminio/app-uploads
# Tạo user và policy
mc admin user add myminio appuser APPUSER_SECRET_KEY
mc admin policy attach myminio readwrite --user appuser
# Tạo access key cho user
mc admin user svcacct add myminio appuser \
--access-key "YOUR_APP_ACCESS_KEY" \
--secret-key "YOUR_APP_SECRET_KEY"
# Giới hạn quyền cho bucket cụ thể
cat > /tmp/app-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": ["arn:aws:s3:::app-uploads", "arn:aws:s3:::app-uploads/*"]
}
]
}
EOF
mc admin policy create myminio app-policy /tmp/app-policy.json
mc admin policy attach myminio app-policy --user appuser
Bước 6: Tích Hợp MinIO Với Ứng Dụng
Python (boto3)
import boto3
from botocore.config import Config
s3 = boto3.client('s3',
endpoint_url='https://s3.yourdomain.com',
aws_access_key_id='YOUR_ACCESS_KEY',
aws_secret_access_key='YOUR_SECRET_KEY',
config=Config(signature_version='s3v4'),
region_name='us-east-1'
)
# Upload file
s3.upload_file('local.jpg', 'app-uploads', 'photos/local.jpg')
# Generate presigned URL (7 ngày)
url = s3.generate_presigned_url('get_object',
Params={'Bucket': 'app-uploads', 'Key': 'photos/local.jpg'},
ExpiresIn=604800
)
Node.js (@aws-sdk/client-s3)
import { S3Client, PutObjectCommand, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const s3 = new S3Client({
endpoint: "https://s3.yourdomain.com",
credentials: {
accessKeyId: "YOUR_ACCESS_KEY",
secretAccessKey: "YOUR_SECRET_KEY"
},
region: "us-east-1",
forcePathStyle: true
});
// Upload
await s3.send(new PutObjectCommand({
Bucket: "app-uploads",
Key: "data/report.pdf",
Body: fileBuffer,
ContentType: "application/pdf"
}));
// Presigned URL
const url = await getSignedUrl(s3, new GetObjectCommand({
Bucket: "app-uploads",
Key: "data/report.pdf"
}), { expiresIn: 3600 });
PHP (AWS SDK)
require 'vendor/autoload.php';
use Aws\S3\S3Client;
$s3 = new S3Client([
'version' => 'latest',
'region' => 'us-east-1',
'endpoint' => 'https://s3.yourdomain.com',
'credentials' => [
'key' => 'YOUR_ACCESS_KEY',
'secret' => 'YOUR_SECRET_KEY',
],
'use_path_style_endpoint' => true,
]);
// Upload
$s3->putObject([
'Bucket' => 'app-uploads',
'Key' => 'images/avatar.png',
'Body' => fopen('/path/to/avatar.png', 'r'),
'ACL' => 'public-read',
]);
// Get object URL
$url = $s3->getObjectUrl('app-uploads', 'images/avatar.png');
Use Cases Phổ Biến Cho MinIO Trên VPS
| Use Case | Mô Tả | Tiết Kiệm So Với AWS S3 |
|---|---|---|
| 📸 Image/Video hosting | Lưu ảnh sản phẩm, video cho website/app. Presigned URL bảo mật. | ~90% (cho 200GB+) |
| 💾 Backup database tự động | mysqldump/pg_dump → MinIO bucket. Versioning chống xóa nhầm. | ~85% |
| 📊 Data lake / Analytics | Lưu Parquet/CSV files cho Spark, Presto, Trino query engine. | ~80% |
| 📱 Mobile app backend | Upload ảnh/video từ app qua S3 SDK. Tự động resize ảnh bằng event hook. | ~92% |
| 🔒 Ransomware protection | Object Locking + Versioning: dữ liệu không thể bị xóa/sửa trong thời gian lock. | ~88% |
| 🌐 CDN origin storage | MinIO làm origin cho CDN (CloudFlare, BunnyCDN). Không phí egress từ CDN. | ~75% |
| 📝 CI/CD Artifacts | Lưu build artifacts (Docker images, binaries, packages) cho GitHub Actions/GitLab CI. | ~90% |
Tự Động Backup MinIO Sang VPS Khác
Dùng mc mirror để đồng bộ dữ liệu sang backup server:
# Cài mc client trên backup VPS
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc && sudo mv mc /usr/local/bin/
# Thêm alias cho cả 2 server
mc alias set primary https://s3-primary.yourdomain.com ADMIN KEY
mc alias set backup https://s3-backup.yourdomain.com ADMIN KEY
# Mirror tất cả bucket
mc mirror primary/ backup/ --watch --remove
# Cron job mirror hàng ngày
0 3 * * * mc mirror primary/app-uploads backup/app-uploads --overwrite
mc admin replicate add primary backup. Dữ liệu, user, policy, bucket được đồng bộ tự động 2 chiều.
Monitoring & Logging MinIO
Theo dõi tình trạng MinIO với Prometheus endpoint có sẵn:
# Thêm vào docker-compose.yml
environment:
MINIO_PROMETHEUS_AUTH_TYPE: public
# MinIO expose metrics tại http://VPS_IP:9000/minio/v2/metrics/cluster
# Import Grafana dashboard ID: 13502
Kiểm tra logs:
docker compose logs -f minio
# Hoặc xem audit log
mc admin trace myminio
Các Tính Năng Nâng Cao
Bucket Lifecycle - Tự Động Xóa File Cũ
mc ilm rule add myminio/app-uploads --expire-days 90
mc ilm rule add myminio/logs --expire-days 30 --noncurrent-expire-days 7
Object Locking (WORM) - Chống Ransomware
# Tạo bucket với object locking
mc mb --with-lock myminio/immutable-backups
# Set retention 30 ngày (không thể xóa/sửa trong 30 ngày)
mc retention set --default GOVERNANCE 30d myminio/immutable-backups
Event Notifications - Webhook, Kafka, Redis
# Gửi webhook khi có file upload mới
mc event add myminio/app-uploads arn:minio:sqs::WEBHOOK:webhook \
--event put,delete \
--webhook-endpoint https://your-app.com/api/minio-events
So Sánh Chi Phí Thực Tế: MinIO vs AWS S3
| Kịch Bản | MinIO (VPS TrumVPS) | AWS S3 Standard | Tiết Kiệm |
|---|---|---|---|
| 100GB + 200GB egress/tháng | 160K (VPS 4GB) | ~$46/tháng (1.15M) | 86% |
| 500GB + 500GB egress/tháng | 320K (VPS 8GB) | ~$105/tháng (2.6M) | 88% |
| 1TB + 1TB egress/tháng | 560K (VPS 16GB) | ~$200/tháng (5M) | 89% |
| 5TB + 2TB egress/tháng | 1.1M (VPS 32GB) | ~$490/tháng (12.2M) | 91% |
Câu Hỏi Thường Gặp
MinIO có thực sự thay thế được AWS S3 cho production không?
Có. MinIO được dùng trong production bởi các công ty lớn như Walmart, Cisco, Verizon. Miễn là bạn có backup và monitoring tốt, MinIO đáp ứng được 99% nhu cầu S3 thông thường. Điểm AWS S3 vượt trội là 11 9's durability (99.999999999%) trên multi-AZ — điều mà 1 VPS đơn lẻ không thể đạt được. Giải pháp: chạy 2-3 node MinIO cluster trên các VPS khác region + erasure coding.
Nếu VPS hỏng thì sao? Có mất dữ liệu không?
Đây là rủi ro cần quản lý. Khuyến nghị:
- Backup off-site:
mc mirrorsang 1 VPS khác hoặc cloud storage (Backblaze B2, Wasabi) hàng ngày - Erasure Coding: Chạy 4+ node MinIO cluster: chịu được mất 2 node
- Object Versioning: Giữ lịch sử các phiên bản file, chống xóa nhầm
Tôi có thể dùng MinIO với WordPress không?
Có, qua plugin WP Offload Media hoặc Media Cloud. Cấu hình S3 endpoint → https://s3.yourdomain.com, chọn custom S3-compatible provider. Tất cả ảnh upload sẽ được lưu vào MinIO.