ข้ามไปยังเนื้อหา

Named Volumes

Named volume คือหน่วยพื้นที่จัดเก็บที่ Docker สร้างและจัดการแทนคุณ Docker เก็บข้อมูล volume ไว้ในไดเรกทอรีของตัวเอง (โดยทั่วไปคือ /var/lib/docker/volumes/ บน Linux) คุณอ้างถึง volume ด้วยชื่อ — ไม่ใช่ด้วย host path

เนื่องจาก Docker เป็นเจ้าของตำแหน่งที่จัดเก็บ named volumes จึง:

  • ทำงานได้เหมือนกันบน Linux, macOS และ Windows
  • รอดจาก docker rm — volume แยกจาก container
  • สามารถแชร์ระหว่าง container หลายตัวพร้อมกันได้
  • เป็นวิธีที่แนะนำในการเก็บข้อมูล application ใน production
Terminal window
docker volume create mydata
Terminal window
docker volume ls

ผลลัพธ์ที่คาดหวัง:

DRIVER VOLUME NAME
local mydata
Terminal window
docker volume inspect mydata
[
{
"CreatedAt": "2024-06-01T10:00:00Z",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/mydata/_data",
"Name": "mydata",
"Scope": "local"
}
]

Mountpoint คือที่ที่ Docker เก็บข้อมูลจริงบน host คุณแทบไม่จำเป็นต้องเข้าถึงโดยตรง — Docker ซ่อนรายละเอียดนั้นไว้

Terminal window
docker volume rm mydata

ไม่สามารถลบ volume ได้ขณะที่ container กำลังใช้งานอยู่ ลบ container ก่อน หรือใช้ docker volume prune เพื่อลบ volumes ที่ไม่ได้ใช้ทั้งหมดในครั้งเดียว

มีสองรูปแบบ syntax ทั้งสองเทียบเท่ากัน — ใช้แบบไหนก็ได้ที่คุณอ่านง่ายกว่า

Short -v syntax:

Terminal window
docker run -d --name myapp -v mydata:/app/data myimage

Long --mount syntax (ชัดเจนและแนะนำสำหรับ scripts):

Terminal window
docker run -d --name myapp \
--mount type=volume,source=mydata,target=/app/data \
myimage

ถ้า volume mydata ยังไม่มีอยู่ Docker จะสร้างให้อัตโนมัติเมื่อคุณรัน container

คุณสมบัติสำคัญของ named volume: คุณสามารถลบ container และสร้างใหม่ได้ ข้อมูลทั้งหมดที่เขียนลง volume ยังคงอยู่ครบถ้วน

Terminal window
# รัน container และเขียนข้อมูล
docker run --name writer -v mydata:/app/data alpine sh -c "echo 'persistent' > /app/data/file.txt"
# ลบ container
docker rm writer
# สร้าง container ใหม่ mount volume เดิม
docker run --rm -v mydata:/app/data alpine cat /app/data/file.txt
# Output: persistent

snippet ด้านล่างรัน container เขียนข้อมูลลง named volume ลบ container แล้ว mount volume เดิมใน container ใหม่เพื่อพิสูจน์ว่าข้อมูลรอดมาได้

# 1. Create a named volume
docker volume create demo-vol

# 2. Write data into the volume via a container
docker run --rm -v demo-vol:/data alpine sh -c "echo 'data survives!' > /data/message.txt"

# 3. Read it back from a completely new container
docker run --rm -v demo-vol:/data alpine cat /data/message.txt

# 4. Inspect the volume
docker volume inspect demo-vol

# 5. Clean up
docker volume rm demo-vol
ตัวเลือกBenefitCost
Named volumeDocker จัดการ path ให้ ย้าย host ได้ backup ง่ายด้วย throwaway containerเข้าถึงข้อมูลตรงจาก host filesystem ไม่ได้ ต้องผ่าน container เสมอ
Bind mountเห็นและแก้ไขไฟล์ตรงจาก host ได้ทันทีผูกกับ path เฉพาะของ host เครื่องนั้น ย้ายข้าม environment ยาก
  • ใช้ bind mount แทน named volume สำหรับข้อมูลฐานข้อมูลใน production ทำให้ portability หายไป
  • รัน docker rm -v หรือ docker compose down -v โดยไม่ตั้งใจ แล้วข้อมูลใน volume หายทั้งหมด
  • ไม่มีแผนสำรองข้อมูลสำหรับ volume เลย คิดว่า “volume คงอยู่ตลอดไป” แล้วไม่เคย backup
  • คิดว่าข้อมูลใน volume จะรอดจาก docker system prune -a --volumes โดยไม่ตรวจสอบก่อนรัน

💡 ตัวอย่างจากของจริง

official Postgres image บน Docker Hub แนะนำให้ mount named volume ที่ /var/lib/postgresql/data เป็น pattern มาตรฐานสำหรับ production เพื่อให้ข้อมูลฐานข้อมูลรอดจากการอัปเดต image หรือสร้าง container ใหม่

เกิดอะไรขึ้นกับ named volume เมื่อคุณรัน `docker rm` บน container ที่ใช้งานอยู่?
flag ใดที่ mount named volume ด้วย short syntax?
`docker volume prune` ทำอะไร?
ถ้าคุณระบุชื่อ volume ที่ยังไม่มีอยู่ใน `docker run` Docker จะทำอะไร?