MinIO — Object Storage แบบ S3 ในเครื่องเรา
รู้จัก object storage รัน MinIO ด้วย compose แล้วให้ API เก็บไฟล์ลง bucket
พื้นฐานที่ควรรู้: ตอนนี้ไฟล์อัปโหลดกองอยู่ใน /tmp ของ container ซึ่งหายทันทีที่ container ตาย และ Pod อื่น (เช่น Job แปลงไฟล์) มองไม่เห็น — ระบบจริงจึงเก็บวิดีโอใน object storage ที่ทุก service เข้าถึงได้ผ่าน network เราใช้ MinIO ซึ่งพูด protocol เดียวกับ AWS S3 เป๊ะ (ย้ายขึ้น S3 จริงได้โดยแก้ endpoint บรรทัดเดียว)
Object storage เหมือนตู้ล็อกเกอร์กลาง — ทุกบ้าน (Pod) เอาของมาฝาก/มาหยิบได้ด้วยกุญแจ (access key) และชื่อช่อง (bucket/key เช่น uploads/a1b2c3d4/source.mp4) ไม่ต้องส่งของถึงบ้านกันเอง · ต่างจาก disk ติดเครื่อง (PVC) ที่ผูกกับ Pod ใด Pod หนึ่ง
รัน MinIO + API คู่กันด้วย Docker Compose
services:
minio:
image: minio/minio
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: password123
ports:
- "9000:9000" # S3 API
- "9001:9001" # เว็บ console
volumes:
- minio-data:/data
api:
build: ./api
environment:
MINIO_HOST: minio # ← ชื่อ service ใน compose ใช้เป็น hostname ได้เลย
MINIO_USER: admin
MINIO_PASS: password123
ports:
- "3000:3000"
depends_on:
- minio
volumes:
minio-data:ต่อ API เข้า MinIO
cd ~/projects/k8s-video-pipeline/api
npm install minioconst Minio = require('minio')
const minio = new Minio.Client({
endPoint: process.env.MINIO_HOST || 'localhost',
port: parseInt(process.env.MINIO_PORT || '9000'),
useSSL: false,
accessKey: process.env.MINIO_USER,
secretKey: process.env.MINIO_PASS,
})
// สร้าง bucket ที่ต้องใช้ตอนแอปสตาร์ท (idempotent — มีอยู่แล้วก็ข้าม)
async function ensureBuckets() {
for (const b of ['uploads', 'vod']) {
if (!(await minio.bucketExists(b))) {
await minio.makeBucket(b)
console.log('สร้าง bucket:', b)
}
}
}
ensureBuckets().catch((err) => {
console.error('ต่อ MinIO ไม่ได้:', err.message)
process.exit(1)
})
// แก้ handler อัปโหลดให้เก็บไฟล์ลง MinIO
app.post('/api/upload', upload.single('video'), async (req, res) => {
if (!req.file) {
return res.status(400).json({ error: 'ต้องแนบไฟล์ใน field ชื่อ "video"' })
}
const videoId = crypto.randomUUID().slice(0, 8)
await minio.fPutObject('uploads', videoId + '/source.mp4', req.file.path)
console.log('เก็บต้นฉบับแล้ว: uploads/' + videoId + '/source.mp4')
res.json({ videoId, status: 'uploaded' })
})cd ~/projects/k8s-video-pipeline
docker compose up --build
# terminal อื่น
curl -F "video=@sample.mp4" http://localhost:3000/api/upload
# → {"videoId":"...","status":"uploaded"}เปิดเว็บ console ของ MinIO ที่ http://localhost:9001 (user admin / pass password123) → เข้า bucket uploads → ต้องเห็นโฟลเดอร์ videoId ที่มี source.mp4 อยู่ข้างใน — เห็นไฟล์ = ชั้นนี้ผ่าน
สรุป Key Takeaways
- Object storage = ที่เก็บไฟล์กลางที่ทุก Pod เข้าถึงผ่าน network — MinIO พูด S3 API เป๊ะ
- bucket uploads เก็บต้นฉบับ · bucket vod เก็บผลลัพธ์ HLS
- อ่าน config จาก env var ตั้งแต่แรก → ย้ายจาก compose ขึ้น K8s ได้โดยไม่แก้โค้ด

