คำตอบสั้น ๆ: สร้างที่เก็บไฟล์แบบ Object Storage บนเซิร์ฟเวอร์ตัวเอง ใช้กับไลบรารีที่รองรับ S3 ได้ทันที เหมาะกับไฟล์ที่ผู้ใช้อัปโหลดและข้อมูลสำรอง
คู่มือนี้อธิบาย Object Storage ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย
Object Storage ต่างจากระบบไฟล์ธรรมดาตรงที่เข้าถึงผ่าน HTTP API ขยายได้ไม่จำกัด และเหมาะกับไฟล์ที่เขียนครั้งเดียวอ่านหลายครั้ง เช่น รูปที่ผู้ใช้อัปโหลด ไฟล์แนบ และข้อมูลสำรอง
MinIO ใช้ API แบบเดียวกับ Amazon S3 ทุกประการ จึงต่อกับไลบรารีและเครื่องมือที่รองรับ S3 ได้ทันทีโดยไม่ต้องแก้โค้ด เพียงเปลี่ยน endpoint ข้อดีคือข้อมูลอยู่บนเซิร์ฟเวอร์ของคุณในประเทศไทยและไม่มีค่าใช้จ่ายตามปริมาณการโอนข้อมูล
สิ่งที่ต้องเตรียม
- Cloud VPS ที่มีดิสก์แยกสำหรับเก็บข้อมูล
- สองโดเมนย่อย หนึ่งสำหรับ API และหนึ่งสำหรับหน้าจอจัดการ
- Docker และ Docker Compose
ขั้นตอนที่ 1: ติดตั้ง
sudo mkdir -p /opt/minio
sudo mkdir -p /srv/minio-data
cd /opt/minio
sudo nano .env
MINIO_ROOT_USER=tdcadmin
MINIO_ROOT_PASSWORD=รหัสผ่านที่ยาวอย่างน้อย 16 ตัวอักษร
MINIO_SERVER_URL=https://s3.example.com
MINIO_BROWSER_REDIRECT_URL=https://minio.example.com
sudo chmod 600 .env
sudo nano docker-compose.yml
services:
minio:
image: quay.io/minio/minio:latest
container_name: minio
restart: unless-stopped
command: server /data --console-address ":9001"
ports:
- "127.0.0.1:9000:9000"
- "127.0.0.1:9001:9001"
volumes:
- /srv/minio-data:/data
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
MINIO_SERVER_URL: ${MINIO_SERVER_URL}
MINIO_BROWSER_REDIRECT_URL: ${MINIO_BROWSER_REDIRECT_URL}
TZ: Asia/Bangkok
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
retries: 3
sudo docker compose up -d
sudo docker compose logs -f minio
MinIO ใช้สองพอร์ต 9000 คือ API ที่แอปเรียกใช้ และ 9001 คือหน้าจอจัดการสำหรับคน ทั้งสองต้องแยกโดเมนกันเพราะ MinIO ต้องรู้ว่าคำขอไหนเป็นของอะไร
ขั้นตอนที่ 2: ตั้ง Nginx สองโดเมน
sudo nano /etc/nginx/sites-available/minio
server {
listen 80;
server_name s3.example.com;
# ไฟล์ขนาดใหญ่ ปิดการจำกัดขนาด
client_max_body_size 0;
ignore_invalid_headers off;
proxy_buffering off;
proxy_request_buffering off;
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_connect_timeout 300;
proxy_http_version 1.1;
chunked_transfer_encoding off;
}
}
server {
listen 80;
server_name minio.example.com;
# จำกัดหน้าจอจัดการให้เข้าได้เฉพาะจากออฟฟิศ
allow 203.0.113.0/24;
deny all;
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-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
sudo ln -s /etc/nginx/sites-available/minio /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d s3.example.com -d minio.example.com --agree-tos -m [email protected] --redirect
ขั้นตอนที่ 3: ติดตั้งเครื่องมือบรรทัดคำสั่ง
curl -sO https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/
mc alias set tdc https://s3.example.com tdcadmin 'รหัสผ่าน'
mc admin info tdc
ขั้นตอนที่ 4: สร้าง Bucket และกำหนดสิทธิ์
# สร้าง Bucket
mc mb tdc/uploads
mc mb tdc/backups
mc ls tdc
# Bucket สำหรับไฟล์สาธารณะ เช่น รูปสินค้า
mc anonymous set download tdc/uploads
# Bucket สำหรับข้อมูลสำรอง ต้องเป็นส่วนตัวเสมอ
mc anonymous set none tdc/backups
mc anonymous get tdc/backups
ตรวจสอบสิทธิ์ทุก Bucket หลังสร้างเสมอ Bucket ที่เปิดสาธารณะโดยไม่ตั้งใจคือสาเหตุของการรั่วไหลข้อมูลที่พบบ่อยที่สุดในระบบ Object Storage ทั่วโลก
ขั้นตอนที่ 5: สร้างผู้ใช้สำหรับแอปพลิเคชัน
อย่าให้แอปใช้บัญชีผู้ดูแล สร้างผู้ใช้แยกพร้อมสิทธิ์เฉพาะ Bucket ที่ต้องใช้
mc admin user add tdc appuser 'รหัสผ่านของแอป'
# สร้างนโยบายที่ให้สิทธิ์เฉพาะ Bucket uploads
cat > /tmp/uploads-policy.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": ["arn:aws:s3:::uploads/*"]
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": ["arn:aws:s3:::uploads"]
}
]
}
EOF
mc admin policy create tdc uploads-rw /tmp/uploads-policy.json
mc admin policy attach tdc uploads-rw --user appuser
mc admin user info tdc appuser