Volumes vs Bind Mounts
เปรียบเทียบอย่างรวดเร็ว
หัวข้อที่มีชื่อว่า “เปรียบเทียบอย่างรวดเร็ว”| คุณสมบัติ | Named Volume | Bind Mount |
|---|---|---|
| Path จัดการโดย | Docker | คุณ |
| ต้องการ host path | ไม่ต้อง | ต้องการ |
| ความสามารถพกพา | สูง — ทำงานได้บน host ทุกเครื่อง | ต่ำ — path ต้องมีอยู่ในทุก host |
| ประสิทธิภาพ | ปรับแต่งโดย Docker storage driver | ใช้ host filesystem โดยตรง (เร็วบน Linux ช้ากว่าบน macOS/Windows) |
| การสำรองข้อมูล | docker volume inspect + tar container | คัดลอกไฟล์โดยตรงจาก host path |
| กรณีใช้งานทั่วไป | ไฟล์ฐานข้อมูล state ของแอป uploads | Source code ไฟล์ config ในการพัฒนา |
| ใช้ใน production ได้ | ได้ | ไม่ค่อยได้ (ขึ้นอยู่กับ layout ของ host) |
เมื่อไรควรใช้แต่ละอย่าง
หัวข้อที่มีชื่อว่า “เมื่อไรควรใช้แต่ละอย่าง”ใช้ named volumes เมื่อ:
หัวข้อที่มีชื่อว่า “ใช้ named volumes เมื่อ:”- คุณต้องการให้ข้อมูลรอดชีวิตจากการสร้าง container ใหม่ (ฐานข้อมูล object storage cache)
- คุณ deploy ไปยัง remote host หรือ environment CI/CD ที่ host path อาจแตกต่างกัน
- คุณต้องการให้ Docker เป็นเจ้าของ lifecycle ของพื้นที่จัดเก็บ
ใช้ bind mounts เมื่อ:
หัวข้อที่มีชื่อว่า “ใช้ bind mounts เมื่อ:”- คุณกำลังพัฒนาในเครื่องและต้องการ live code reload โดยไม่ต้อง rebuild image
- คุณต้องการ inject ไฟล์ config จาก host เข้า container ณ เวลา runtime
- คุณกำลังรัน tools (linters, compilers) ที่ผลิต output ที่คุณต้องการโดยตรงบน host
Read-only mounts
หัวข้อที่มีชื่อว่า “Read-only mounts”ทั้งสองประเภทรองรับ read-only mounts container สามารถอ่านข้อมูลได้แต่เขียนไปยัง mount target ไม่ได้
Named volume แบบ read-only:
docker run --rm -v mydata:/app/data:ro alpine ls /app/dataBind mount แบบ read-only:
docker run --rm -v $(pwd)/config:/etc/app/config:ro myimageด้วย --mount syntax (ทั้งสองประเภท):
# Volumedocker run --rm --mount type=volume,source=mydata,target=/app/data,readonly myimage
# Binddocker run --rm --mount type=bind,source=$(pwd)/config,target=/etc/app/config,readonly myimageRead-only mounts เป็น security best practice เมื่อ container ต้องการเพียงแค่อ่านข้อมูล — ป้องกัน process ที่ถูก compromise หรือมีข้อบกพร่องจากการเขียนทับไฟล์สำคัญ
ฝึกปฏิบัติ
หัวข้อที่มีชื่อว่า “ฝึกปฏิบัติ”snippet ด้านล่างสาธิต mount ทั้งสองประเภทเคียงข้างกัน เพื่อให้คุณสังเกตความแตกต่างในเซสชันเดียว
# --- Named volume ---
docker volume create compare-vol
# Write via container
docker run --rm -v compare-vol:/data alpine sh -c "echo 'from named volume' > /data/note.txt"
# Read from a new container (data persists)
docker run --rm -v compare-vol:/data alpine cat /data/note.txt
# --- Bind mount ---
mkdir -p /tmp/compare-bind
echo 'from bind mount' > /tmp/compare-bind/note.txt
# Read from container via bind mount
docker run --rm -v /tmp/compare-bind:/data alpine cat /data/note.txt
# --- Read-only mount ---
docker run --rm -v /tmp/compare-bind:/data:ro alpine sh -c "cat /data/note.txt && echo 'trying to write...' && echo 'blocked' > /data/note.txt || echo 'Write blocked as expected'"
# Clean up
docker volume rm compare-vol
rm -rf /tmp/compare-bindข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| Named volume | Docker จัดการเอง พกพาข้าม host ได้ สำรองข้อมูลง่ายด้วย throwaway container | เรียกดูไฟล์ตรงจาก host filesystem ไม่ได้ ต้อง mount เข้า container ก่อน |
| Bind mount | เข้าถึง path บน host ได้โดยตรง เหมาะกับ dev workflow ที่ต้องแก้ไฟล์บ่อยๆ | ผูกกับโครงสร้างไดเรกทอรีของ host เครื่องนั้น ย้ายข้าม environment ยาก |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- เลือก bind mount สำหรับเก็บข้อมูลฐานข้อมูล production เพราะ “เห็นไฟล์ตรงๆ ง่ายดี” ทั้งที่ named volume คือตัวเลือกที่ถูกต้องกว่า
- รัน
docker compose down -vทั้งที่ตั้งใจแค่หยุด container ทำให้ named volume ที่ผูกกับ service ถูกลบไปด้วย - ไม่เคยตั้งแผนสำรองข้อมูลให้ named volume เพราะเข้าใจผิดว่า Docker จัดการ backup ให้อัตโนมัติ
💡 ตัวอย่างจากของจริง
official Postgres/MySQL Docker image documentation แนะนำให้ใช้ named volume mount ที่
/var/lib/postgresql/dataเป็น pattern มาตรฐานสำหรับ production ส่วน bind mount ใช้เฉพาะตอนพัฒนาเพื่อความสะดวกในการแก้ไข config หรือ source code