ข้อมูลและ Volumes
วัดบน Docker Desktop 4.81.0 / Engine 29.6.1 (macOS, linux/arm64), 2026-09-30
ทำไมข้อมูลใน container ถึงหายไป
หัวข้อที่มีชื่อว่า “ทำไมข้อมูลใน container ถึงหายไป”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
Stop ไม่ใช่ remove
หัวข้อที่มีชื่อว่า “Stop ไม่ใช่ remove”ข้อมูลหายตอน 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 ephA /dataA /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/fkeepkeeppersisted$ 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 mounts | path ใดก็ได้บน filesystem ของ host | คุณ | ไฟล์ที่เขียนใน container ปรากฏในไดเรกทอรีบน host - Bind Mounts |
| tmpfs mounts | หน่วยความจำเท่านั้น (ไม่เขียนลงดิสก์ของ container) | Kernel | --tmpfs /scratch:size=8m ปฏิเสธ MB ที่ 9 และว่างเปล่าเมื่อ restart (ด้านล่าง) |
tmpfs: เร็ว จำกัดขนาดได้ และหายเมื่อ restart
หัวข้อที่มีชื่อว่า “tmpfs: เร็ว จำกัดขนาดได้ และหายเมื่อ 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 devicetmpfs 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!'"Reading AI-generated code
หัวข้อที่มีชื่อว่า “Reading AI-generated code”Script ที่ AI เขียนซึ่ง “เก็บ build cache ใน RAM เพื่อความเร็ว” แล้วรันเครื่องมือที่ดาวน์โหลดมาไว้ตรงนั้น:
🐛 หา bug ในโค้ดนี้
#!/bin/shset -eu# AI: tmpfs = fast scratch space, capped at 8 MBdocker run --rm --tmpfs /work:size=8m alpine:3.24 sh -c 'printf "#!/bin/sh\necho worker ran\n" > /work/tool.shchmod +x /work/tool.sh/work/tool.sh'เฉลย
Script ล้มเหลวทั้งที่เขียนไฟล์และ chmod executable แล้ว:
$ sh scripts/run-worker.shsh: /work/tool.sh: Permission denied # exit code 126mount แบบ --tmpfs มีค่าเริ่มต้นเป็น noexec,nosuid,nodev (เห็นได้ในบรรทัด mount ด้านบน) จึงรันอะไรบน mount นั้นไม่ได้ เพิ่ม option exec เมื่อ tmpfs ต้องเก็บโปรแกรมจริงๆ:
#!/bin/shset -eudocker 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 กับข้อมูลเท่านั้น
Mental Model
หัวข้อที่มีชื่อว่า “Mental Model”filesystem ของ container คือ image บวก writable layer ส่วนตัวที่ทิ้งได้หนึ่งชั้น อะไรที่ต้องอยู่ยาวกว่า container ต้องถูกเขียนลงสิ่งที่ mount เข้าไป: volume (Docker เป็นเจ้าของพื้นที่), bind mount (คุณเป็นเจ้าของ path) หรือ tmpfs (RAM ที่ตั้งใจให้อายุสั้น) อายุของ container กับอายุของข้อมูลเป็นการตัดสินใจคนละเรื่อง
Trade-offs
หัวข้อที่มีชื่อว่า “Trade-offs”| ตัวเลือก | ข้อดี | ข้อเสีย |
|---|---|---|
| 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 |
Common Misconceptions
หัวข้อที่มีชื่อว่า “Common Misconceptions”- “
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 Volumes | docker 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 การกู้คืน การย้าย |