ลดความยุ่งยากในการใช้คลาวด์ พูดคุยกับเจ้าหน้าที่

ติดตั้ง MinIO ทำ Object Storage ส่วนตัวที่เข้ากับ S3
Home ติดตั้ง MinIO ทำ Object Storage ส่วนตัวที่เข้ากับ S3

ติดตั้ง MinIO ทำ Object Storage ส่วนตัวที่เข้ากับ S3

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

ขั้นตอนที่ 6: ต่อกับแอปพลิเคชัน

ตั้งค่าเหมือนใช้ S3 ทุกประการ เพียงระบุ endpoint

// Node.js ด้วย AWS SDK v3
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'

const s3 = new S3Client({
  endpoint: 'https://s3.example.com',
  region: 'us-east-1',
  credentials: {
    accessKeyId: process.env.MINIO_ACCESS_KEY,
    secretAccessKey: process.env.MINIO_SECRET_KEY,
  },
  forcePathStyle: true,
})

ตัวเลือก forcePathStyle: true จำเป็น เพราะ MinIO ใช้รูปแบบ URL แบบพาธ ไม่ใช่แบบชื่อ Bucket นำหน้าโดเมนเหมือน S3

สำหรับ WordPress หรือ Laravel ตั้งค่าในไฟล์คอนฟิกด้วยหลักการเดียวกัน

AWS_ACCESS_KEY_ID=appuser
AWS_SECRET_ACCESS_KEY=รหัสผ่านของแอป
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=uploads
AWS_ENDPOINT=https://s3.example.com
AWS_USE_PATH_STYLE_ENDPOINT=true

ขั้นตอนที่ 7: ตั้งนโยบายอายุไฟล์

ลบไฟล์เก่าอัตโนมัติ เหมาะกับ Bucket ที่เก็บข้อมูลสำรองหรือไฟล์ชั่วคราว

cat > /tmp/lifecycle.json <<'EOF'
{
  "Rules": [
    {
      "ID": "expire-old-backups",
      "Status": "Enabled",
      "Expiration": { "Days": 30 }
    }
  ]
}
EOF

mc ilm import tdc/backups < /tmp/lifecycle.json
mc ilm ls tdc/backups

เปิดการเก็บหลายรุ่นของไฟล์เดียวกัน ป้องกันการเขียนทับหรือลบโดยไม่ตั้งใจ

mc version enable tdc/uploads
mc version info tdc/uploads

ขั้นตอนที่ 8: ใช้เป็นปลายทางสำรองข้อมูล

เครื่องมือสำรองข้อมูลส่วนใหญ่รองรับ S3 อยู่แล้ว ใช้ MinIO เป็นปลายทางได้ทันที

# restic
export RESTIC_REPOSITORY="s3:https://s3.example.com/backups/web1"
export AWS_ACCESS_KEY_ID="appuser"
export AWS_SECRET_ACCESS_KEY="รหัสผ่าน"
restic init
restic backup /var/www

# คัดลอกไฟล์ด้วย mc โดยตรง
mc cp --recursive /var/backups/mysql/ tdc/backups/mysql/
mc mirror --overwrite /var/backups/ tdc/backups/

ปัญหาที่พบบ่อย

อัปโหลดไฟล์ใหญ่แล้วล้มเหลว

ตรวจว่า Nginx ตั้ง client_max_body_size 0 และปิด proxy_request_buffering แล้ว การเปิด buffering ทำให้ Nginx ต้องเก็บไฟล์ทั้งก้อนก่อนส่งต่อ ซึ่งกินดิสก์และช้า

หน้าจอจัดการเปิดแล้วเด้งกลับ

ตรวจว่า MINIO_BROWSER_REDIRECT_URL ตรงกับโดเมนที่ใช้จริง และแยกจาก MINIO_SERVER_URL

แอปเชื่อมต่อแล้วขึ้น SignatureDoesNotMatch

มักเกิดจากไม่ได้ตั้ง forcePathStyle หรือเวลาบนเครื่องคลาดเคลื่อน ตรวจด้วย timedatectl เพราะลายเซ็นของ S3 ผูกกับเวลา

ดิสก์เต็ม

ตรวจขนาดแต่ละ Bucket ด้วย mc du tdc และตรวจว่าเปิดการเก็บหลายรุ่นไว้หรือไม่ ซึ่งทำให้ไฟล์ที่ถูกลบยังกินพื้นที่อยู่ ตั้งนโยบายอายุไฟล์ให้ลบรุ่นเก่าด้วย

ต้องการ Object Storage ที่ข้อมูลอยู่ในประเทศไทย ติดต่อ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/

ผู้ให้บริการคลาวด์ไทย
เพื่อธุรกิจของคนไทย

"มุ่งมั่น" และ "มั่นคง"
พร้อมรับมือทุกการเติบโต
Trust Cloud
คลาว์ที่ปลอดภัย
คือรากฐานที่มั่นคง
cloud security