วันนี้ไปดู release note ของ Docker edge version (v17.05.0 ce) พบว่า
มีความสามารถที่กำลังต้องการคือ Multi-stage build
ซึ่งช่วยทำให้การสร้าง image ของระบบงานได้ง่าย และสะดวกขึ้น
ที่สำคัญยังช่วยลดขนาดของ image อีกด้วย
มาลองใช้งานกันดู
ก่อนอื่นมาดูขั้นตอนการสร้าง image แบบปกติกันก่อน
ระบบตัวอย่างเป็นการสร้าง image ของระบบที่พัฒนาด้วยภาษา Go
ซึ่งส่วนใหญ่มักจะสร้าง image ขึ้นมาสองตัวคือ
- สำหรับทำการ build เพื่อ compile และสร้างไฟล์ binary ของระบบ
- สำหรับการ deploy นั่นคือทำการทำเอาไฟล์ binary จาก image ตัวที่ 1
ปล. บางคนก็ทำเพียง image เดียวเท่านั้น
แต่ผลที่ได้คือ ขนาดของ image ที่ใหญ่มาก ๆ
เพราะว่ามีทั้ง OS + Golang (257MB), Library และ source code
ทั้ง ๆ ที่เราต้องการเพียง OS และไฟล์ binary เท่านั้นเอง !!
ดังนั้นขอแนะนำให้ทำเป็น 2 image น่าจะดีกว่า
ซึ่งวิธีการนี้เราเรียกว่า Builder pattern
ดังนั้นต้องสร้าง Dockerfile ขึ้นมา 2 ไฟล์ (ชีวิตดูลำบาก)
การนำไฟล์ binary จาก container หนึ่งไปอีก container หนึ่งทำอย่างไร ?
เช่นการ map volume หรือ copy ข้าม container กันเลย
ตัวอย่าง script ของการใช้งาน
ผลที่ได้คือ image 2 ตัวดังนี้
จากนั้นทำการสร้าง container จาก image ที่ได้คือ my_image:latest เช่น
$docker container run --rm -p 8080:8080 my_image:latest
ปกติก็ใช้วิธีนี้กัน ซึ่งก็ใช้งานได้ดีนะ
มาดูกันต่อสิว่าแล้ว Multi-stage build มันเป็นอย่างไร ?
จากวิธีการข้างต้น ต้องจัดการ Dockerfile 2 ไฟล์
ซึ่งดูลำบากน่าดู
ดังนั้นจะดีไหม ถ้ายุบให้เหลือเพียงไฟล์เดียว น่าจะสบายขึ้นไหม ?
จากวิธีการข้างต้น จะสร้าง image ขึ้นมา 2 ตัว
ซึ่งต้องลบ image ตัวแรกออกไปตลอด
ดังนั้นจะดีไหม ถ้าเราสร้างไฟล์ image เดียวไปเลย
เราสามารถเขียน Dockerfile แบบใหม่ได้ดังนี้
คำอธิบาย
- COPY –from=0 คือการบอกว่าให้ copy ข้อมูลจาก image แรก โดยเริ่มจากตำแหน่งที่ 0
- หรืออาจจะใช้ COPY –from=build ก็ได้นะครับ ทำให้อ่านเข้าใจง่ายขึ้นอีก
- จากตัวอย่างทำการ copy ไฟล์ app ซึ่งเป็นไฟล์ binary มายัง image ที่สอง
ทำการสร้าง image ด้วยคำสั่ง
$docker image build -t my_demo . -f Dockerfile_multi
จากนั้นก็ทำการสร้าง container จาก image ชื่อว่า my_demo
เพียงเท่านี้ก็เป็นอันเรียบร้อย
สำหรับการเริ่มใช้งาน Multi-stage build
ง่ายขึ้นไหมนะ ?
ตัวอย่าง source code และ configuration ต่าง ๆ อยู่ที่ Github::Up1::Docker with Multi-stage build