Tự host object storage tương thích S3 với MinIO trên VPS

Bạn đang trả phí cho AWS S3, Backblaze B2 hay các dịch vụ object storage khác và muốn cắt giảm chi phí? Hoặc bạn cần một giải pháp lưu trữ dữ liệu phi cấu trúc (ảnh, video, file upload, backup) với giao diện API tương thích S3 ngay trên VPS của mình? MinIO là câu trả lời. Đây là một object storage server mã nguồn mở, tương thích với API S3 của AWS, cho phép bạn tự host hoàn toàn trên hạ tầng riêng.
Trong hướng dẫn chi tiết cho năm 2026 này, mình sẽ chỉ bạn cách cài đặt MinIO trên VPS Linux (mình sẽ dùng Ubuntu 24.04 LTS để minh họa), cấu hình HTTPS, tạo user và bucket, cũng như cách bảo mật và giám sát hệ thống object storage của bạn. Không có bước nào thừa, không có lý thuyết suông, chỉ có lệnh và file config bạn có thể copy-paste và chạy ngay.
- Bạn sẽ có một object storage server hoạt động, tương thích với hàng nghìn công cụ sử dụng S3 SDK và CLI.
- Chi phí chỉ là chi phí VPS bạn đang trả, không có phí lưu trữ hay phí request nào khác.
- Quyền kiểm soát dữ liệu ở mức tối đa, dữ liệu nằm trên ổ đĩa NVMe của bạn, không phải trên server của bên thứ ba.
Yêu cầu trước khi bắt đầu
Trước khi đi vào cài đặt, hãy chắc chắn bạn đã có sẵn những thứ sau:
- Một VPS với hệ điều hành Ubuntu 24.04 LTS hoặc bản phân phối Linux tương tự (Debian 12 phổ biến không kém), có quyền
roothoặc usersudo. - Tối thiểu 1 GB RAM cho bản dùng thử, nhưng để chạy ổn định cho production, mình khuyên bạn nên có từ 2 GB RAM trở lên. MinIO xử lý rất nhiều tác vụ I/O, vì vậy một VPS Linux dùng ổ NVMe sẽ là lựa chọn hàng đầu.
- Tên miền (domain) trỏ về IP VPS của bạn, ví dụ
s3.yourdomain.comvà bản ghi DNS A đã được cấu hình. Điều này cần thiết để có chứng chỉ SSL hợp lệ. - Có kiến thức cơ bản về dòng lệnh Linux và cấu hình Nginx hoặc Caddy.
Vì sao nên tự host object storage thay vì dùng dịch vụ đám mây?
Câu hỏi này mình nhận được rất nhiều. AWS S3 là tiêu chuẩn vàng cho object storage, nhưng chi phí cho băng thông và số lượng request có thể tăng nhanh không kiểm soát, đặc biệt với các ứng dụng có lượng truy cập lớn. Backblaze B2 rẻ hơn nhưng vẫn là chi phí định kỳ hàng tháng.
Tự host MinIO mang lại cho bạn sự tự do hoàn toàn. Bạn trả một khoản phí cố định cho VPS, mọi thứ khác là của bạn. Dữ liệu không rời khỏi hạ tầng của bạn, điều này quan trọng nếu bạn có các yêu cầu về tuân thủ dữ liệu. Bạn có thể tự do mở rộng bằng cách thêm ổ đĩa hoặc nâng cấp VPS của mình.
Tuy nhiên, tự host cũng đi kèm trách nhiệm: bạn phải tự quản lý bảo mật, sao lưu và sự sẵn sàng (availability). Nếu bạn không thoải mái với việc này, hoặc ứng dụng của bạn có yêu cầu độ trễ thấp lan truyền toàn cầu, dịch vụ quản lý sẵn vẫn đáng để chi tiền. Nhưng với nhiều dự án, đặc biệt là các sản phẩm phục vụ thị trường nội địa, một instance MinIO trên VPS là hoàn toàn hợp lý.
Bước 1 - Cài đặt MinIO Server
Có hai cách cài đặt phổ biến: dùng file binary trực tiếp (quản lý bằng systemd) hoặc dùng Docker. Mình sẽ hướng dẫn cả hai, nhưng khuyến khích bạn dùng docker-compose bởi nó đơn giản và dễ dàng nâng cấp hơn.
Cách 1: Cài đặt bằng Docker Compose. Đây là cách mình thấy sạch sẽ và dễ bảo trì nhất.
Tạo thư mục và file docker-compose.yml:
sudo mkdir -p /opt/minio/data
sudo nano /opt/minio/docker-compose.yml
Dán nội dung sau vào, nhớ thay YOUR_ACCESS_KEY và YOUR_SECRET_KEY bằng một chuỗi ký tự mạnh của riêng bạn (có thể dùng lệnh openssl rand -base64 24 để tạo):
services:
minio:
image: minio/minio:latest
container_name: minio
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: YOUR_ACCESS_KEY
MINIO_ROOT_PASSWORD: YOUR_SECRET_KEY
ports:
- "9000:9000"
- "9001:9001"
volumes:
- /opt/minio/data:/data
Chạy dịch vụ bằng lệnh:
cd /opt/minio && sudo docker compose up -d
Verify:
sudo docker compose ps
Output mong đợi sẽ hiển thị container minio ở trạng thái Up.
Cách 2: Cài đặt bằng Binary. Đây là cách truyền thống, phù hợp nếu bạn không muốn dùng Docker.
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/
Tạo user hệ thống cho MinIO và thư mục dữ liệu:
sudo useradd -r minio-user -s /sbin/nologin
sudo mkdir -p /var/lib/minio/data
Set biến môi trường và tạo file service systemd. Bạn cần tạo file /etc/default/minio:
sudo nano /etc/default/minio
Thêm nội dung:
MINIO_VOLUMES="/var/lib/minio/data"
MINIO_OPTS="--address :9000 --console-address :9001"
MINIO_ROOT_USER="YOUR_ACCESS_KEY"
MINIO_ROOT_PASSWORD="YOUR_SECRET_KEY"
Tạo file service:
sudo nano /etc/systemd/system/minio.service
Dán nội dung:
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
[Service]
User=minio-user
Group=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Kích hoạt và khởi động dịch vụ:
sudo chown -R minio-user:minio-user /var/lib/minio
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
Verify:
sudo systemctl status minio
Output mong đợi: active (running).
Bước 2 - Cấu hình Nginx làm Reverse Proxy với HTTPS
Dù cài theo cách nào, bạn cũng không nên expose MinIO trực tiếp ra ngoài bằng port. Hãy dùng Nginx hoặc Caddy để chặn các yêu cầu, cấu hình SSL và bảo vệ console. Ở đây mình dùng Nginx và Certbot của Let's Encrypt.
Cài đặt Nginx và Certbot:
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
Tạo file cấu hình cho MinIO:
sudo nano /etc/nginx/sites-available/minio
Dán nội dung sau, thay s3.yourdomain.com bằng domain của bạn:
server {
listen 80;
server_name s3.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:9000;
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_read_timeout 900;
}
}
server {
listen 443 ssl http2;
server_name s3.yourdomain.com;
client_max_body_size 500M;
location / {
proxy_pass http://127.0.0.1:9000;
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_read_timeout 900;
}
}
Kích hoạt site và cấu hình SSL:
sudo ln -s /etc/nginx/sites-available/minio /etc/nginx/sites-enabled/
sudo nginx -t
Nếu kết quả là syntax is ok, bạn reload Nginx và chạy certbot:
sudo systemctl reload nginx
sudo certbot --nginx -d s3.yourdomain.com
Certbot sẽ tự động cấu hình lại SSL cho Nginx. Verify: truy cập https://s3.yourdomain.com/minio/health/live từ trình duyệt, nếu bạn thấy dòng {"status":"alive"} thì mọi thứ đã hoạt động.
Bạn cũng nên cấu hình tương tự cho port 9001 (console) tại một domain riêng như console.yourdomain.com, hoặc chỉ đơn giản là không expose port 9001 ra ngoài internet, chỉ cho phép truy cập từ IP bạn tin cậy bằng firewall. Mình thường dùng cách thứ hai cho an toàn.
Lưu ý về firewall: Nếu bạn dùng UFW, hãy chắc chắn đã mở port 80 và 443:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
Bước 3 - Tạo user truy cập và bucket
hiếm khi dùng root user cho các ứng dụng. Hãy tạo user riêng cho từng ứng dụng với quyền tối thiểu. Trước tiên, cài đặt MinIO Client (mc) trên máy local của bạn:
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/
Trỏ mc về server MinIO của bạn:
mc alias set mys3 https://s3.yourdomain.com YOUR_ACCESS_KEY YOUR_SECRET_KEY
Bây giờ, hãy tạo một user mới có tên là app-backend:
mc admin user add mys3 app-backend YOUR_APP_SECRET_KEY
Tạo một policy cho phép user này chỉ truy cập vào các bucket bắt đầu bằng app-. Tạo file app-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListAllMyBuckets"],
"Resource": ["arn:aws:s3:::*"]
},
{
"Effect": "Allow",
"Action": ["s3:*"],
"Resource": [
"arn:aws:s3:::app-*"
]
}
]
}
Áp dụng policy này cho user:
mc admin policy create mys3 apponly /path/to/app-policy.json
mc admin user attach-policy mys3 apponly --user app-backend
Tạo bucket đầu tiên:
mc mb mys3/app-backup
Verify:
mc ls mys3
Output sẽ hiển thị bucket app-backup đã được tạo.
Bước 4 - Bảo mật dữ liệu và cấu hình sao lưu
MinIO hỗ trợ mã hóa dữ liệu tại chỗ (SSE). Bạn có thể bật mã hóa phía server bằng cách đặt biến môi trường trong file docker-compose.yml hoặc /etc/default/minio. Bạn sẽ cần một khóa mã hóa 32-byte.
MINIO_KMS_SECRET_KEY="my-minio-encryption-key:$(openssl rand -base64 32)"
Bảo mật dữ liệu không chỉ nằm ở mã hóa. Bạn cần có chiến lược sao lưu. Cách đơn giản nhất là dùng mc mirror hoặc một công cụ như restic backup dữ liệu lên S3, sao lưu vào một VPS khác hoặc một máy chủ riêng.
mc mirror --watch /local/data/directory mys3/backup
Lệnh trên sẽ đồng bộ thư mục cục bộ lên bucket sao lưu và tiếp tục theo dõi các thay đổi. Tuy nhiên, nó chạy liên tục, vì vậy bạn nên đặt trong một systemd service riêng hoặc dùng cron cho một tác vụ đồng bộ định kỳ.
Đừng quên bảo vệ dữ liệu của chính MinIO server. Nếu bạn đã có hạ tầng, hãy sử dụng tính năng Snapshot của VPS. Hầu hết các nhà cung cấp VPS hiện nay đều cung cấp tính năng này. Với VPS Linux của thueVPS, bạn có thể dùng tính năng snapshot trong bảng điều khiển để tạo bản sao thời điểm, một cách tuyệt vời để khôi phục nhanh nếu có sự cố.
Bước 5 - Giám sát và cập nhật
MinIO cung cấp dashboard để bạn theo dõi các metric như dung lượng, số lượng request, và I/O. Với bản cài Docker, bạn có thể xem log bằng lệnh:
sudo docker logs -f minio
Bạn nên bật khả năng giám sát tự động. Việc cập nhật MinIO thường xuyên là rất quan trọng. Hãy kiểm tra trang phát hành trên GitHub của dự án để nắm bắt các bản vá bảo mật. Với Docker, bạn có thể nâng cấp lên phiên bản mới nhất bằng lệnh:
cd /opt/minio && sudo docker compose pull && sudo docker compose up -d
Với bản binary, bạn tải file minio mới nhất về và thay thế vào /usr/local/bin/, sau đó chạy sudo systemctl restart minio.
Xử lý sự cố thường gặp
Lỗi 1: Không kết nối được từ ứng dụng. Kiểm tra xem ứng dụng của bạn đang trỏ đúng URL và port. Hãy chắc chắn rằng bạn đang dùng https://s3.yourdomain.com chứ không phải IP. Các SDK của AWS thường mặc định trỏ tới us-east-1; nếu bạn chỉ có một region riêng biệt, hãy cấu hình endpoint và region cho phù hợp trong SDK của bạn.
Lỗi 2: Mã lỗi SignatureDoesNotMatch. Lỗi này đến từ việc sai access key/secret key hoặc sai timezone trên máy. Hãy kiểm tra thời gian hệ thống với lệnh date, nếu sai hãy cài đặt NTP:
sudo apt install -y ntpdate
sudo ntpdate pool.ntp.org
Lỗi 3: Dữ liệu bị chậm khi upload file lớn. MinIO yêu cầu Nginx có cấu hình proxy_request_buffering off cho các file lớn. Hãy thêm dòng này vào trong block location / của file cấu hình Nginx và reload:
proxy_request_buffering off;
Lỗi 4: Trang console không mở được. Update lại MINIO_OPTS trong file cấu hình để chỉ định đúng port. Kiểm tra xem port 9001 đã được mở trong firewall chưa.
Nếu bạn chạy MinIO trên một VPS có RAM thấp, hãy xem xét việc tắt console khi không cần thiết để tiết kiệm bộ nhớ. Bạn có thể cài MinIO ở chế độ chạy chỉ server bằng cách không thêm --console-address vào lệnh khởi động.
Câu hỏi thường gặp
MinIO có hoàn toàn miễn phí không?
MinIO có phiên bản Community Edition hoàn toàn miễn phí và mã nguồn mở theo giấy phép AGPLv3. Bạn có thể dùng nó cho mục đích thương mại và lưu trữ dữ liệu. Ngoài ra còn có phiên bản Enterprise trả phí với các tính năng bổ sung như hỗ trợ từ nhà cung cấp và một số cải tiến quản trị, nhưng phiên bản community đã đủ cho hầu hết các nhu cầu.
MinIO có hoàn toàn tương thích với AWS S3 không?
MinIO được thiết kế để tương thích với hầu hết các API của AWS S3, bao gồm cả SDK của nhiều ngôn ngữ. Hầu hết các ứng dụng được viết cho AWS S3 có thể chạy ngay với MinIO chỉ bằng cách thay đổi endpoint. Một số tính năng S3 mới nhất của AWS có thể xuất hiện muộn hơn trên MinIO, nhưng với các tính năng cơ bản (bucket, object, lifecycle, versioning) thì sự tương thích là gần như hoàn toàn.
MinIO có hỗ trợ phiên bản (versioning) và khóa (locking) không?
Có, MinIO hỗ trợ cả versioning, object locking và retention policy, cho phép bạn bảo vệ dữ liệu khỏi việc ghi đè hoặc xóa nhầm. Đây là các tính năng quan trọng để tuân thủ các yêu cầu về lưu trữ dữ liệu.
Tôi có cần cấu hình RAID không?
MinIO hoạt động tốt trên nhiều ổ đĩa với tính năng erasure coding, tức là nó có thể tự phân tán dữ liệu trên nhiều ổ để chống lỗi. Tuy nhiên, nếu bạn chỉ có một VPS riêng biệt với một ổ đĩa, bạn vẫn có thể chạy MinIO, nhưng không có khả năng dự phòng dữ liệu. RAID ở cấp độ phần cứng hoặc phần mềm có thể giúp, nhưng với VPS, hàng đầu là bạn nên dựa vào cơ chế sao lưu của nhà cung cấp hoặc sao lưu định kỳ sang nơi khác.
Bài viết liên quan
- Hướng dẫn backup tự động VPS lên S3 với restic
- Quản lý Docker volume và backup dữ liệu container
- Dùng rclone backup VPS lên Google Drive
- Giám sát VPS với Prometheus và Grafana tự host


