Bind Mounts
Bind mount คืออะไร?
หัวข้อที่มีชื่อว่า “Bind mount คืออะไร?”Bind mount map path เฉพาะเจาะจงบนเครื่อง host ของคุณโดยตรงเข้าไปใน container ต่างจาก named volume ตรงที่คุณเลือกเองว่าข้อมูลจะอยู่ที่ไหนบน host — Docker ไม่ได้จัดการ path ให้
Host filesystem: /home/user/myapp/src ↕ bind mountContainer filesystem: /app/srcการเปลี่ยนแปลงใดๆ ที่เกิดขึ้นฝั่ง host จะมองเห็นได้ทันทีภายใน container และในทางกลับกันด้วย ทำให้ bind mounts เหมาะสำหรับการพัฒนา: editor ของคุณแก้ไขไฟล์บน host และ process ที่รันอยู่ภายใน container เห็นการอัปเดตทันที — ไม่ต้อง rebuild
Short -v syntax:
docker run -v /host/path:/container/path myimageLong --mount syntax (แนะนำสำหรับ scripts — ไม่มีความกำกวม):
docker run \ --mount type=bind,source=/host/path,target=/container/path \ myimageใช้ $(pwd) สำหรับไดเรกทอรีปัจจุบัน
หัวข้อที่มีชื่อว่า “ใช้ $(pwd) สำหรับไดเรกทอรีปัจจุบัน”ในการพัฒนาคุณแทบจะต้องการ mount ไดเรกทอรีทำงานปัจจุบันเสมอ:
docker run --rm -v $(pwd):/app -w /app node:22-alpine node server.js$(pwd) ขยายเป็น absolute path ของ host ณ เวลา runtime นี่เป็น pattern มาตรฐานสำหรับการรัน code โดยไม่ต้อง build image ใหม่ทุกครั้งที่มีการเปลี่ยนแปลง
Workflow การพัฒนาในทางปฏิบัติ
หัวข้อที่มีชื่อว่า “Workflow การพัฒนาในทางปฏิบัติ”# Mount source ของคุณเข้า container ที่ /app# flag -w กำหนด working directory ภายใน containerdocker run -d --name dev-server \ -v $(pwd)/src:/app/src \ -p 3000:3000 \ node:22-alpine \ node /app/src/server.jsตอนนี้แก้ไข src/server.js บน host ของคุณ ถ้า process ภายใน container ดู filesystem อยู่ (เช่น ด้วย nodemon) จะ restart อัตโนมัติ ไม่จำเป็นต้อง rebuild image สำหรับการเปลี่ยนแปลง code ทุกครั้ง
Read-only bind mounts
หัวข้อที่มีชื่อว่า “Read-only bind mounts”เพิ่ม :ro เพื่อทำให้ mount เป็น read-only จากมุมมองของ container container สามารถอ่านไฟล์ได้แต่เขียนไม่ได้:
docker run --rm \ -v $(pwd)/config:/etc/myapp/config:ro \ myimageด้วย --mount syntax:
docker run --rm \ --mount type=bind,source=$(pwd)/config,target=/etc/myapp/config,readonly \ myimageมีประโยชน์สำหรับการ inject ไฟล์ configuration จาก host เข้า container โดยไม่ให้ container เขียนทับโดยบังเอิญ
ฝึกปฏิบัติ
หัวข้อที่มีชื่อว่า “ฝึกปฏิบัติ”snippet ด้านล่างสร้างไฟล์บน host (จำลองด้วย echo ในขั้นตอน setup) mount ไดเรกทอรีเข้า container และอ่านไฟล์จากภายใน container — สาธิตการแชร์ไฟล์แบบ live
# 1. Create a directory with a file to share
mkdir -p /tmp/bindtest && echo 'shared from host' > /tmp/bindtest/hello.txt
# 2. Mount it into a container and read the file
docker run --rm -v /tmp/bindtest:/data alpine cat /data/hello.txt
# 3. Write from inside the container back to the host
docker run --rm -v /tmp/bindtest:/data alpine sh -c "echo 'written by container' > /data/from-container.txt"
# 4. Check the file now exists on the host path
ls -la /tmp/bindtest/
cat /tmp/bindtest/from-container.txt
# 5. Clean up
rm -rf /tmp/bindtestข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| Bind mount | แก้ไขไฟล์บน host แล้วเห็นผลใน container ทันที เหมาะกับ live reload ตอนพัฒนา | ผูกกับ layout ของ host เครื่องนั้น ย้ายไป host อื่นต้องมี path เดียวกัน |
| Named volume | Docker จัดการพื้นที่จัดเก็บให้ พกพาข้าม host ได้ | ต้องเข้า container เพื่อดูไฟล์ ไม่สามารถเปิดด้วย editor บน host ได้ตรงๆ |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ใช้ bind mount เก็บข้อมูลฐานข้อมูลใน production แทนที่จะใช้ named volume ทำให้ deploy ไป host อื่นแล้ว path ไม่ตรงกัน ข้อมูลหาย
- ลืมว่า bind mount เขียนทับสิทธิ์ไฟล์ (permission) ตาม user ของ container ทำให้ไฟล์บน host เปลี่ยนเจ้าของโดยไม่ตั้งใจ
- Mount ทั้งไดเรกทอรี
node_modulesจาก host เข้า container ทำให้ dependency ที่ build บน host คนละ OS ขัดแย้งกับที่ต้องใช้ใน container
💡 ตัวอย่างจากของจริง
official Postgres และ MySQL image แนะนำ named volume สำหรับ
/var/lib/postgresql/dataหรือ/var/lib/mysqlเสมอ ไม่ใช่ bind mount เพราะ production ต้องการความสามารถพกพาที่ bind mount ให้ไม่ได้ bind mount เหมาะกับ source code ตอน dev เท่านั้น