มาเล่าเรื่องราว Docker Compose โดยการทำ Load Balancing กัน

Docker Compose คืออะไรก่อนจะรู้จักมันว่าคืออะไร มาทำความรู้จัก Docker และ Dockerfile ก่อนถ้าใครรู้แล้วมาต่อกันครับ ลองนึกภาพตามนะครับ ถ้าเรามีสิ่งที่ต้อง Run เยอะๆ เพราะตามหลักการออกแบบระบบที่ถูกต้องเราต้องทำ Microservices แยกเป็นส่วนๆซึ่งมันก็จะแยกย่อยออกไปอีกหลายอันเลย เราจะมาเสียเวลาทำทีละอันทำไม Docker Compose เลยเอามาแก้ปัญหานี้ Docker Compose ก็คือตัวจัดการ Container พร้อมๆกันหลายๆอันและทำการ Sync Container แต่ละอันได้ด้วย พูดง่ายๆคือการทำ Group Container หลายๆอันให้อยู่ใน Network เดียวกัน และที่สำคัญเราไม่ต้องมาจำคำสั่ง Docker ให้มากมายครับ

จากความเดิมตอนที่แล้ว Dockerfile เราได้ได้ทำการสร้าง Dockerfile มาแล้วเราจะใช้ Code ชุดเดิมในการทำ

ผมได้สร้าง Folder ชื่อ ว่า api และได้เอา Code เดิมจากตอนที่แล้วย้ายเข้าไปใน Folder Api path ก็จะได้เป็น exampledocker/api

หลังจากนั้นไปแก้ไข scripts โดยเพิ่ม

"start" : "node index.js"

และทำการแก้ไข Dockerfile นิดหน่อยโดยผมจะใช้ npm มาช่วย Run จริงๆใครใช้ yarn ก็ดีครับไม่ต้องเปลี่ยนมันเร็วกว่า npm 5555+

ต่อมาสร้าง File docker-compose.yml

โดย Coppy Code ต่อไปนี้ใส่ไปใน docker-compose.yml ซึ่งเราสามารถเลือกใช้ Version ต่างๆได้ตามใน https://docs.docker.com/compose/compose-file/ ซึ่งผมได้ทำการตั้งชื่อให้เป็น api-1 และทำการ build โดยชี้ไปที่ path api มันจะไปหา Dockerfile อัตโนมัติแล้วทำการ Build ตามนั้น และผมทำการ Mapping Port ของ Server(ให้สมมุติว่า Local เราก็คือ Server อันนึงครับ) เข้ากับ Port ของ Container

docker-compose up --build -d

หลังจากเราลอง run ดู คำสั่งนี้คือการ build และ run image บน background

docker ps

จากนั้นเราก็เช็คมัน Run สำเร็จไหมจากภาพถือว่าสำเร็จปกติครับ

ผลลัพก็เหมือนเรา Run Docker ตรงๆปกติเลย

ต่อมาผมลองเพิ่ม Redis เข้ามาอยู่ใน Network Docker ของเรา Redis ผมได้กล่าวไปตอน Docker แรกสุดเลย

cd api
npm install redis

หลักจากนั้นผมทำการติดตั้ง Redis ใน Nodejs ก่อน

หลังจากนั้นผมก็ทำการตั้งชื่อเป็น redis-server และทำการ pull image redis เพื่อมาทำการ build ในการต่อไป

จากนั้น Coppy Code ไปแทนใน api/index.js ซึ่งจะเห็นว่ามันเพิ่มมาจากเดิมนิดหน่อย ซึ่งผมได้การ import redis และได้ทำการ config ,set และ update ซึ่ง port default container ของ redis คือ 6379 แต่ถ้ามันไม่ได้อยู่ใน docker compose มันจะเรียกตรงๆแบบนี้ไม่ได้นะครับ ตอนนี้มันมองว่าอยู่ใน Network เดียวกันครับ

*ผมแค่ยกตัวอย่างนะครับหลักความจริง Database กับ Api เรามันไม่ควรมาอยู่ในที่เดียวกันครับ หมายถึงบน Server เดียวกันมันมีหลายเหตุผลมากไม่ว่าจะเรื่อง Security หรือการ Maintenance และอีกหลายอย่างมากครับ

เหมือนเดิมครับหลังจากนั้น Build And Run เสร็จ เราก็มาดูผลลัพธ์มันครับ

หลังจากนั้นก็จะได้ Value หลัง Test เปลี่ยนแปลงไปตลอดละครับเหมือนเรากำลังเช็คคนเข้ามาใช้ Api เรากี่คนนั้นแหละครับ

หลังจากนั้นผมลอง sh เข้าไปใน container ของ redis ดูค่าที่เรากดก็จะมาอยู่ตรงนี้ด้วยเพราะมันเชื่อมกันแล้ว

ลองเข้าไปดูในตัว docker ก็ได้จะเห็นว่ามันอยู่ใน Network เดียวกันแล้ว

ต่อมาผมจะเอา Nginx เข้ามาอยู่ใน Network นี้ด้วย Nginx คืออะไร คือ Web Server ที่ได้รับความนิยมมากๆ เพราะมันเป็น Open Source ที่เราเอาไป Custom ใช้ได้หลายแบบมาก

หลังจากนั้นสร้าง Folder nginx ขึ้นมาและทำการ สร้าง Dockerfile สำหรับ nginx และ สร้าง nginx.conf ขึ้นมา

ผมจะอธิบาย nginx.conf แบบคร่าวๆก่อน ผมสร้างกลุ่มก้อน Api ไว้ภายใน upstream ที่มีชื่อว่า api และทำการใส่ least_conn เพื่อจะให้ Users เข้าหา Server ที่มีคนใช้น้อยที่สุด อ่านเพิ่มเติมได้ ที่นี่ มันคือการทำ Load Balancing แหละอีกตัวล่มก็ไปใช้อีกตัวอีกตัวคนใช้เยอะก็ไปใช้อีกตัว จริงมันมี Auto สร้างขึ้นมาอีกแต่ผมจะไม่พูดลงลึกไปขนาดนั้นนะครับ และตรง server {} ผมก็ทำการ proxy ไปหา upstream ชื่อว่า api ส่วน config ต่างๆไปหาอ่านเพิ่มเติมได้เลยครับ

ส่วนนี้เป็น Dockerfile ของ Folder nginx ครับ กำหนด base image และกำหนด port 80

จากนั้นกลับไปที่ docker-compose.yml ของเรากันและ Coppy ไปวางได้เลย จะเห็นว่าผมได้ สร้าง api-1 api-2 api-3 และทำการกำหนด port ให้ container เป็น 3000–3002 ผมไม่ mapping port เพราะผมจะให้เข้าผ่านตัว nginx เท่านั้น โดยชื่อและ port ต้องสอดคล้องกันกับชื่อของ api และ port ใน nginx.conf ส่วน depends_on เป็นการรอให้สิ่งที่อยู่ในนั้นถูกสร้างแล้ว run เสร็จก่อนถึงจะ run ตัวเอง ส่วน enviornment คือจริงๆคือการตั้งค่า Values ส่วนใหญ่จะเอาไว้ไปเป็น Config ใน Code ส่วน restart : always คือถ้า container มันหยุดทำงานให้มันทำการ run ตัวเองใหม่เลยเราไม่จำเป็นต้องมาห่วงว่าต้องไป start ใหม่เอง

จากนั้นไปแก้ Code ใน api/index.js นิดหน่อย เพิ่ม server:${process.env.NODE_SERVER} เอาไว้เช็คว่าตอนนี้เราอยู่บน Api อันไหนอยู่

docker-compose up --build -d

มาลอง Run ดูกันครับตาม Step เลยครับ Build and Run

มาดูผลลัพธ์ที่เรา Run ไป

หลังจากนั้นก็เข้าผ่าน Browser หรือ Postman ผลลัพธ์ก็ตามรูปเลยครับตอนนี้ใช้
api-3 อยู่ส่วนตัวนับก็ยังนับเหมือนเดิมตัวนับเชื่อมกันหมดทุกอัน

จากนั้นผมมาสร้าง file .env เพื่อจะได้ config ค่าต่างๆอยู่ในที่เดียวจะได้ดูเป็นระเบียบ

หลังจากนั้นผมก็มาแทนค่าโดยเป็น ${value} แค่นี้ file .env กับ docker compose ก็ sync กันแล้วลอง Run และ Build ผลลัพก็จะได้เหมือนเดิม

ผมสร้าง .dockerignore ไว้ใน api เพื่อที่จะให้มันไม่เอา Node_modules เข้าไปครับจริงๆแล้ว Code เราขึ้น git เราก็ ignore มันอยู่แล้วครับผมยกตัวอย่างเผื่อ Run ใน Local ไว้ครับ จริงทำใน Local ต้องมีเรื่องของ Volume อีกเพื่อจะได้ไม่เสียเวลามา Build ใน Local ตลอด แต่ส่วนใหญ่เวลาทำในเครื่องผมไม่ได้ Run docker อยู่แล้วเลยไม่ได้ทำการยกตัวอย่างให้ครับ งั้นบทความมันจะยาวกว่านี้อีก 5555+

เป็นยังไงกันบ้างครับสำหรับบทความนี้จริงๆมันก็มีอันที่ไม่ได้เอามายกตัวอย่างอีกเยอะแยะครับแต่แค่นี้ก็ครอบคลุมมากแล้วครับ นอกนั้นต้องไปลองเล่นเองจริงๆครับ แค่นี้ก็เพียงพอสำหรับไปติดตั้งบน Server แล้วครับ แต่สมัยนี้ส่วนใหญ่จะทำผ่าน CI/CD กันครับไว้ผมจะมาเล่าถึงมันนะครับ

( CR. ธำรงค์ ไชยวงค์ )

--

--

No responses yet