วิธีเชื่อม docker container มากกว่า 1 ตัวระหว่าง api กับ front end และ database ด้วย docker-network ผ่านทาง docker-compose เพื่อ dev ใน local



ปรกติแล้วแล้วการพัฒนาระบบสมัยนี้มักจะแบ่งแยกการทำงานออกเป็นสองส่วนหลัก ๆ คือ ส่วนที่ใช้การแสดงผล (Frontend) และอีกส่วนคือส่วนทำานด้านการประมวลผล Business logic ต่าง ๆ แน่นอนว่าทั้งสองส่วนนี้มีความสัมพันธ์แบบตัดกันไม่ขาด  ในอดีตนั้นก็ไม่ใช่ปัญหายุ่งยากอะไรที่จะทำ Vhost ขึ้นมาสองตัวโดยให้ตัวหนึ่งเป็น Frontend อีกตัวเป็น Backend หรือ API

ข้อดีของการมี API แน่นอนว่า Business Logic ต่าง ๆ จะถูกมาเก็บรวบรวมไว้ที่นี่ ที่เดียว การบริหารจัดการก็ทำได้ง่าย และยังสามารถให้บริการได้หลาย ๆ Client ที่ต้องการเข้ามาเชื่อมต่อ ผ่านทางภาษากลางของ API ที่เรียกว่า JSON (Javascript Object Notation)

ข้อเสียของการมี API คือการแก้ไขข้อมูลอะไรก็ช่างต้องพึงระหว่างการส่งผลกระทบ กับทุก ๆระบบที่มีการเรียกใช้งานอยู่ หากพลาดหรือไม่รอบครอบส่วนที่ทำการเชื่อมต่ออยู่นั้นจะกระทบไปหมด แน่นอนการออกแบบต้องให้รองรับทุก Client ที่เชื่อมต่อยู่ การ Custom API เพื่อให้รองรับเฉพาะงานนั้น ๆ ของ Client เดียวจึงไม่ค่อยเหมาะมากนัก อีกอย่าง คือค่าใช้จ่าย Cost ที่ต้องจ่ายเพิ่มเติมเข้ามาในส่วนของ Hardware และ Software

ในตัวอย่างต่อไปนี้ผมสร้าง Docker ขึ้นมา 3 ตัวคือส่วนของ Frontend ซึ่งทำงานอยู่บน Laravel ส่วนของ Backend  ที่ทำงานบน Laravel เช่นเดียวกัน และส่วนสุดท้าย Database ที่ประกอบไปด้วย  Redis, mariaDB และ phpmyadmin สำหรับจัดการข้อมูล ในส่วนของ Frontend นั้น ต้องการเรียกใช้ข้อมูลจาก Backend การเชื่อมต่อระหว่าง Docker container นั้นมีอยู่  2 ท่าด้วยกันคือ ผ่าน network ของ docker และ ผ่าน network ของ host ในตัวอย่างนี้ผมจะแสดงวิธีการเชื่อมต่อด้วย network ของ docker เอง ทั้งนี้ก็เพื่อประสิทธิภาพของการเชื่อมต่อที่ดีที่สุด โดยมีแผนภาพการเชื่อมต่อตามตัวอย่างภาพด้านล่าง



หลังจากที่เราได้เห็นภาพรวมของระบบกันแล้ว ขั้นตอนต่อไปมาลองสร้าง Container ของแต่ละส่วนกันดีกว่า โดยเริ่มจากส่วนของ Frontend ซึ่งจะเป็นส่วนที่เรียกใช้งาน Backend โดยมี docker-compose.yml ดังต่อไปนี้

ส่วนของ  Frontend 

ส่วนของ Backend


ส่วนของ MariaDB + Redis + phpmyadmin

วิธีการเริ่มต้นสำหรับมือใหม่ สำหรับคนที่ยังไม่มี Docker แนะนำให้ติดตั้ง Docker ให้เสร็จเสียก่อนซึ่งวิธีการติดตั้งนั้นก็ง่ายๆ เหมือนการติดตั้งโปรแกรมทั่วไป ทั้งนี้ผมไม่ขอข้ามไปถึงส่วนของการทำงานกับ docker-compose เลย

ก่อนอื่นให้สร้าง Folder ออกเป็น 3 Folder โดยแบ่งเป็น Frontend Backend และ Database เมื่อทำครบทั้งสามส่วนแล้วให้คัดลอก Source code ด้านบนไปไว้ตามส่วนที่ถูกต้อง โดยให้เปลี่ยนชื่อเป็น docker-compose.yml ทุก ๆ ส่วนโดยจะมีโครงสร้างดังต่อไปนี้

  • Frontend 
    • docker-compose.yml
  • Backend
    • docker-compose.yml
  • Database
    • store 
    • redis
    • docker-compose.yml

ในส่วนของ Database จะเห็นว่าผมได้สร้าง Folder เพิ่มเข้ามาสองตัวด้วยกันคือ store สำหรับเก็บข้อมูลของ mariaDB และ redis สำหรับเก็บข้อมูล Redis เพื่อแยกข้อมูลออกมาเป็นเฉพาะส่วนจากข้อมูลอื่น ๆ ป้องกันการเขียนข้อมูลที่ทับซ้อนกัน ช่วยให้เรา Backup ข้อมูลได้ง่ายขึ้น


ขั้นตอนการรัน docker-compose วิธีการนั้นง่ายมาก โดยเข้าไปที่ Terminal หรือ Console (หน้าจอดำ ๆ) ของ Path นั้นแล้วรันด้วยคำสั่ง docker-compose up -d โดยให้ run ในส่วนของ Database ขึ้นมาก่อน ตามด้วย Backend และท้ายสุดคือ Frontend สาเหตุให้รันขั้นตอนตามนี้เพราะว่า  ตัว Backend นั้นจำเป็นต้องมี database เสียก่อนถึงจะทำงานได้ เช่นเดียวกับตัว Frontend ต้องมี Backend ที่รันอยู่ก่อนมันถึงจะทำงานได้ หรือเรียกอีกอย่างว่ามัน depend กับ Container อื่น

วิธีการตรวจสอบว่า docker-compose นั้นทำงานได้สำเร็จหรือไม่ สามารถตรวจสอบด้วยคำสั่ง docker ps  หรือสังเกตุง่าย ๆ เวลาที่เรารันคำสั่ง docker-compose up -d หากไม่มีข้อผิดพลาดอะไรเกิดขึ้น หน้าจอจะแสดง success message เช่น create success หรือ  create network success เป็นต้น


มาถึงขั้นตอนนี้แล้ว ณ​ ตอนนี้เรายังไม่มีข้อมูลที่เป็น Soucecode ของ Laravel แต่สามารถติดตั้งด้วยวิธีการง่าย ๆ ผ่านทาง docker ด้วยขั้นตอนดังนี้

  1. เข้าไปที่ Folder ที่ Container นั้นอยู่เช่น Frontend 
  2. เปิดโปรแกรม Terminal หรือ Cmd หรือ Console ในเครื่องที่อยู่ Path นั้น ๆ ขึ้นมา
  3.  รันคำสั่ง docker exec -it frontend composer create laravel/laravel simple "5.4.*"
  4.  หลังจากที่รันเสร็จแล้วให้คัดลอกไฟล์ทั้งหมดออกมาจาก Folder simple มาไว้ข้างนอกสุดทุก ๆ ไฟล์ อย่าลืมไฟล์​ .env ด้วย
  5. ถ้าไม่พบไฟล์ .env ให้คัดลอกไฟล์มาจาก .env.example บางทีมันอาจ ซ่อนอยู่ให้เปิด file hidden ก่อน หรือไม่ก็ copy ด้วย command 
  6. ให้ทำแบบนี้กับ Container ของ Backend แบบเดียวกัน โดยเปลี่ยนคำสั่งจาก frontend เป็น backend 

เอาละพอมาถึงขั้นตอนนี้แล้ว เครื่องของเราก็พร้อมจะเชื่อมโยงกันด้วย docker network ภายในแล้วครับ มี Trick เล็กน้อย ๆ ที่อยากแชร์ให้คือ วิธีการเชื่อมโยงระหว่าง Container นั้นมีอยู่ 2 ส่วนด้วยกันคือ

  1. ส่วนของ external network ที่ docker-compose.yml ถ้าสังเกตุจุดนี้จะเห็นว่าผมได้ประกาศ external จาก Frontend ไปที่ Backend ด้วย network ที่ชื่อว่า backend_backendnetwork ซึ่งมีค่า external = true 
  2. ส่วนที่ 2 ในไฟล์ .env นั้นเราจะประกาศตัวแปร host ของ backend ด้วยชื่อของ Container name เช่น BACKEND_HOST=http://backend โดยไม่ต้องใส่ port ซึ่งในการเชื่อมโยงนั้นมันจะวิ่งอยู่ภายใน network ของ docker เอง ไม่ได้ใช้ network ของ Host นั่นเอง 
  3. ในตอนเรียกใช้งาน app ของ laravel ก็สามารถเรียนผ่าน helper function ชื่อ env('BACKEND_HOST') ได้เลย

สิ่งที่อยากเพิ่มเติม เราสามารถดัดแปลง Vhost หรือ map hosts หรือ แก้ไข php.ini ได้ด้วยตัวเองด้วยวิธีการ map volumn โดยการ point path หรือไฟล์ที่ต้องการออกมาที่ไฟล์ข้างนอก ทั้งนี้ผมจะนำไปเขียนในบทความลำดับถัดไปครับ 

ใน docker image ตัวนี้ผมได้ bundle composer + phpunit เข้าไปในตัวและทำงานบน Ubuntu เป็นคอร์หลักและ Apache สำหรับเป็น webserver ทำการเปิดโหมด Rewrite และ htaccess บนภาษา php5.6 ท่านใดสนใจก็นำไปใช้งานต่อได้เลยตามสะดวกครับ

ในบทความนี้ ต้องขออภัยที่ไม่ได้ทำตัวอย่างที่ครบถ้วน เป็นเพียงแนวทางสำหรับคนที่สนใจในการใช้งาน docker เบื้องต้นเท่านั้น หากติดปัญหาการใช้งานอย่างไรสามารถ อีเมล์มาสอบถามได้ที่ samarkchsngn@gmail.com

 ตัวอย่าง .env 
สมัคร ชัยสงวน
13/12/2018


Share on Google Plus

About maxcom

This is a short description in the author block about the author. You edit it by entering text in the "Biographical Info" field in the user admin panel.
    Blogger Comment
    Facebook Comment

0 ความคิดเห็น:

แสดงความคิดเห็น