ติดตั้ง MinIO บน VPS Ubuntu 24.04 ทำ S3 ใช้เอง
สร้าง object storage แบบโฮสต์เองบน Ubuntu 24.04 VPS ด้วย MinIO พร้อม binary ที่ตรวจสอบแล้ว, systemd, คำสั่ง mc, presigned URL และปลายทางสำรองข้อมูลของ restic
MinIO ให้พื้นที่จัดเก็บอ็อบเจ็กต์แบบโฮสต์เองแก่คุณอย่างไร
MinIO คือพื้นที่จัดเก็บอ็อบเจ็กต์แบบโฮสต์เองที่รองรับ Amazon S3 API คุณสามารถกำหนดให้ restic หรือ S3 SDK ใด ๆ เชื่อมต่อกับเซิร์ฟเวอร์ของคุณเองได้ โดยเปลี่ยนการตั้งค่า endpoint เพียงรายการเดียว จากนั้นไคลเอ็นต์จะไม่สามารถแยกความแตกต่างได้ คู่มือนี้จะสร้างโหนดเดี่ยวบน Ubuntu 24.04 ซึ่งประกอบด้วยไบนารีที่ผ่านการตรวจสอบ ผู้ใช้ระบบเฉพาะ unit ของ systemd ที่ไม่นำข้อมูลรับรอง root ไปเก็บไว้ในไฟล์ unit และ bucket ที่ restic ใช้สำหรับสำรองข้อมูล
S3 (simple storage service) คือ API แบบ HTTP ไม่ใช่ระบบไฟล์ คุณใช้ PUT อ็อบเจ็กต์ลงใน bucket ภายใต้ key แล้วใช้ GET เพื่อดึงอ็อบเจ็กต์กลับมา โดยไม่มีการเขียนข้อมูลเพียงบางส่วนและไม่มีการเปลี่ยนชื่อ เครื่องมือสำรองข้อมูลชอบรูปแบบนี้ เพราะอ็อบเจ็กต์จะถูกส่งมาครบถ้วนหรือไม่ก็ไม่ถูกส่งมาเลย
โหนดหนึ่งโหนดจะเก็บข้อมูลของคุณไว้เพียง 1 ชุด นี่คือข้อแลกเปลี่ยนที่คุณเลือก คุณจะได้ endpoint ของ S3 ที่ควบคุมเองในต้นทุนเทียบเท่า VPS และต้องรับผิดชอบงานทั้งหมดที่ผู้ให้บริการคลาวด์เคยดำเนินการให้ ตั้งแต่การเปลี่ยนดิสก์ที่เสียไปจนถึงการอัปเดตซอฟต์แวร์เซิร์ฟเวอร์ ส่วนใกล้ท้ายเอกสารจะอธิบายอย่างชัดเจนว่าข้อแลกเปลี่ยนนี้เหมาะสมเมื่อใด
สถานะของ MinIO community edition ในเดือนกรกฎาคม 2026
อ่านส่วนนี้ก่อนนำไปใช้งาน เนื่องจากมีการเปลี่ยนแปลงเมื่อไม่นานมานี้ ในเดือนพฤษภาคม 2025 MinIO ได้ลบฟีเจอร์การดูแลระบบออกจาก web console ใน community edition สิ่งที่ยังคงใช้งานผ่านเบราว์เซอร์ได้คือ object browser ดังนั้นให้จัดการ buckets และ access keys ด้วย mc command line client แทน
ต่อมาในปี 2025 MinIO หยุดเผยแพร่ community binaries ที่คอมไพล์ไว้ล่วงหน้า README ของโครงการระบุในขณะนี้ว่า community edition เผยแพร่เป็น source code เท่านั้น URL สำหรับดาวน์โหลดแบบเดิมยังคงใช้งานได้ โดย ณ เดือนกรกฎาคม 2026 URL เหล่านั้นให้บริการ server build RELEASE.2025-09-07T16-13-09Z และ client build RELEASE.2025-08-13T08-35-41Z และยังไม่มี community build รุ่นใหม่กว่านี้ ดังนั้น binary ด้านล่างมีอยู่จริงและสามารถทำงานได้ แต่เป็นรุ่นที่หยุดการอัปเดตแล้ว Security fixes ที่เผยแพร่หลังเดือนกันยายน 2025 ไม่รวมอยู่ใน binary นี้
ข้อเท็จจริงนี้เป็นตัวกำหนดแนวทางของส่วนที่เหลือในคู่มือนี้ นี่คือเหตุผลที่ MinIO ในคู่มือนี้รับการเชื่อมต่อที่ 127.0.0.1 และเข้าถึงอินเทอร์เน็ตได้ผ่าน proxy ที่คุณควบคุมเท่านั้น หากต้องการติดตาม security fixes ให้ build จาก source โดย vendor README มีคำสั่งเดียวคือ go install github.com/minio/minio@latest ซึ่งต้องใช้ Go toolchain และเขียน binary ไปที่ ~/go/bin/minio ติดตั้ง binary นี้ไปที่ /usr/local/bin/minio แล้วขั้นตอนอื่นทั้งหมดในคู่มือนี้ยังคงเหมือนเดิม
ติดตั้งไบนารี MinIO และตรวจสอบการดาวน์โหลด
ดาวน์โหลดรีลีสที่ระบุเวอร์ชันไว้และค่า checksum ที่เผยแพร่ไว้ แฟล็ก -f ทำให้ curl ล้มเหลวเมื่อเกิดข้อผิดพลาด HTTP แทนที่จะบันทึกหน้าแสดงข้อผิดพลาดด้วยชื่อไฟล์ที่คุณระบุ ซึ่งเป็นสาเหตุที่ผู้ใช้ติดตั้งหน้า 404 แล้วสงสัยว่าเหตุใดจึงเรียกใช้ไม่ได้
cd /tmp
REL=RELEASE.2025-09-07T16-13-09Z
curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.$REL" -o minio
curl -fsSL "https://dl.min.io/server/minio/release/linux-amd64/archive/minio.$REL.sha256sum" -o minio.sha256sumเปรียบเทียบค่า hash ทั้งสองค่า และเปรียบเทียบเฉพาะค่า hash เท่านั้น
published=$(awk '{print $1}' minio.sha256sum)
downloaded=$(sha256sum minio | awk '{print $1}')
[ "$published" = "$downloaded" ] && echo "checksum ok"อย่าใช้ sha256sum -c minio.sha256sum ในกรณีนี้ ป้ายกำกับที่เขียนต่อท้ายค่า hash ในไฟล์นั้นคือ minio.RELEASE.2025-09-07T16-13-09Z แต่เราบันทึกไฟล์ที่ดาวน์โหลดเป็น minio ดังนั้น -c จึงค้นหาไฟล์ที่ไม่มีอยู่ ระบบรายงาน No such file or directory แล้วตามด้วย WARNING: 1 listed file could not be read ซึ่งดูเหมือนการดาวน์โหลดเสียหาย แต่ความจริงไม่ใช่ ป้ายกำกับเป็นเพียงชื่อ ค่า hash คือส่วนที่ให้หลักประกัน
ควรเข้าใจอย่างชัดเจนว่าการตรวจสอบนี้ยืนยันอะไร ไบนารีและค่า hash มาจากผู้จัดจำหน่ายรายเดียวกันผ่านการเชื่อมต่อเดียวกัน ดังนั้นการจับคู่ที่ตรงกันจึงยืนยันได้ว่าการดาวน์โหลดเสร็จสมบูรณ์และไม่ได้รับความเสียหายหรือถูกแก้ไขระหว่างส่งข้อมูล แต่ไม่สามารถยืนยันได้ว่าผู้จัดจำหน่ายน่าเชื่อถือ นั่นเป็นอีกประเด็นหนึ่ง และไม่มีคำสั่ง sha256sum ใดแก้ปัญหานี้ได้
sudo install -o root -g root -m 755 minio /usr/local/bin/minio
minio --versionminio --version แสดง minio version RELEASE.2025-09-07T16-13-09Z ตามด้วยบรรทัดข้อมูลบิลด์อีกสองสามบรรทัด หากพบ Permission denied ในกรณีนี้ แสดงว่าโหมดไม่ถูกต้อง และ command not found หมายความว่า /usr/local/bin ไม่อยู่ใน PATH ของคุณ
สร้างผู้ใช้ระบบและไดเรกทอรีข้อมูล
MinIO รับการอัปโหลดจากเครือข่าย จึงไม่ควรทำงานในฐานะ root กำหนดบัญชีที่ไม่มีไดเรกทอรี home และไม่มี shell สำหรับเข้าสู่ระบบให้กับบัญชีนี้
sudo groupadd -r minio-user
sudo useradd -M -r -g minio-user -s /usr/sbin/nologin minio-user
sudo mkdir -p /var/lib/minio/data
sudo chown -R minio-user:minio-user /var/lib/minio
sudo chmod 750 /var/lib/minio-r สร้างบัญชีระบบที่มี UID ต่ำกว่า 1000 ซึ่งทำให้บัญชีนี้อยู่นอกช่วงที่ใช้สำหรับผู้ใช้ทั่วไป -M ไม่สร้างไดเรกทอรี home เนื่องจากบัญชีที่ไม่เคยเข้าสู่ระบบไม่มีข้อมูลที่ต้องจัดเก็บไว้ในไดเรกทอรีดังกล่าว ตรวจสอบผลลัพธ์ด้วย id minio-user และด้วย stat -c '%U %a' /var/lib/minio ซึ่งควรแสดงผลเป็น minio-user 750
ผู้ใช้นั้นต้องมีสิทธิ์เขียนไดเรกทอรีข้อมูล ไม่ใช่มีเพียงสิทธิ์อ่านเท่านั้น เมื่อเริ่มทำงานครั้งแรก MinIO จะสร้างไดเรกทอรี .minio.sys ภายใน volume เพื่อจัดเก็บการกำหนดค่าของตนเอง ดังนั้นไดเรกทอรีที่มี root เป็นเจ้าของจะทำให้ MinIO ออกจากการเริ่มต้นทำงานพร้อมข้อความที่ลงท้ายด้วย permission denied กฎเดียวกันนี้ใช้กับทุกบริการที่คุณเรียกใช้ในลักษณะนี้ และ ผู้ใช้บริการที่มีสิทธิ์เท่าที่จำเป็นบน VPS อธิบายเรื่องนี้ไว้อย่างเหมาะสม
ใส่ข้อมูลรับรองของ root ในไฟล์สภาพแวดล้อม
ข้อมูลรับรองของ root สามารถเข้าถึง bucket ได้ทุกใบ จึงไม่ควรใส่ไว้ในไฟล์ unit ซึ่งผู้ใช้ทุกคนสามารถอ่านได้ ให้สร้างไฟล์ด้วยโหมดที่ถูกต้องก่อน แล้วจึงเขียนข้อมูลลงไป เพื่อไม่ให้รหัสผ่านอยู่ในไฟล์ที่อ่านได้แม้เพียงชั่วขณะ
sudo install -o root -g root -m 600 /dev/null /etc/default/minio
printf 'MINIO_ROOT_USER=minio-root\nMINIO_ROOT_PASSWORD=%s\nMINIO_VOLUMES="/var/lib/minio/data"\nMINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"\n' "$(openssl rand -base64 24)" | sudo tee /etc/default/minio > /dev/null
sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/miniotee จะล้างเนื้อหาของไฟล์ที่มีอยู่แทนการสร้างไฟล์ใหม่ ดังนั้นโหมดจึงยังคงเป็น 600 และเจ้าของยังคงเป็น root การทำเช่นนี้เป็นความตั้งใจ systemd จะอ่าน EnvironmentFile ในฐานะ root ก่อนลดสิทธิ์เป็น User= ซึ่งหมายความว่าบัญชีบริการไม่จำเป็นต้องอ่านข้อมูลรับรองของตนเอง เมื่อบริการทำงานแล้ว ให้ตรวจสอบด้วย sudo -u minio-user cat /etc/default/minio คำสั่งนี้ต้องแสดงผลเป็น Permission denied
ควรทราบพฤติกรรม 2 ประการของ MinIO ก่อนเริ่มบริการ หากไม่มี MINIO_ROOT_USER และไม่มี MINIO_ROOT_PASSWORD ในสภาพแวดล้อมของ MinIO โปรแกรมจะไม่ปฏิเสธการเริ่มทำงาน แต่จะเริ่มทำงานด้วยข้อมูลรับรองเริ่มต้นที่ระบุไว้ในเอกสาร คือ minioadmin:minioadmin ซึ่งเป็นข้อมูลรับรองคู่แรกที่เครื่องมือสแกนใดลองใช้ และบริการจะดูเหมือนทำงานปกติ ในทางกลับกัน หากรหัสผ่านมีความยาวน้อยกว่า 8 ตัวอักษร MinIO จะปฏิเสธและออกจากโปรแกรมขณะเริ่มทำงาน พร้อมแสดงข้อผิดพลาดว่าข้อมูลรับรองไม่ถูกต้อง เนื่องจาก access key ต้องมีอย่างน้อย 3 ตัวอักษร และ secret key ต้องมีอย่างน้อย 8 ตัวอักษร
MINIO_VOLUMES คือเส้นทางข้อมูล และ MINIO_OPTS ใช้เก็บ flags การผูกบริการกับ 127.0.0.1 หมายความว่าในขณะนี้ไม่มีสิ่งใดภายนอก VPS นี้สามารถเข้าถึง S3 API ได้ ซึ่งเป็นค่าเริ่มต้นที่เหมาะสม ภายหลังคุณจะเปิดให้เข้าถึงโดยตั้งใจผ่าน proxy ที่มี certificate
เขียน unit ของ systemd
สร้าง /etc/systemd/system/minio.service:
[Unit]
Description=MinIO object storage
Documentation=https://github.com/minio/minio
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_VOLUMES $MINIO_OPTS
Restart=always
RestartSec=5
LimitNOFILE=65536
NoNewPrivileges=true
[Install]
WantedBy=multi-user.targetไม่มี - นำหน้า EnvironmentFile และนี่เป็นการตั้งใจ ไม่ใช่การพิมพ์ผิด หากมีขีด systemd จะไม่สนใจไฟล์ที่ไม่มีอยู่และเริ่ม MinIO ต่อไป ดังนั้นไฟล์ที่ถูกลบหรือ path ที่พิมพ์ผิดจะทำให้มี server ที่ทำงานบน minioadmin:minioadmin โดยไม่มีการแจ้งเตือน หากไม่มีขีด ไฟล์ที่ไม่มีอยู่จะทำให้ unit ล้มเหลวก่อนที่ MinIO จะเริ่มทำงาน และ journalctl -u minio จะแสดง Failed to load environment files: No such file or directory unit ที่ปฏิเสธการเริ่มทำงานตรวจพบได้ง่ายกว่า server ที่ยอมรับรหัสผ่านเริ่มต้นโดยไม่มีการแจ้งเตือน
$MINIO_VOLUMES และ $MINIO_OPTS ไม่ใส่เครื่องหมายอัญประกาศโดยตั้งใจ เพราะ systemd จะแยกตัวแปรที่ไม่ใส่เครื่องหมายอัญประกาศตามช่องว่างออกเป็นอาร์กิวเมนต์แยกกัน นี่คือสาเหตุที่คำ 4 คำใน MINIO_OPTS กลายเป็นอาร์กิวเมนต์ 4 รายการของ minio server LimitNOFILE=65536 เพิ่มขีดจำกัด file descriptor เพราะการเชื่อมต่อแต่ละรายการและไฟล์ข้อมูลแต่ละไฟล์ที่เปิดอยู่ใช้ descriptor 1 รายการ และค่าเริ่มต้น 1024 จะไม่เพียงพอเมื่อมีโหลดสูง
sudo systemctl daemon-reload
sudo systemctl enable --now minio
systemctl is-active minio
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9000/minio/health/liveis-active ควรแสดง active และ health endpoint ควรตอบกลับ 200 journalctl -u minio -n 20 --no-pager แสดงที่อยู่ API ที่ server กำลัง listening อยู่ หาก unit เริ่มทำงานซ้ำอย่างต่อเนื่อง systemd จะยอมแพ้และบันทึก Start request repeated too quickly ซึ่งหมายความว่า MinIO ออกจากการทำงานทุกครั้ง สาเหตุจะแสดงอยู่ในบรรทัดก่อนหน้าข้อความดังกล่าว ดังนั้นให้อ่านย้อนขึ้นไป
หากต้องการแยกการทำงานเพิ่มเติม ให้เพิ่ม ProtectSystem=full และ ProtectHome=true ในส่วน [Service] ทั้งสองรายการต้องใช้ mount namespace จาก kernel ของ host เมื่อใช้ container virtualisation ที่ใช้ kernel ร่วมกับ host เช่น OpenVZ หรือ LXC รายการเหล่านี้อาจล้มเหลว และ unit จะแจ้ง status=226/NAMESPACE จากนั้นลบ 2 บรรทัดดังกล่าว แล้ว unit จะเริ่มทำงาน ตัว unit เองเป็น unit ทั่วไป และ บริการและตัวตั้งเวลาของ systemd บน VPS อธิบาย directive อื่นๆ ที่เหลือ
ติดตั้ง mc และพิสูจน์การส่งข้อมูลไป-กลับ
ไคลเอ็นต์ MinIO คือ mc ห้ามติดตั้งด้วย apt install mc แพ็กเกจดังกล่าวคือ Midnight Commander ซึ่งเป็น file manager ที่ไม่เกี่ยวข้องกับ MinIO
cd /tmp
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc -o mc
curl -fsSL https://dl.min.io/client/mc/release/linux-amd64/mc.sha256sum -o mc.sha256sum
[ "$(awk '{print $1}' mc.sha256sum)" = "$(sha256sum mc | awk '{print $1}')" ] && echo "checksum ok"
sudo install -o root -g root -m 755 mc /usr/local/bin/mcลงทะเบียนเซิร์ฟเวอร์เป็น alias จากนั้นย้ายออบเจ็กต์ผ่านเซิร์ฟเวอร์
MINIO_PASS=$(sudo sed -n 's/^MINIO_ROOT_PASSWORD=//p' /etc/default/minio)
mc alias set local http://127.0.0.1:9000 minio-root "$MINIO_PASS"
mc mb local/backups
echo "hello object storage" > /tmp/hello.txt
mc cp /tmp/hello.txt local/backups/hello.txt
mc ls local/backups
mc cat local/backups/hello.txtmc ls ควรแสดงรายการ hello.txt พร้อมขนาด และ mc cat ควรพิมพ์ hello object storage การส่งข้อมูลไป-กลับนี้เป็นหลักฐานที่ยืนยันว่าเซิร์ฟเวอร์ทำงานได้จริง เพราะกระบวนการนี้ส่งคำขอ S3 ที่มีลายเซ็นแบบเดียวกับที่ไคลเอ็นต์อื่นจะส่ง mc admin info local จะแสดงสถานะเซิร์ฟเวอร์ หากต้องการตรวจสอบเพิ่มเติม
เรียกใช้การตรวจสอบอีกครั้งตอนนี้ ขณะที่เครื่องยังไม่มีข้อมูล
mc alias set defaultcheck http://127.0.0.1:9000 minioadmin minioadminคำสั่งนี้ต้องล้มเหลว หากคำสั่งทำงานสำเร็จ แสดงว่าไฟล์ environment ไม่ได้ถูกส่งต่อไปยัง process และเซิร์ฟเวอร์กำลังทำงานด้วย credentials เริ่มต้น ให้แก้ไขปัญหานี้ก่อนให้สิ่งอื่นเข้าถึงเครื่อง
mc จัดเก็บ alias ไว้ใน ~/.mc/config.json ในรูปแบบ plain text ดังนั้น credentials เหล่านั้นจึงอยู่ใน home directory ของผู้ที่เรียกใช้คำสั่ง การเรียกใช้ mc ภายใต้ sudo จะจัดเก็บ credentials ของ root ไว้ใน /root/.mc/config.json เก็บ alias ของ root ไว้ในบัญชีผู้ดูแลระบบเพียงบัญชีเดียว และกำหนด key ของตนเองให้แต่ละแอปพลิเคชัน
แจกจ่ายออบเจ็กต์หนึ่งรายการด้วย presigned URL
presigned URL คือ HTTPS link ทั่วไปที่แนบลายเซ็นและวันหมดอายุไว้ ผู้ที่มี link นี้สามารถดึงออบเจ็กต์นั้นได้โดยไม่ต้องมี account และไม่ต้องใช้ client
mc share download --expire 12h local/backups/hello.txtผลลัพธ์จะมี X-Amz-Signature และ X-Amz-Expires อยู่ใน query string มี 2 ประเด็นที่มักทำให้ผู้ใช้ประหลาดใจ link นี้สร้างจาก endpoint ใน alias ที่คุณใช้ ดังนั้น alias บน 127.0.0.1 จะสร้าง link ที่เปิดได้เฉพาะจากเครื่องนี้เท่านั้น ให้สร้าง alias ที่สองบน hostname สาธารณะสำหรับ link ที่คุณต้องการส่งต่อ และไม่มีปุ่ม revoke ลายเซ็นจะยังใช้ได้จนกว่าจะหมดอายุ ดังนั้นการกำหนดวันหมดอายุให้สั้นจึงเป็นวิธีควบคุมเพียงอย่างเดียวที่มี รูปแบบลายเซ็น S3 อนุญาตให้กำหนดได้สูงสุด 7 วัน
สร้าง key และ bucket สำหรับ restic โดยเฉพาะ
ข้อมูลรับรองของ root สามารถอ่านและลบ bucket ได้ทุก bucket ดังนั้นงานสำรองข้อมูลต้องไม่ใช้ข้อมูลรับรองเหล่านี้ ให้สร้าง bucket, policy ที่จำกัดขอบเขตไว้เฉพาะ bucket นั้น และ user ที่ไม่มีสิทธิ์อื่น
mc mb local/restic
cat > /tmp/restic-rw.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket", "s3:GetBucketLocation"],
"Resource": ["arn:aws:s3:::restic"]
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": ["arn:aws:s3:::restic/*"]
}
]
}
EOF
RESTIC_KEY=$(openssl rand -base64 24)
mc admin policy create local restic-rw /tmp/restic-rw.json
mc admin user add local restic-backup "$RESTIC_KEY"
mc admin policy attach local restic-rw --user restic-backupMinIO มี policy ในตัวชื่อ readwrite ซึ่งจะทำให้สั้นลง 1 คำสั่ง แต่ policy นี้ให้สิทธิ์เข้าถึงทุก bucket บน server อย่างเต็มรูปแบบ policy ด้านบนระบุชื่อ bucket 2 ครั้งโดยตั้งใจ: ครั้งแรกเป็น arn:aws:s3:::restic เพื่อให้สามารถแสดงรายการ bucket ได้ และอีกครั้งเป็น arn:aws:s3:::restic/* สำหรับ object ภายใน bucket ใน S3 bucket และ object เป็น resource แยกกัน ดังนั้น policy ที่ระบุเพียงอย่างใดอย่างหนึ่งจะทำงานล้มเหลวในลักษณะที่ดูเหมือน client เสีย
ทดสอบข้อจำกัดก่อนนำไปใช้งานจริง
mc alias set resticuser http://127.0.0.1:9000 restic-backup "$RESTIC_KEY"
mc ls resticuser/restic
mc ls resticuser/backupsls รายการแรกทำงานสำเร็จ และรายการที่สองล้มเหลวโดยแสดง Access Denied policy ที่ยังไม่ได้ทดสอบเป็นเพียงการคาดเดา
จากนั้นกำหนดค่า restic ให้ใช้ bucket นี้ restic จะอ่านข้อมูลรับรอง S3 จากตัวแปรสภาพแวดล้อมมาตรฐานของ AWS จึงไม่ต้องมีไฟล์ข้อมูลรับรองเฉพาะของ restic
sudo apt install -y restic
export AWS_ACCESS_KEY_ID=restic-backup
export AWS_SECRET_ACCESS_KEY="$RESTIC_KEY"
restic -r s3:http://127.0.0.1:9000/restic init
restic -r s3:http://127.0.0.1:9000/restic backup /etc
restic -r s3:http://127.0.0.1:9000/restic snapshotsrestic init จะขอรหัสผ่านของ repository รหัสผ่านนี้ใช้เข้ารหัส repository ดังนั้น MinIO จะจัดเก็บเฉพาะ ciphertext เท่านั้น และหากสูญเสียรหัสผ่าน ก็จะสูญเสียข้อมูลสำรองไปด้วย งานที่เริ่มโดย systemd timer ไม่มี terminal สำหรับป้อนรหัสผ่าน ดังนั้นให้กำหนด RESTIC_PASSWORD_FILE เป็นไฟล์ mode 600 สำหรับงานสำรองข้อมูลตามกำหนดเวลา
มีกฎสำคัญเกี่ยวกับตำแหน่งจัดเก็บซึ่งสำคัญกว่าคำสั่งใดๆ ข้างต้น การมี repository ของ restic อยู่บน VPS เดียวกับข้อมูลที่ปกป้องจะช่วยป้องกันได้เฉพาะกรณี rm ที่ไม่ดีเท่านั้น และไม่ช่วยป้องกันเหตุอื่น MinIO node ควรอยู่คนละเครื่อง และควรอยู่คนละ region หากเป็นไปได้ การสำรองข้อมูล restic บน VPS อธิบายการตั้งเวลาและการเก็บรักษาข้อมูลต่อจากขั้นตอนนี้
ยุติ TLS ด้วย nginx
MinIO ทำงานอยู่บน localhost ดังนั้น nginx จึงเป็นจุดให้บริการสาธารณะ ให้ออกใบรับรองก่อนตามที่อธิบายไว้ใน ใบรับรอง Let's Encrypt ด้วย certbot และ nginx จากนั้นใช้ server block นี้
server {
listen 443 ssl;
server_name s3.example.com;
ignore_invalid_headers off;
client_max_body_size 0;
proxy_buffering off;
proxy_request_buffering off;
location / {
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 300;
proxy_http_version 1.1;
proxy_set_header Connection "";
chunked_transfer_encoding off;
proxy_pass http://127.0.0.1:9000;
}
}บรรทัดเหล่านี้หลายบรรทัดมีผลโดยตรงต่อการทำงาน client_max_body_size 0 ลบขีดจำกัดขนาด body เริ่มต้นที่ 1 MB ซึ่งหากไม่ตั้งค่า การอัปโหลดที่มีขนาดใหญ่กว่านั้นจะถูกปฏิเสธด้วย 413 Request Entity Too Large ก่อนที่ MinIO จะได้รับคำขอ proxy_request_buffering off ทำให้การอัปโหลดถูกส่งต่อโดยตรง เนื่องจากค่าเริ่มต้นจะเขียนคำขอทั้งหมดลงในไฟล์ชั่วคราวก่อน และออบเจ็กต์ขนาดใหญ่จะต้องใช้พื้นที่ดิสก์ซ้ำ 2 เท่า proxy_set_header Host $http_host เป็นค่าที่มักมองข้าม ลายเซ็น S3 ครอบคลุม header Host ดังนั้นพร็อกซีที่เขียนค่าใหม่จะทำให้ทุกคำขอล้มเหลวด้วย SignatureDoesNotMatch แม้ access log จะแสดงว่ามีคำขอปกติเข้ามาถึง
กำหนดชื่อสาธารณะของ MinIO ด้วย เพื่อให้ลิงก์ที่ MinIO สร้างชี้ไปยังพร็อกซีแทน localhost
echo 'MINIO_SERVER_URL=https://s3.example.com' | sudo tee -a /etc/default/minio
sudo systemctl restart minioกฎไฟร์วอลล์ควรมีเพียงไม่กี่รายการ อนุญาต SSH และ HTTPS และไม่ต้องสร้างกฎสำหรับพอร์ต 9000 และ 9001 เนื่องจาก address ที่ bind กับ 127.0.0.1 จะไม่สามารถเข้าถึงจากเครื่องอื่นได้ ไม่ว่าไฟร์วอลล์จะกำหนดไว้อย่างไร พื้นฐาน ufw firewall บน VPS มีคำสั่งที่ต้องใช้
เมื่อ MinIO แบบโหนดเดียวเพียงพอ และเมื่อควรใช้ S3 จริง
แบบโหนดเดียวในที่นี้หมายถึงใช้ไดรฟ์ 1 ตัวโดยไม่มี parity เลย เอกสารของ MinIO ระบุว่าโครงสร้างนี้เหมาะสำหรับการทดสอบและเวิร์กโหลดขนาดเล็กที่ไม่ต้องการความพร้อมใช้งาน เนื่องจากภายในการติดตั้งไม่มีสำเนาที่สอง ความทนทานของออบเจ็กต์แต่ละรายการจึงเท่ากับความทนทานของดิสก์ VPS เพียงตัวเดียว ฟีเจอร์ที่ต้องใช้แบ็กเอนด์แบบกระจายและเข้ารหัสแบบ erasure เช่น การจำลอง bucket และการล็อกออบเจ็กต์ เหมาะกับการติดตั้งที่ใช้หลายไดรฟ์ ดังนั้นอย่ารับรองนโยบายการเก็บรักษาข้อมูลแบบแก้ไขไม่ได้สำหรับการติดตั้งนี้
การติดตั้งนี้เหมาะสำหรับใช้เป็นเป้าหมายของ restic บน VPS อีกเครื่องในภูมิภาคอื่น และเป็น S3 endpoint สำหรับงานพัฒนาและอาร์ติแฟกต์ของ CI ซึ่งการสูญเสีย bucket จะมีต้นทุนเพียงการสร้างใหม่เท่านั้น นอกจากนี้ยังเหมาะสมสำหรับการอัปโหลดของผู้ใช้ในแอปพลิเคชันขนาดเล็ก ตราบใดที่คุณเป็นผู้รับผิดชอบแผนกู้คืน และได้ทดสอบการกู้คืนจริงแล้ว
เลือก S3 แบบมีผู้ให้บริการจัดการเมื่อสัญญาหรือหน่วยงานกำกับดูแลกำหนดให้ใช้ object lock หรือความทนทานหลายภูมิภาค หรือเมื่อคุณไม่ต้องการเป็นผู้ที่ต้องรับแจ้งเตือนเวลา 03:00 เนื่องจากดิสก์เต็ม อีกเหตุผลที่ควรพิจารณาอย่างตรงไปตรงมาคือบิลด์ที่หยุดนิ่ง ณ เดือน July 2026 ไบนารีที่คอมไพล์ไว้ล่วงหน้าสำหรับชุมชนมีวันที่จาก September 2025 และไม่ได้รับการแก้ไขอีก ดังนั้นการใช้งานไบนารีนี้หมายถึงการยอมรับข้อจำกัดดังกล่าว หรือคอมไพล์จากซอร์สและติดตามโครงการด้วยตนเอง
มีขอบเขตหนึ่งที่ควรระบุไว้ เนื่องจากมักเกิดคำถามเรื่องนี้ Object storage ไม่ใช่ฐานข้อมูล การเขียนแต่ละครั้งจะแทนที่ออบเจ็กต์ทั้งรายการ ดังนั้นไฟล์ SQL ที่กำลังใช้งานอยู่บน bucket ของ S3 จึงทำงานช้าและไม่ปลอดภัย ให้เก็บฐานข้อมูลไว้บนดิสก์ภายในเครื่อง และสำรองข้อมูลไปยัง bucket แทน: การใช้งาน SQLite ในระบบ production บน VPS อธิบายการแยกส่วนนี้ไว้
โหมดความล้มเหลวและข้อความที่คุณจะเห็น
หน่วยล้มเหลวทันทีหลังจาก systemctl enable --now อ่าน journalctl -u minio -n 30 --no-pager ค่า Failed to load environment files: No such file or directory หมายความว่า /etc/default/minio ไม่มีอยู่ หรือระบุพาธไว้ผิดในหน่วย ข้อความที่ลงท้ายด้วย permission denied หมายความว่า service account ไม่มีสิทธิ์เขียนไดเรกทอรีข้อมูล ดังนั้นตรวจสอบว่า stat -c '%U' /var/lib/minio/data แสดงค่า minio-user
minioadmin:minioadmin ยังคงเข้าสู่ระบบได้ ไฟล์สภาพแวดล้อมไม่ถูกส่งไปถึงโพรเซส ตรวจสอบว่าในหน่วยมี EnvironmentFile=/etc/default/minio เรียกใช้ sudo systemctl daemon-reload จากนั้นรีสตาร์ต service MinIO จะอ่านข้อมูลประจำตัว root เพียงครั้งเดียวเมื่อเริ่มต้นระบบ ดังนั้นการแก้ไขไฟล์ดังกล่าวโดยไม่รีสตาร์ตจะไม่เปลี่ยนแปลงอะไร
Address already in use เมื่อเริ่มต้นระบบ มีโพรเซสอื่นใช้ port 9000 อยู่ ค้นหาโพรเซสนั้นด้วย sudo ss -ltnp | grep :9000 ก่อนเปลี่ยน port ของ MinIO
การอัปโหลดที่มีขนาดเกิน 1 MB ล้มเหลวผ่าน proxy nginx ตอบกลับด้วย 413 Request Entity Too Large และ MinIO ไม่ได้รับคำขอ กำหนด client_max_body_size 0 ใน server block
SignatureDoesNotMatch สาเหตุอาจเป็น secret key ไม่ถูกต้อง หรือมีสิ่งใดระหว่าง client กับ MinIO แก้ไข header Host ซึ่งอยู่ในขอบเขตที่ลายเซ็นครอบคลุม
RequestTimeTooSkewed นาฬิกาของ client หรือ server ไม่ถูกต้อง คำขอ S3 ทุกคำขอมีการประทับเวลา และจะถูกปฏิเสธหากอยู่นอกช่วง 15 นาที ตรวจสอบ timedatectl และยืนยันว่าการซิงโครไนซ์เวลาทำงานอยู่
Access Denied บน bucket ที่คุณทราบว่ามีอยู่ key นี้กำหนดขอบเขตไว้กับ bucket อื่น แสดงสิ่งที่ policy อนุญาตจริงด้วย mc admin policy info local restic-rw แล้วเปรียบเทียบชื่อ bucket ในบรรทัด resource
FAQ
MinIO แบบโหนดเดียวเพียงพอสำหรับการสำรองข้อมูลจริงหรือไม่
เพียงพอสำหรับใช้เป็นเป้าหมายของ restic ที่ทำงานอยู่บนเครื่องแยกจากข้อมูลที่ต้องปกป้อง แต่ไม่เพียงพอที่จะใช้เป็นสำเนาเดียว การติดตั้งที่มีไดรฟ์เดียวไม่มี parity ดังนั้นจึงไม่มีสำเนาที่สองอยู่ภายใน MinIO หากดิสก์ของ VPS สูญเสียข้อมูล ออบเจ็กต์จะสูญหายทั้งหมด ควรมีเป้าหมายสำรองอีกแห่งหนึ่ง และทดสอบการกู้คืนจากทั้งสองแห่งอย่างน้อย 1 ครั้ง เพื่อให้แน่ใจว่ากระบวนการทำงานได้
เหตุใด sha256sum -c จึงล้มเหลวกับไฟล์ checksum ของ MinIO
เนื่องจากป้ายกำกับหลังค่า hash ในไฟล์นั้นระบุชื่อ release เป็น minio.RELEASE.2025-09-07T16-13-09Z แต่ไฟล์ที่ดาวน์โหลดมักมีชื่อว่า minio sha256sum -c จะค้นหาไฟล์ตามชื่อที่เขียนไว้ในไฟล์ checksum เมื่อไม่พบ จึงรายงาน No such file or directory และ WARNING: 1 listed file could not be read การดาวน์โหลดไม่มีปัญหา ให้เปรียบเทียบสตริง hash โดยตรงและไม่ต้องสนใจป้ายกำกับ เนื่องจากป้ายกำกับไม่มีความหมายด้านความปลอดภัย
คอนโซลเว็บผู้ดูแลระบบของ MinIO หายไปไหน
MinIO นำความสามารถด้านการดูแลระบบออกจากคอนโซลของ community edition ในเดือน May 2025 เหลือเพียงตัวเรียกดูออบเจ็กต์ในเว็บอินเทอร์เฟซ ปัจจุบันให้จัดการ buckets และ users ด้วยไคลเอ็นต์ mc โดยใช้คำสั่ง เช่น mc admin user add และ mc admin policy attach นี่คือวิธีที่รองรับใน community edition ไม่ใช่วิธีแก้ชั่วคราว ดังนั้นคู่มือนี้จึงดำเนินการทั้งหมดจาก command line
จะกำหนดให้ restic ใช้ MinIO เป็นแบ็กเอนด์ S3 ได้อย่างไร
กำหนด AWS_ACCESS_KEY_ID และ AWS_SECRET_ACCESS_KEY ให้เป็น access key ของ MinIO และ secret ของ access key ดังกล่าว จากนั้นใช้สตริง repository ในรูปแบบ s3:https://s3.example.com/restic โดยองค์ประกอบสุดท้ายของ path คือชื่อ bucket ให้สร้าง bucket ก่อนด้วย mc mb เนื่องจาก key ที่จำกัดขอบเขตไว้ที่ bucket เดียวไม่มีสิทธิ์สร้าง buckets restic จะเข้ารหัสทุกอย่างด้วยรหัสผ่าน repository ของตัวเองก่อนอัปโหลด ดังนั้น MinIO จะจัดเก็บ ciphertext และไม่สามารถเห็นไฟล์ของคุณ
จำเป็นต้องให้ MinIO ทำงานอยู่เบื้องหลัง nginx หรือไม่
คุณต้องใช้ TLS (transport layer security) เมื่อ client ไม่ได้อยู่บนเครื่องเดียวกัน เนื่องจากข้อมูลรับรอง S3 และข้อมูลออบเจ็กต์จะถูกส่งอยู่ภายใน request การใช้ proxy บน port 443 พร้อม certificate จาก certbot เป็นวิธีที่ง่ายที่สุด และช่วยแยกการต่ออายุ certificate ออกจาก MinIO MinIO สามารถทำหน้าที่ terminate TLS ได้เช่นกัน หากกำหนด --certs-dir ให้ชี้ไปยัง directory ที่มี public.crt และ private.key แต่ service account จะต้องมีสิทธิ์ read ต่อ private key ที่ต่ออายุแล้ว ซึ่งเพิ่มภาระงานโดยให้ผลลัพธ์เหมือนเดิม