Docker Volume: จัดการข้อมูลแบบถาวรใน Container
ในบทความที่แล้ว เราได้เรียนรู้วิธีการสร้าง Docker Container สำหรับเว็บแอปพลิเคชัน Node.js อย่างง่าย แต่สิ่งหนึ่งที่เรายังไม่ได้พูดถึงคือ การจัดการข้อมูลที่อยู่ใน Container อย่างถาวร เมื่อ Container หยุดทำงานหรือถูกลบ ข้อมูลทั้งหมดที่อยู่ในนั้นก็จะหายไปด้วย แล้วเราจะทำอย่างไรถ้าเราต้องการเก็บข้อมูลที่สำคัญ เช่น ฐานข้อมูล หรือไฟล์ที่ผู้ใช้อัปโหลด?
คำตอบคือ Docker Volume! ในบทความนี้ เราจะมาเรียนรู้เรื่อง Volume กันตั้งแต่เริ่มต้น เพื่อให้คุณสามารถจัดการข้อมูลใน Container ของคุณได้อย่างมีประสิทธิภาพ
ทำความเข้าใจเรื่อง Volume และ Bind Mount
Docker มีสองวิธีหลักในการจัดการข้อมูลที่ Container สร้างขึ้นหรือใช้งาน:
- Volume: Docker จะเป็นผู้จัดการพื้นที่จัดเก็บข้อมูลนี้อย่างเต็มที่ Volume จะถูกสร้างและจัดการโดย Docker เอง และถูกเก็บไว้ในส่วนหนึ่งของระบบไฟล์ที่ Docker จัดการ ซึ่งทำให้ Volume เหมาะสำหรับการเก็บข้อมูลที่ Container สร้างขึ้นและต้องการให้คงอยู่ แม้ Container จะถูกลบไปแล้ว
- Bind Mount: เป็นการเชื่อมต่อไฟล์หรือโฟลเดอร์จาก Host (เครื่องที่เรากำลังรัน Docker) เข้ากับ Container โดยตรง Container จะสามารถเข้าถึงและแก้ไขไฟล์เหล่านั้นได้ ซึ่งเหมาะสำหรับการพัฒนาที่ต้องการแก้ไขโค้ดบน Host และเห็นผลลัพธ์ใน Container ทันที แต่ Bind Mount อาจมีปัญหาเรื่องความเข้ากันได้ของระบบปฏิบัติการ
สรุปง่ายๆ คือ Volume เหมาะสำหรับการเก็บข้อมูล Container ที่ต้องการความถาวร ส่วน Bind Mount เหมาะสำหรับการพัฒนาที่ต้องการความรวดเร็วในการแก้ไขไฟล์
สร้างและใช้งาน Volume
มาลองสร้างและใช้งาน Volume กันเลยดีกว่า สมมติว่าเราต้องการสร้าง Volume เพื่อเก็บข้อมูลของเว็บแอปพลิเคชัน Node.js ของเรา (จากบทความก่อนหน้า) เราจะใช้คำสั่ง docker volume create:
docker volume create my_app_data
คำสั่งนี้จะสร้าง Volume ชื่อ my_app_data ตอนนี้เราต้องเชื่อมต่อ Volume นี้กับ Container ของเราตอนที่รัน Container โดยใช้ flag -v หรือ --mount
ตัวอย่างการใช้ -v:
docker run -d -p 3000:3000 -v my_app_data:/app/data my_app_image
คำสั่งนี้จะรัน Container จาก Image my_app_image และเชื่อมต่อ Volume my_app_data เข้ากับโฟลเดอร์ /app/data ภายใน Container นั่นหมายความว่าข้อมูลใดๆ ที่ถูกเขียนลงใน /app/data ภายใน Container จะถูกเก็บไว้ใน Volume my_app_data อย่างถาวร
ตัวอย่างการใช้ --mount:
docker run -d -p 3000:3000 --mount source=my_app_data,target=/app/data my_app_image
คำสั่งนี้ทำงานเหมือนกับตัวอย่างก่อนหน้า แต่ใช้ syntax ของ --mount ซึ่งมีความชัดเจนกว่าและรองรับ option เพิ่มเติม
ข้อควรระวัง: โฟลเดอร์ /app/data ภายใน Container จะถูกแทนที่ด้วย Volume หากมีข้อมูลอยู่ใน /app/data ก่อนหน้านี้ ข้อมูลนั้นจะถูกซ่อนไว้ (แต่ไม่ได้ถูกลบ) จนกว่า Volume จะถูกยกเลิกการเชื่อมต่อ
กรณีใช้งานจริง: สมมติว่าเว็บแอปพลิเคชัน Node.js ของเรามีฟังก์ชันให้ผู้ใช้อัปโหลดรูปภาพ เราสามารถใช้ Volume เพื่อเก็บรูปภาพเหล่านั้นได้อย่างถาวร โดยกำหนดให้โฟลเดอร์ที่เก็บรูปภาพ (เช่น /app/uploads) ถูกเชื่อมต่อกับ Volume
ข้อผิดพลาดที่พบบ่อย:
- ลืมสร้าง Volume ก่อนรัน Container: หาก Volume ยังไม่ได้ถูกสร้าง Docker จะสร้างโฟลเดอร์เปล่าๆ ภายใน Container แทนที่จะเชื่อมต่อกับ Volume ที่ต้องการ
- ระบุ path ผิด: ตรวจสอบให้แน่ใจว่า path ที่ระบุใน
-vหรือ--mountตรงกับโฟลเดอร์ที่ Container ต้องการเข้าถึง
แชร์ Volume ระหว่าง Container
Volume ไม่ได้ถูกผูกติดอยู่กับ Container ใด Container หนึ่งเท่านั้น เราสามารถแชร์ Volume เดียวกันระหว่าง Container หลายตัวได้ ซึ่งมีประโยชน์ในกรณีที่เราต้องการให้ Container เหล่านั้นเข้าถึงข้อมูลชุดเดียวกัน
ตัวอย่าง: สมมติว่าเรามีเว็บแอปพลิเคชัน Node.js และ Nginx Container ที่ทำหน้าที่เป็น reverse proxy เราสามารถแชร์ Volume เดียวกันเพื่อเก็บไฟล์ static (เช่น รูปภาพ, CSS, JavaScript) เพื่อให้ Nginx สามารถเข้าถึงไฟล์เหล่านั้นได้โดยตรง
ขั้นตอน:
- สร้าง Volume:
docker volume create shared_static - รัน Node.js Container โดยเชื่อมต่อ Volume:
docker run -d -p 3000:3000 -v shared_static:/app/public my_app_image(สมมติว่าไฟล์ static อยู่ใน/app/public) - รัน Nginx Container โดยเชื่อมต่อ Volume:
docker run -d -p 80:80 -v shared_static:/usr/share/nginx/html nginx(สมมติว่า Nginx ใช้/usr/share/nginx/htmlเป็น root directory)
ตอนนี้ทั้ง Node.js และ Nginx Container สามารถเข้าถึงไฟล์ static ใน Volume shared_static ได้
สรุป
ในบทความนี้ เราได้เรียนรู้เกี่ยวกับ Docker Volume ซึ่งเป็นเครื่องมือสำคัญสำหรับการจัดการข้อมูลที่ถาวรใน Container เราได้เรียนรู้วิธีการสร้างและใช้งาน Volume, การแชร์ Volume ระหว่าง Container, และข้อควรระวังในการใช้งาน Volume
ในบทความถัดไป เราจะไปเรียนรู้เรื่อง Docker Compose ซึ่งเป็นเครื่องมือที่ช่วยให้เราสามารถกำหนดค่าและจัดการ Container หลายตัวที่ทำงานร่วมกันได้อย่างง่ายดาย