พอดีในวงกินเบียร์มีการพูดคุยเรื่องการใช้งาน Docker สำหรับการพัฒนาระบบงาน
ซึ่งมันมีทางเลือกในการใช้งานหลากหลายแนวทางมาก ๆ
ดังนั้นจึงสรุปไว้กันลืมนิดหน่อย
ว่าคุยอะไรไปบ้าง (เท่าที่จำได้น่าจะคุยและ demo ให้ดูประมาณไม่เกิน 10 นาที)
มาเริ่มกันเลย
เริ่มจากปัญหาคือ Work on my machine
นักพัฒนานั้นก็จะทำการเขียน code ติดตั้ง library/dependency ทำการ build/compile จัดการข้อมูลต่าง ๆ ใน database แน่นอนว่า ทุกอย่างมัน work หรือทำงานได้ตามที่คาดกวังบนเครื่องนักพัฒนา แต่เมื่อไปติดตั้งสิ่งต่าง ๆ ที่พูดมาข้างต้นแล้ว บนเครื่องอื่น ๆ ยกตัวอย่างเช่น CI server, Dev/Test/Staging/Production กลับไม่ได้ !! ต้องใช้เครื่องมือและวิธีการที่ต่างออกไป สุดท้ายก็ไม่เหมือนกันอีกแล้ว มันยังไงกันนะ !! ยกตัวอย่างของปัญหา เครื่องนักพัฒนาใช้ Mac OS พัฒนาระบบงานด้วยภาษา Go จัดการ dependency ด้วย go mod ทำการ compile และ build เป็น binary file ทำการทดสอบทั้ง Unit test และ Integration test ทำการ deploy และติดตั้งระบบงานด้วยการนำ binary file ไป run เพียงเท่านี้ก็จบแล้ว ปัญหาที่พบเจอบ่อย ๆ คือ- Version ของภาษา Go ที่ต่างกัน
- Binary file ที่สร้าง และ deploy ใน environment ต่าง ๆ มีปัญหา เพราะว่าใช้ OS ต่างกัน
- การทำ integration test ยากมาก ๆ
จากปัญหาต่าง ๆ ที่ยังเกิดขึ้น เลยมีการพูดถึงการนำ Docker มาใช้งาน
ซึ่งการใช้งานต้องแบ่งออกเป็นขั้นตอนแยกกันดังนี้ อย่าเอามารวมกันนะ ไม่งั้นมั่วแน่นอน- Docker สำหรับการพัฒนาบนเครื่องของนักพัฒนาแต่ละคน
- Docker สำหรับการทดสอบ
- Docker สำหรับการ deploy
1. Docker สำหรับการพัฒนาบนเครื่องของนักพัฒนาแต่ละคน
เริ่มง่าย ๆ คือ ติดตั้ง Docker ก่อนนะ กินทรัพยากรมากพอดู ดังนั้นเครื่องนักพัฒนาต้องแรงพอตัว เมื่อเครื่องพร้อมก็ไปเลือก Docker Image ของภาษา Go ที่ต้องการจาก Docker Hub ใช้งานง่าย ๆ ด้วย command line ดังนี้ ตัวอย่างใช้ภาษา Go version 1.11.2 บน Alpine OS Code ตัวอย่างที่พอจะเขียนได้ตอนนั้น [gist id="3575eca14ac0cd64d44d5526d9e66f09" file="hello.go"] ทำการ compile และ run ด้วย Docker ดังนี้ [code] # Run $docker container run --rm -w /xxx -v $(pwd):/xxx golang:1.11.2-alpine3.8 go run hello.go # Build binary file และ Run $docker container run --rm -w /xxx -v $(pwd):/xxx golang:1.11.2-alpine3.8 go build -o ./app $docker container run --rm -w /xxx -v $(pwd):/xxx golang:1.11.2-alpine3.8 ./app [/code] แต่ถ้าเบื่อ command line เยอะ ๆ ก็สร้าง Dockerfile มาใช้ซะ เริ่มจากสร้างไฟล์ Dockerfile_dev สำหรับทำการ compile/build/run ระบบงาน [gist id="3575eca14ac0cd64d44d5526d9e66f09" file="Dockerfile_dev"] ทำการ run ด้วยคำสั่ง [code] $docker image build -t demo -f Dockerfile_dev . $docker container run --rm demo [/code]2. อย่าลืมเพิ่มส่วนของการทดสอบ และพวกการจัดการ library/dependency เข้าไปด้วยนะ
เริ่มด้วยการเขียน Dockerfile_testing ขึ้นมา [gist id="3575eca14ac0cd64d44d5526d9e66f09" file="Dockerfile_testing"] ทำการ run ด้วยคำสั่ง [code] $docker image build -t demo -f Dockerfile_testing . $docker container run --rm -t demo [/code]3. อีกส่วนคือการใช้ Docker สำหรับการ deploy
สิ่งที่แนะนำไปคือ การใช้งาน Multi-stage build สำหรับการสร้าง Docker Image เพื่อให้ได้ Docker Image ที่มีของเท่าที่จำเป็น เนื่องจากตอนนี้ Docker Image ของระบบจากขั้นตอนที่ 1 และ 2 มันใหญ่มาก เพราะว่ามีทั้ง Go และอื่น ๆ อีกมากมาย แต่ในการ deploy ระบะบบงานของเรานั้น ต้องการเพียงนำ binary file ไปติดตั้งบน OS ที่ต้องการเท่านั้น ดังนั้นมาใช้งาน Multi-stage build กัน ทำการสร้าง Dockerfile ดังนี้ [gist id="3575eca14ac0cd64d44d5526d9e66f09" file="Dockerfile"] ทำการ run ด้วยคำสั่ง [code] $docker image build -t demo -f Dockerfile . $docker container run --rm -t demo [/code] ส่งผลทำให้ขนาดของ Docker Image ของระบบงานเราเล็กลงไปอย่างมาก จากตัวอย่างนี้ลดจาก 431 MB เหลือเพียง 6.92 MB เท่านั้นเอง ตัวอย่าง code อยู่ที่ Github:Up1:Demo with Goเพียงเท่านี้เราก็สามารถนำ Docker มาใช้ในการพัฒนาระบบงานได้อย่างแจ่มแล้วนะครับ ถ้าไม่อยากเขียนเยอะ ๆ ก็ไปใช้ Docker Compose ต่อไปนะ ขอให้สนุกกับการ coding ครับ