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

ข้อมูลและ Volumes

วัดบน Docker Desktop 4.81.0 / Engine 29.6.1 (macOS, linux/arm64), 2026-09-30

Container มี writable layer อยู่ด้านบนของ image layer ที่เป็น read-only ทุกไฟล์ที่คุณสร้าง แก้ไข หรือลบภายใน container ที่กำลังทำงานอยู่ จะอาศัยอยู่ใน writable layer นั้นเท่านั้น ทันทีที่ container ถูกลบด้วย docker rm layer นั้นก็หายไปอย่างถาวร

นี่เป็นการออกแบบที่ตั้งใจ Container ถูกออกแบบมาให้ไม่มี state (stateless) ใช้แล้วทิ้งได้ และสามารถสร้างขึ้นใหม่ได้เสมอ คุณควรหยุด container ลบทิ้ง แล้วสร้างใหม่จาก image เดิมได้ตลอดเวลา ถ้าข้อมูลของคุณอยู่ภายใน container โมเดลนี้จะล้มเหลว

flowchart TB
  W["Writable layer (this container only): runtime writes, gone on docker rm"]
  I2["Image layer (read-only): COPY app files"]
  I1["Image layer (read-only): node:24-alpine base"]
  W --> I2 --> I1
Container: image layer รวมกับ writable layer หนึ่งชั้น

ข้อมูลหายตอน docker rm ไม่ใช่ตอน docker stop container ที่หยุดแล้วยังเก็บ writable layer ไว้บนดิสก์ docker diff แสดงว่า layer นั้นเก็บอะไรอยู่:

$ docker run --name eph alpine:3.24 sh -c "mkdir -p /data && echo 'hello world' > /data/message.txt && cat /data/message.txt"
hello world
$ docker diff eph
A /data
A /data/message.txt
$ docker run -d --name keep alpine:3.24 sh -c 'mkdir -p /data; echo persisted > /data/f; sleep 300'
$ docker stop -t 1 keep && docker start keep && docker exec keep cat /data/f
keep
keep
persisted
$ docker rm eph
$ docker run --rm alpine:3.24 sh -c "cat /data/message.txt 2>/dev/null || echo 'File is gone!'"
File is gone!

ไฟล์รอดจาก stop/start ของ container เดิม และหายไปสำหรับ container ใหม่ จาก image เดียวกัน นั่นคือเหตุผลที่ “container restart แล้วข้อมูลยังอยู่” ไม่ได้พิสูจน์ว่าข้อมูลคงทน: พอสร้าง container ใหม่ (docker rm + docker run, docker compose up หลังแก้ config, อัปเกรด image) ข้อมูลก็หาย

Docker มีกลไกสามอย่างเพื่อออกจาก writable layer ชั่วคราว คอลัมน์สุดท้ายของทุกแถวสร้างจริงบน Mac เครื่องนี้:

ตัวเลือกข้อมูลอยู่ที่ไหนจัดการโดยหลักฐาน (Engine 29.6.1)
Named volumesไดเรกทอรีที่ Docker จัดการ (อยู่ใน VM บน Docker Desktop)Dockerรอดหลัง docker rm container - Named Volumes
Bind mountspath ใดก็ได้บน filesystem ของ hostคุณไฟล์ที่เขียนใน container ปรากฏในไดเรกทอรีบน host - Bind Mounts
tmpfs mountsหน่วยความจำเท่านั้น (ไม่เขียนลงดิสก์ของ container)Kernel--tmpfs /scratch:size=8m ปฏิเสธ MB ที่ 9 และว่างเปล่าเมื่อ restart (ด้านล่าง)
$ docker run --rm --tmpfs /scratch:size=8m alpine:3.24 sh -c 'mount | grep scratch; dd if=/dev/zero of=/scratch/big bs=1M count=20; df -h /scratch | tail -1'
tmpfs on /scratch type tmpfs (rw,nosuid,nodev,noexec,relatime,size=8192k)
dd: error writing '/scratch/big': No space left on device
tmpfs 8.0M 8.0M 0 100% /scratch

การเขียน 20 MB หยุดที่ 8 MiB พอดี สังเกต noexec ใน mount options: --tmpfs ธรรมดารันโปรแกรมไม่ได้ (ดู bug ด้านล่าง) หลัง docker stop + docker start container เดิมพบ /scratch ว่างเปล่า ขณะที่ไฟล์ที่เขียนบน filesystem ปกติยังอยู่ docker inspect แสดง tmpfs ใน .HostConfig.Tmpfs ({"/scratch":""}) ไม่ใช่ใน .Mounts ([]) รูปแบบยาวคือ --mount type=tmpfs,destination=/scratch,tmpfs-size=8m tmpfs เหมาะกับข้อมูลชั่วคราวและ secret ที่ไม่ต้องการเขียนลงดิสก์ หน่วยความจำที่ใช้นับรวมใน memory limit ของ container

ก่อนเรียนรู้วิธีเก็บข้อมูลถาวร ควรเห็นปัญหาด้วยตาตัวเองก่อน snippet ด้านล่างจะสร้างไฟล์ภายใน container ลบ container นั้น แล้วรัน container ใหม่ — ไฟล์หายไปแล้ว

# Run a container and write a file
docker run --name ephemeral-demo alpine:3.24 sh -c "mkdir -p /data && echo 'hello world' > /data/message.txt && cat /data/message.txt"

# Remove the container
docker rm ephemeral-demo

# Start a brand-new container from the same image
docker run --rm alpine:3.24 sh -c "cat /data/message.txt 2>/dev/null || echo 'File is gone!'"

Script ที่ AI เขียนซึ่ง “เก็บ build cache ใน RAM เพื่อความเร็ว” แล้วรันเครื่องมือที่ดาวน์โหลดมาไว้ตรงนั้น:

🐛 หา bug ในโค้ดนี้

scripts/run-worker.sh
#!/bin/sh
set -eu
# AI: tmpfs = fast scratch space, capped at 8 MB
docker run --rm --tmpfs /work:size=8m alpine:3.24 sh -c '
printf "#!/bin/sh\necho worker ran\n" > /work/tool.sh
chmod +x /work/tool.sh
/work/tool.sh'
เฉลย

Script ล้มเหลวทั้งที่เขียนไฟล์และ chmod executable แล้ว:

$ sh scripts/run-worker.sh
sh: /work/tool.sh: Permission denied # exit code 126

mount แบบ --tmpfs มีค่าเริ่มต้นเป็น noexec,nosuid,nodev (เห็นได้ในบรรทัด mount ด้านบน) จึงรันอะไรบน mount นั้นไม่ได้ เพิ่ม option exec เมื่อ tmpfs ต้องเก็บโปรแกรมจริงๆ:

scripts/run-worker.sh
#!/bin/sh
set -eu
docker run --rm --tmpfs /work:exec,size=8m alpine:3.24 sh -c '
printf "#!/bin/sh\necho worker ran\n" > /work/tool.sh
chmod +x /work/tool.sh
/work/tool.sh'

เมื่อใส่ :exec การรันพิมพ์ worker ran ควรเก็บ executable ไว้ใน image และใช้ tmpfs กับข้อมูลเท่านั้น

filesystem ของ container คือ image บวก writable layer ส่วนตัวที่ทิ้งได้หนึ่งชั้น อะไรที่ต้องอยู่ยาวกว่า container ต้องถูกเขียนลงสิ่งที่ mount เข้าไป: volume (Docker เป็นเจ้าของพื้นที่), bind mount (คุณเป็นเจ้าของ path) หรือ tmpfs (RAM ที่ตั้งใจให้อายุสั้น) อายุของ container กับอายุของข้อมูลเป็นการตัดสินใจคนละเรื่อง

ตัวเลือกข้อดีข้อเสีย
Writable layer อย่างเดียวไม่ต้องตั้งค่าหายเมื่อ docker rm ช้ากว่า volume เมื่อเขียนหนัก และทำให้ container โต
Named volumeรอด rm พกพาข้าม host ตามชื่อได้ Docker จัดการให้ตำแหน่งมองไม่เห็นตรงๆ (อยู่ใน VM บน Desktop) ต้องใช้ docker run -v หรือ cp เพื่อดูข้างใน
Bind mountเห็นและแก้ไฟล์ด้วยเครื่องมือบน host ได้path, permission และความต่างของ OS บน host รั่วเข้า container
tmpfsไม่มี disk I/O จำกัดด้วย size= หายเมื่อ restartไม่คงทน นับรวมใน memory และเป็น noexec เว้นแต่ใส่ :exec
  • “docker stop ลบข้อมูลของฉัน” ไม่จริง: writable layer รอด stop/start มีแต่ docker rm (หรือสร้าง container ใหม่) ที่ทิ้งมัน
  • “container restart แล้วไฟล์ยังอยู่ แปลว่าคงทน” จะคงทนก็ต่อเมื่ออยู่บน volume หรือ bind mount การสร้างใหม่ทำให้หาย
  • “tmpfs คือ volume ที่เร็ว” มันคือหน่วยความจำ ว่างเปล่าเมื่อ container หยุด และเป็น noexec โดยค่าเริ่มต้น
  • “named volume คือโฟลเดอร์บน Mac ของฉัน” บน Docker Desktop มันอยู่ใน VM
บทเรียนหัวข้อ
Named Volumesdocker volume create/ls/inspect/rm การ mount volumes, copy-up, ความหมายของ prune
Bind Mountsการ map host paths เข้า container, -v เทียบกับ --mount, การแก้ไข source code แบบ live
Volumes vs Bind Mountsตารางเปรียบเทียบ ความสามารถในการพกพา ความเร็วเขียนที่วัดจริง read-only mounts
Backup & Restoreการ archive volumes ด้วย throwaway container การกู้คืน การย้าย
เกิดอะไรขึ้นกับไฟล์ที่เขียนภายใน container เมื่อคุณรัน docker rm?
ตัวเลือกพื้นที่จัดเก็บใดที่ Docker จัดการทั้งหมดและเก็บไว้ในไดเรกทอรีที่ Docker ควบคุม?
tmpfs mount เก็บข้อมูลไว้ที่ใด?
คุณรัน docker stop web แล้ว docker start web ไฟล์ที่แอปเคยเขียนลง filesystem ของตัวเองจะเป็นอย่างไร?
docker run --tmpfs /work alpine:3.24 sh -c '/work/tool.sh' ล้มเหลวด้วย 'Permission denied' ทั้งที่ script เป็น executable เพราะอะไร?