1484 lines
No EOL
113 KiB
Markdown
1484 lines
No EOL
113 KiB
Markdown
# บทนำ
|
||
|
||
การพัฒนาและจัดการแอปพลิเคชันในยุคปัจจุบันได้มีการเปลี่ยนแปลงไปจากวิธีการเดิมๆ ด้วยการนำเทคโนโลยีใหม่ๆ มาใช้ ซึ่งทำให้กระบวนการพัฒนาและการดูแลระบบมีประสิทธิภาพมากขึ้น โดยเฉพาะการใช้ Container, Docker, Microservice, และ API Gateway ซึ่งแต่ละเทคโนโลยีก็มีบทบาทที่สำคัญในการสร้างแอปพลิเคชันที่สามารถปรับตัวได้ง่ายและสามารถขยายได้อย่างยืดหยุ่น
|
||
|
||
# Container คืออะไร?
|
||
|
||
Container คือ เทคโนโลยีที่ทำให้การรันแอปพลิเคชันเป็นไปอย่างมีประสิทธิภาพโดยการแยกแอปพลิเคชันและไลบรารีที่จำเป็นออกจากระบบปฏิบัติการหลัก (Host OS) ไว้ในสภาพแวดล้อมที่เป็นอิสระ Container จะบรรจุโค้ด ไลบรารี และการตั้งค่าทั้งหมดที่จำเป็นต้องใช้สำหรับการทำงาน ทำให้แอปพลิเคชันนั้นสามารถทำงานได้ไม่ว่าจะรันในสภาพแวดล้อมไหนก็ตาม เช่น บนเครื่องพัฒนาของโปรแกรมเมอร์ หรือบนเซิร์ฟเวอร์การผลิต
|
||
|
||
การใช้ Container ช่วยให้
|
||
|
||
- **ลดความขัดแย้ง** ในการพัฒนาระหว่างทีม เพราะทีมพัฒนาไม่ต้องกังวลว่าแอปพลิเคชันจะทำงานไม่ได้บนเครื่องอื่น
|
||
- **ปรับขนาดได้ง่าย** ด้วยการโคลน Container เพิ่มเมื่อมีความต้องการใช้งานสูง
|
||
- **การจัดการทรัพยากรมีประสิทธิภาพขึ้น** เนื่องจาก Container ใช้ทรัพยากรของระบบปฏิบัติการร่วมกัน ลดความซ้ำซ้อนของระบบที่ต้องจัดเตรียมทรัพยากรแยกเหมือนใน Virtual Machine
|
||
|
||
# เปรียบเทียบระหว่างเทคโนโลยี Container และ Virtual Machine
|
||
|
||
การเปรียบเทียบระหว่าง Container และ Virtual Machine (VM) เป็นหัวข้อสำคัญในการเลือกใช้สถาปัตยกรรมสำหรับการรันแอปพลิเคชัน เนื่องจากทั้งสองเทคโนโลยีนี้มีวิธีการทำงานและประโยชน์ที่แตกต่างกัน การทำความเข้าใจความแตกต่างระหว่าง Container และ VM จะช่วยให้ผู้พัฒนาและผู้ดูแลระบบสามารถเลือกใช้เทคโนโลยีที่เหมาะสมกับงานมากที่สุด
|
||
|
||
# ภาพรวมของ Container และ Virtual Machine
|
||
|
||
Virtual Machine (VM) คือ การจำลองระบบคอมพิวเตอร์ทั้งหมดที่รันอยู่บนฮาร์ดแวร์เสมือน โดย VM จะมีระบบปฏิบัติการที่แยกต่างหากจากระบบปฏิบัติการหลัก (Host OS) และทำงานได้อย่างอิสระในลักษณะของคอมพิวเตอร์เสมือน
|
||
Container คือ เทคโนโลยีที่แบ่งแยกแอปพลิเคชันและไลบรารีที่จำเป็นออกจากระบบปฏิบัติการหลักในรูปแบบที่เบากว่า VM โดย Container ใช้ระบบปฏิบัติการร่วมกับ Host OS และมีการแยกแอปพลิเคชันจากกันในระดับของโปรเซส
|
||
|
||
ต่อไปนี้คือการเปรียบเทียบความแตกต่างระหว่าง Container และ VM โดยพิจารณาในหลายๆ ด้าน
|
||
|
||
1. **สถาปัตยกรรม**
|
||
|
||
- **VM**: ทำงานบน Hypervisor (เช่น VMware, Hyper-V หรือ KVM) ซึ่งจัดการการสร้างและการรัน VM แต่ละตัว โดย VM แต่ละตัวจะมี Guest OS เป็นระบบปฏิบัติการที่รันภายในของตัวเอง พร้อมด้วย Kernel, แอปพลิเคชัน, และการตั้งค่าเฉพาะ ซึ่งหมายความว่า VM มีการแยกทรัพยากรอย่างสมบูรณ์
|
||
- **Container**: ทำงานบน Container Engine (เช่น Docker, Kubernetes) โดยไม่ต้องใช้ Hypervisor และใช้ Host OS ร่วมกันทุก Container แต่มีการแยกแอปพลิเคชันและไลบรารีในระดับโปรเซส ทำให้ Container มีขนาดเล็กกว่าและมีการทำงานที่เบากว่า VM
|
||
|
||
2. **ประสิทธิภาพ**
|
||
|
||
- **VM**: เนื่องจาก VM มี Guest OS ที่เป็นระบบปฏิบัติการเต็มรูปแบบและต้องใช้ Hypervisor ในการรัน VM การใช้ทรัพยากร เช่น CPU และหน่วยความจำจึงมีค่าใช้จ่ายสูงและทำให้ประสิทธิภาพการทำงานช้าลง โดยเฉพาะเมื่อต้องรันหลาย VM พร้อมกัน
|
||
- **Container**: Container ใช้ทรัพยากรร่วมกับ Host OS และมีขนาดเล็กกว่า VM จึงใช้หน่วยความจำและ CPU น้อยลง ซึ่งส่งผลให้ Container มีการทำงานที่รวดเร็วและมีประสิทธิภาพสูงกว่า VM
|
||
|
||
3. **การใช้งานทรัพยากร (Resource Efficiency)**
|
||
|
||
- **VM**: แต่ละ VM ต้องจัดสรรทรัพยากรแยกต่างหาก เช่น CPU, RAM และ Disk โดยการรัน VM หลายๆ ตัวพร้อมกันอาจส่งผลให้เกิดการใช้ทรัพยากรสูง ซึ่งไม่สามารถใช้งานทรัพยากรได้อย่างมีประสิทธิภาพเต็มที่เสมอไป
|
||
- **Container**: Container ใช้ทรัพยากรร่วมกับ Host OS ทำให้ประหยัดพื้นที่และหน่วยความจำมากกว่า การสร้างและรัน Container หลายๆ ตัวในเวลาเดียวกันยังใช้ทรัพยากรได้น้อยกว่า และสามารถปรับขนาดการใช้งานได้ง่าย
|
||
|
||
4. **การเริ่มต้นและการหยุดการทำงาน (Startup and Shutdown Time)**
|
||
|
||
- **VM**: เนื่องจากแต่ละ VM มี Guest OS เต็มรูปแบบ การเริ่มต้นและหยุด VM จะใช้เวลาค่อนข้างนาน ต้องผ่านกระบวนการบูทและการโหลด OS ซึ่งจะกินเวลาและทำให้การตอบสนองช้าลง
|
||
- **Container**: Container ใช้เวลาในการเริ่มต้นและหยุดทำงานเร็วกว่ามาก เนื่องจาก Container ไม่ต้องบูท OS ใหม่ แต่เป็นการเรียกโปรเซสในระบบปฏิบัติการหลักโดยตรง ทำให้เหมาะสมกับแอปพลิเคชันที่ต้องการความรวดเร็วและการตอบสนองทันที
|
||
|
||
5. **ขนาดของ Image และการจัดเก็บ**
|
||
|
||
- **VM**: VM มีขนาดใหญ่เนื่องจากมีการเก็บข้อมูลของ Guest OS, Kernel, และข้อมูลการติดตั้งต่างๆ ซึ่งส่งผลให้การย้ายหรือแชร์ VM Image ทำได้ยากและใช้เวลาในการส่งถ่ายข้อมูลมากขึ้น
|
||
- **Container**: Container Image มีขนาดเล็กกว่ามากเพราะไม่ต้องเก็บ OS ทั้งระบบ แต่จะบรรจุเฉพาะแอปพลิเคชันและไลบรารีที่จำเป็น การแชร์หรือย้าย Container Image จึงทำได้รวดเร็วและง่ายขึ้น
|
||
|
||
6. **ความสามารถในการพกพา (Portability)**
|
||
|
||
- **VM**: VM สามารถรันบนระบบที่รองรับ Hypervisor ใดๆ ที่สามารถโฮสต์ VM ได้ แต่ยังมีข้อจำกัดเนื่องจากต้องพิจารณาเวอร์ชันของ Hypervisor และการตั้งค่าที่ใช้
|
||
- **Container**: Container มีความสามารถในการพกพาสูงมาก เนื่องจากรันบน Container Engine ที่รองรับทุกแพลตฟอร์ม เช่น Docker ทำให้แอปพลิเคชันสามารถย้ายไปยังสภาพแวดล้อมที่ต่างกันได้ง่ายและทำงานได้เหมือนกันทุกที่
|
||
|
||
7. **การแยกความปลอดภัย (Isolation and Security)**
|
||
|
||
- **VM**: VM มีการแยกความปลอดภัยที่ดีกว่า เนื่องจาก Guest OS แต่ละตัวมี Kernel เป็นของตนเอง และทำงานในลักษณะอิสระ การโจมตีจาก VM หนึ่งไปยัง VM อื่นหรือ Host OS จึงทำได้ยากกว่า
|
||
- **Container**: Container มีการแยกความปลอดภัยในระดับโปรเซส ซึ่งไม่สมบูรณ์เท่า VM เนื่องจากทุก Container ใช้ Host OS ร่วมกัน ทำให้หากมีการเจาะระบบหรือโจมตีในระดับ Kernel ของ Host OS อาจส่งผลต่อ Container ทั้งหมดได้
|
||
|
||
# สรุปเปรียบเทียบ
|
||
|
||
| **คุณลักษณะ** | **Virtual Machine (VM)** | **Container** |
|
||
|-------------------------|-----------------------------------------------|--------------------------------------------|
|
||
| **การจำลองระบบ** | จำลองระบบปฏิบัติการทั้งหมด | ใช้เคอร์เนลร่วมกับโฮสต์ |
|
||
| **ระบบปฏิบัติการ** | แต่ละ VM มีระบบปฏิบัติการของตัวเอง | ใช้ระบบปฏิบัติการเดียวกับโฮสต์ |
|
||
| **ประสิทธิภาพ** | ใช้ทรัพยากรมากเพราะต้องรัน OS ทั้งระบบ | ใช้ทรัพยากรน้อยเพราะแชร์ OS กับโฮสต์ |
|
||
| **ขนาดไฟล์** | ขนาดใหญ่ (รวม OS และแอปพลิเคชัน) | ขนาดเล็ก (มีเพียงแอปพลิเคชันและไลบรารี) |
|
||
| **เวลาในการเริ่มต้น** | ช้ากว่า เนื่องจากต้องบูต OS | เร็วกว่า เพราะรันแค่กระบวนการของแอป |
|
||
| **การแยกการทำงาน** | แยกการทำงานได้เต็มรูปแบบ | แยกผ่าน namespace และ cgroups |
|
||
| **การพกพา (Portability)** | ขึ้นอยู่กับ Hypervisor และ OS | ง่ายต่อการพกพาผ่าน Docker หรือ Podman |
|
||
| **การใช้งาน** | เหมาะสำหรับแอปพลิเคชันขนาดใหญ่หรือหลาย OS | เหมาะสำหรับแอปพลิเคชันที่ปรับขยายได้ |
|
||
| **การจัดการ** | ซับซ้อนกว่า เพราะต้องจัดการทั้ง VM และ OS | ง่ายกว่า โดยใช้เครื่องมือจัดการ Container |
|
||
| **ทรัพยากรที่ใช้** | ใช้ CPU, RAM และ Storage มากกว่า | ใช้น้อยกว่าเพราะไม่มี OS เต็มรูปแบบ |
|
||
| **ตัวอย่างเครื่องมือ** | VMware, Hyper-V, VirtualBox | Docker, Kubernetes, Podman |
|
||
|
||
|
||
# Docker คืออะไร?
|
||
|
||
Docker เป็นแพลตฟอร์มที่ช่วยให้การพัฒนาและจัดการแอปพลิเคชันเป็นไปอย่างรวดเร็วและมีประสิทธิภาพ โดย Docker ใช้เทคโนโลยี Containerization เพื่อสร้างและรันแอปพลิเคชันในรูปแบบที่เรียกว่า Container ซึ่งเป็นหน่วยการทำงานที่มีความเป็นอิสระและมีทุกสิ่งที่จำเป็นสำหรับการทำงานของแอปพลิเคชัน เช่น โค้ด, ไลบรารี, ระบบไฟล์ และตัวแปรที่จำเป็น ทำให้สามารถพกพาและรันได้อย่างยืดหยุ่นในทุกระบบที่ติดตั้ง Docker ไว้
|
||
|
||
# แนวคิดเบื้องต้นเกี่ยวกับ Docker
|
||
|
||
Docker เป็นแพลตฟอร์มที่ช่วยให้การสร้าง รัน และจัดการแอปพลิเคชันในรูปแบบ Container เป็นไปอย่างสะดวกและมีประสิทธิภาพ ซึ่งแตกต่างจากการใช้งาน Virtual Machine ที่ต้องจำลองระบบปฏิบัติการแยกกัน Docker จะใช้เคอร์เนลของ Host OS ร่วมกันในระดับโปรเซส ดังนั้น Container จึงมีน้ำหนักเบาและใช้ทรัพยากรน้อยกว่า VM อย่างมาก ทำให้สามารถรันหลายๆ Container พร้อมกันได้บนฮาร์ดแวร์เดียว
|
||
|
||
# ส่วนประกอบสำคัญของ Docker
|
||
|
||
1. **Docker Engine**: เป็นซอฟต์แวร์หลักของ Docker ที่ทำหน้าที่รันและจัดการ Container ประกอบด้วยสองส่วนสำคัญ คือ
|
||
|
||
- Docker Daemon (dockerd): เป็นตัวควบคุมการทำงานของ Docker โดยทำหน้าที่ในการสร้าง จัดการ และรัน Container รวมถึงทำงานร่วมกับ Docker CLI
|
||
- Docker CLI: เป็นเครื่องมือบรรทัดคำสั่งที่ใช้ในการสื่อสารกับ Docker Daemon ทำให้เราสามารถสั่งการ เช่น การสร้างหรือรัน Container ได้
|
||
|
||
2. **Docker Image**: Docker Image เป็นต้นแบบของ Container ที่บรรจุโค้ด ไลบรารี และทรัพยากรที่จำเป็นสำหรับการทำงานของแอปพลิเคชัน โดยแต่ละ Image จะถูกสร้างจาก Dockerfile ซึ่งเป็นไฟล์ที่กำหนดขั้นตอนการสร้าง Image เช่น การติดตั้งแพ็กเกจต่างๆ การคัดลอกไฟล์ และการกำหนดค่าที่จำเป็น
|
||
|
||
3. **Docker Container**: Container คือ Instance ของ Docker Image ที่รันอยู่จริง ทำให้เราสามารถใช้งานแอปพลิเคชันหรือบริการต่างๆ ได้ในรูปแบบของ Container ซึ่งทำให้มีความยืดหยุ่นในการจัดการและสามารถรันแอปพลิเคชันหลายตัวในสภาพแวดล้อมที่แยกจากกันได้อย่างปลอดภัย
|
||
|
||
4. **Docker Compose**: เป็นเครื่องมือที่ใช้สำหรับจัดการหลายๆ Container ที่ต้องการทำงานร่วมกัน โดยสามารถกำหนดการตั้งค่าของแต่ละ Container ได้ในไฟล์เดียว (ไฟล์ docker-compose.yml) เช่น การเชื่อมต่อกับเครือข่าย การกำหนดค่าทรัพยากร และการตั้งค่าอื่นๆ เหมาะสำหรับการพัฒนาและทดสอบแอปพลิเคชันที่มีหลายองค์ประกอบ เช่น การรันฐานข้อมูล และเว็บเซิร์ฟเวอร์พร้อมกัน
|
||
|
||
5. **Docker Hub**: เป็นบริการคลังเก็บ Image ที่มีอยู่บนอินเทอร์เน็ต Docker Hub ช่วยให้ผู้ใช้สามารถดาวน์โหลด Image ที่มีอยู่แล้ว หรืออัปโหลด Image ของตัวเองได้ ซึ่งทำให้นักพัฒนาสามารถเข้าถึง Image ต่างๆ ได้อย่างสะดวกโดยไม่ต้องสร้าง Image ใหม่จากศูนย์
|
||
|
||
# การทำงานของ Docker
|
||
|
||
1. สร้าง Image จาก Dockerfile: นักพัฒนาสามารถสร้าง Docker Image โดยใช้ Dockerfile ซึ่งเป็นไฟล์ที่ประกอบไปด้วยคำสั่งและขั้นตอนการติดตั้งและการตั้งค่าต่างๆ เช่น การติดตั้งไลบรารี การคัดลอกไฟล์ และการกำหนดคำสั่งที่ต้องรันเมื่อเริ่มต้น Container
|
||
2. สร้างและรัน Container: เมื่อมี Image แล้ว สามารถสร้าง Container ได้โดยการใช้คำสั่ง เช่น docker run ซึ่งจะสร้าง Instance ของ Image ที่ทำงานอยู่จริง Container นี้จะทำงานเป็นแอปพลิเคชันที่แยกออกจากระบบปฏิบัติการหลัก แต่ยังสามารถสื่อสารกับ Host ได้ตามการตั้งค่า
|
||
3. การจัดการ Container ด้วย Docker Compose: หากแอปพลิเคชันต้องการหลาย Container ทำงานร่วมกัน เช่น มีทั้งฐานข้อมูลและ API นักพัฒนาสามารถใช้ Docker Compose เพื่อสร้างและจัดการ Container หลายๆ ตัวพร้อมกันได้ ทำให้การตั้งค่าทั้งหมดถูกรวมอยู่ในไฟล์เดียว และสามารถเรียกใช้ทุก Container ได้ด้วยคำสั่งเดียว (docker-compose up)
|
||
4. การจัดการและการปรับแต่ง Container: Docker รองรับการควบคุมการใช้ทรัพยากรของ Container เช่น CPU และ RAM ซึ่งช่วยให้การทำงานของแอปพลิเคชันมีประสิทธิภาพมากขึ้น โดยสามารถกำหนดการใช้ทรัพยากรให้เหมาะสมตามความต้องการ
|
||
|
||
# ข้อดีของ Docker
|
||
|
||
1. พกพาสะดวกและสภาพแวดล้อมคงที่: Docker ช่วยให้นักพัฒนาสามารถรันแอปพลิเคชันใน Container เดียวกันในทุกๆ สภาพแวดล้อม เช่น การพัฒนา การทดสอบ และการใช้งานจริง โดยที่ไม่ต้องปรับแต่งใหม่
|
||
2. การจัดการทรัพยากรที่มีประสิทธิภาพ: Container ใช้ทรัพยากรน้อยกว่า Virtual Machine เพราะไม่ต้องมี Guest OS ทำให้สามารถรันหลายๆ Container พร้อมกันบนเครื่องเดียวได้อย่างมีประสิทธิภาพ
|
||
3. การเริ่มต้นและหยุดใช้งานรวดเร็ว: Container สามารถเริ่มต้นและหยุดใช้งานได้รวดเร็ว เพราะไม่ต้องรันระบบปฏิบัติการใหม่ จึงเหมาะกับงานที่ต้องการปรับเปลี่ยนบ่อย เช่น DevOps
|
||
4. รองรับการทำงานแบบ Microservices: Docker เหมาะกับการทำงานในสถาปัตยกรรมแบบ Microservices ที่ต้องการแยกแอปพลิเคชันออกเป็นส่วนย่อยๆ แต่ละส่วนทำงานแยกจากกันและมีความเป็นอิสระ
|
||
5. การควบคุมและจัดการทรัพยากรง่าย: Docker ช่วยให้สามารถควบคุมการใช้ทรัพยากรของแต่ละ Container ได้อย่างละเอียด เช่น การกำหนดขีดจำกัดการใช้ CPU และ RAM เพื่อให้แอปพลิเคชันมีประสิทธิภาพที่ดีที่สุด
|
||
|
||
Docker เป็นเทคโนโลยีที่ช่วยให้การพัฒนาและการจัดการแอปพลิเคชันเป็นไปอย่างรวดเร็วและยืดหยุ่นด้วยการใช้ Container ซึ่งเป็นหน่วยการทำงานที่เบากว่า Virtual Machine ช่วยให้การพัฒนาแอปพลิเคชันหลายๆ ส่วนทำงานอย่างเป็นอิสระในรูปแบบ Microservices แต่การใช้งาน Docker ก็มีข้อจำกัดเช่นกัน ซึ่งควรพิจารณาตามความเหมาะสม
|
||
|
||
# Microservice คืออะไร?
|
||
|
||
Microservices คือสถาปัตยกรรมการออกแบบซอฟต์แวร์ที่เน้นการแบ่งแยกส่วนของระบบออกเป็นบริการย่อยๆ (Service) ที่เป็นอิสระต่อกัน โดยแต่ละบริการจะรับผิดชอบเฉพาะงานหรือฟังก์ชันหนึ่งๆ ของระบบ และสามารถสื่อสารกับบริการอื่นๆ ผ่านโปรโตคอล API (เช่น HTTP/REST, gRPC, หรือ Message Queue) ทำให้ระบบมีความยืดหยุ่นสูง สามารถพัฒนา ทดสอบ และปรับปรุงแต่ละส่วนแยกกันได้ รวมทั้งมีความสามารถในการสเกล (Scale) ตามความต้องการได้ดีกว่าการออกแบบระบบแบบ Monolithic ที่รวมทุกฟังก์ชันไว้ในแอปพลิเคชันเดียว
|
||
|
||
# แนวคิดและการทำงานของ Microservices
|
||
|
||
ในการออกแบบแบบ Microservices ระบบจะถูกแบ่งเป็นบริการย่อยๆ ซึ่งแต่ละบริการจะรับผิดชอบหน้าที่อย่างใดอย่างหนึ่ง เช่น การจัดการข้อมูลผู้ใช้ การประมวลผลข้อมูล การจัดการคำสั่งซื้อ เป็นต้น การแบ่งแยกแบบนี้ทำให้ทุกบริการมีความเป็นอิสระ สามารถปรับแต่งและพัฒนาแยกจากกันได้โดยไม่กระทบส่วนอื่นๆ ของระบบ ตัวอย่างเช่น:
|
||
|
||
- **User Service** – จัดการข้อมูลผู้ใช้และการยืนยันตัวตน
|
||
- **Product Service** – จัดการข้อมูลสินค้า
|
||
- **Order Service** – จัดการข้อมูลคำสั่งซื้อ
|
||
|
||
# องค์ประกอบสำคัญของ Microservices
|
||
|
||
1. **การแยกเป็นอิสระ (Decentralized Services)**: แต่ละบริการจะทำงานแยกจากกันโดยสมบูรณ์ สามารถพัฒนาและปรับปรุงโดยทีมงานที่ดูแลเฉพาะบริการนั้นๆ ได้โดยไม่ส่งผลกระทบต่อบริการอื่นๆ
|
||
|
||
2. **การสื่อสารผ่าน API**: Microservices สื่อสารระหว่างกันโดยใช้ API เช่น RESTful, gRPC, หรือใช้ Message Queue อย่าง RabbitMQ, Kafka เป็นต้น ทำให้บริการเหล่านี้สามารถแลกเปลี่ยนข้อมูลระหว่างกันได้แม้จะอยู่บนสถาปัตยกรรมหรือภาษาโปรแกรมที่ต่างกัน
|
||
|
||
3. **ฐานข้อมูลแยกส่วน (Decentralized Data Management)**: แต่ละบริการมีฐานข้อมูลเป็นของตัวเอง ทำให้สามารถใช้ฐานข้อมูลประเภทที่เหมาะสมกับงานของตน เช่น บริการจัดการผู้ใช้อาจใช้ฐานข้อมูล SQL ในขณะที่บริการวิเคราะห์ข้อมูลอาจใช้ NoSQL หรือฐานข้อมูลเชิงกราฟ (Graph Database)
|
||
|
||
4. **ความสามารถในการสเกล (Scalability)**: Microservices สามารถเพิ่มหรือลดจำนวน Instance ของบริการได้ตามความต้องการ เช่น หากบริการจัดการคำสั่งซื้อต้องรองรับปริมาณการใช้งานมาก สามารถเพิ่มจำนวนของ Order Service ได้โดยไม่ต้องเพิ่มบริการอื่นๆ
|
||
|
||
5. **การใช้เทคโนโลยีที่เหมาะสม (Polyglot Programming)**: ในสถาปัตยกรรม Microservices แต่ละบริการสามารถเลือกใช้ภาษาโปรแกรมและเทคโนโลยีที่เหมาะสมกับงานของตัวเอง เช่น ใช้ Python สำหรับการวิเคราะห์ข้อมูล ใช้ Java หรือ .NET สำหรับระบบหลัก เป็นต้น
|
||
|
||
6. **การติดตั้งและปรับปรุงง่าย (Continuous Deployment)**: แต่ละบริการสามารถปรับปรุง แก้ไข และติดตั้งใหม่ได้อิสระ โดยไม่จำเป็นต้องปล่อยซอฟต์แวร์ทั้งหมดใหม่ ซึ่งช่วยให้การปรับปรุงหรือแก้ไขบั๊กสามารถทำได้ทันที
|
||
|
||
# ข้อดีของ Microservices
|
||
|
||
1. **ความยืดหยุ่นในการพัฒนาและการทำงานเป็นทีม**: ทีมพัฒนาสามารถรับผิดชอบเฉพาะบริการที่ตนพัฒนาได้โดยตรง ทำให้แต่ละทีมสามารถเลือกเทคโนโลยีและการทำงานที่เหมาะสมได้ ช่วยให้ระบบพัฒนาได้เร็วขึ้นและมีคุณภาพสูงขึ้น
|
||
|
||
2. **ความสามารถในการสเกลสูง**: Microservices สามารถเพิ่มหรือลดจำนวนของบริการต่างๆ ตามการใช้งานจริงได้ การสเกลนี้ช่วยให้เรารองรับปริมาณการใช้งานที่เพิ่มขึ้นได้โดยไม่ต้องเพิ่มกำลังทุกส่วนของระบบ
|
||
|
||
3. **รองรับการเปลี่ยนแปลงและปรับปรุงได้ง่าย**: การอัปเดตหรือปรับปรุงสามารถทำได้เฉพาะในบางบริการ ไม่จำเป็นต้องปรับปรุงทั้งระบบ จึงช่วยลดความเสี่ยงและเวลาในการปรับปรุง
|
||
|
||
4. **ความทนทาน (Fault Tolerance)**: หากบริการหนึ่งล้มเหลว บริการอื่นๆ ที่เหลือจะยังทำงานต่อไปได้ ซึ่งช่วยลดผลกระทบจากปัญหาที่เกิดขึ้นกับบริการบางส่วน
|
||
|
||
# ข้อเสียของ Microservices
|
||
|
||
1. **ความซับซ้อนในการออกแบบและจัดการ**: เนื่องจาก Microservices ต้องมีการเชื่อมโยงบริการหลายๆ ตัว การออกแบบและจัดการสถาปัตยกรรมจึงซับซ้อนมากขึ้น ทำให้ต้องมีการวางแผนที่ดีในเรื่องของการจัดการบริการ การตรวจสอบ และการบำรุงรักษา
|
||
|
||
2. **ภาระในการสื่อสารระหว่างบริการ**: การสื่อสารระหว่างบริการต้องอาศัยโปรโตคอล เช่น HTTP, gRPC, หรือ Message Queue ซึ่งทำให้เกิดความหน่วง (Latency) และทำให้ต้องมีการจัดการกับการเกิดความล้มเหลวในการสื่อสาร
|
||
|
||
3. **ค่าใช้จ่ายในการบำรุงรักษาสูงขึ้น**: เนื่องจากแต่ละบริการมีฐานข้อมูลและทรัพยากรแยกกัน ทำให้มีค่าใช้จ่ายและความยุ่งยากในการบำรุงรักษามากขึ้น รวมถึงการจัดการด้านความปลอดภัยและการสำรองข้อมูลที่ซับซ้อน
|
||
|
||
4. **การทดสอบยากขึ้น**: การทดสอบ Microservices ต้องตรวจสอบการทำงานของแต่ละบริการและการทำงานร่วมกัน ซึ่งทำให้ต้องออกแบบการทดสอบที่ซับซ้อนมากขึ้น รวมถึงต้องใช้เครื่องมือเฉพาะสำหรับการทดสอบระบบที่มีหลายบริการ
|
||
|
||
# การใช้งาน Microservices ในโลกจริง
|
||
|
||
1. **การพัฒนาแอปพลิเคชันแบบ Cloud-native**: Microservices เป็นพื้นฐานของการพัฒนาแอปพลิเคชันแบบ Cloud-native ที่ใช้ Cloud Infrastructure ในการบริหารจัดการ เช่น การใช้ Kubernetes เพื่อจัดการบริการในรูปแบบ Container ซึ่งทำให้การปรับขนาดและการจัดการทรัพยากรเป็นไปอย่างมีประสิทธิภาพ
|
||
|
||
2. **การจัดการทราฟฟิกด้วย API Gateway**: ระบบที่ใช้ Microservices จะมีบริการหลายตัวทำงานร่วมกัน ดังนั้นการใช้ API Gateway ช่วยจัดการการเข้าถึงบริการทั้งหมดให้เป็นระบบระเบียบ และจัดการทราฟฟิกที่เข้าถึงบริการต่างๆ ได้อย่างมีประสิทธิภาพ
|
||
|
||
3. **การนำมาใช้ในองค์กรที่มีการเปลี่ยนแปลงบ่อย**: เนื่องจาก Microservices สามารถปรับปรุงเฉพาะส่วนได้ จึงเหมาะกับองค์กรที่ต้องการเปลี่ยนแปลงและปรับปรุงซอฟต์แวร์อย่างต่อเนื่องเพื่อรองรับตลาดหรือการพัฒนาใหม่ๆ
|
||
|
||
# การเปรียบเทียบ Microservices กับ Monolithic
|
||
|
||
| **คุณสมบัติ** | **Monolithic Architecture** | **Microservices Architecture** |
|
||
| --------------------------- | ----------------------------------------- | ----------------------------------------- |
|
||
| **การพัฒนา** | ทุกฟังก์ชันรวมอยู่ในแอปพลิเคชันเดียว | แต่ละฟังก์ชันแยกเป็นบริการย่อยๆ |
|
||
| **การสเกล** | สเกลทั้งแอปพลิเคชันพร้อมกัน | สเกลเฉพาะบริการที่ต้องการได้ |
|
||
| **ความซับซ้อน** | จัดการง่าย แต่ไม่ยืดหยุ่น | ซับซ้อนกว่าแต่มีความยืดหยุ่นสูง |
|
||
| **การปรับปรุง** | ต้องปรับปรุงทั้งแอปพลิเคชัน | ปรับปรุงเฉพาะบริการได้โดยไม่กระทบส่วนอื่น |
|
||
| **การพัฒนาแบบทีม** | ทีมต้องทำงานร่วมกันบนแอปพลิเคชันเดียว | ทีมสามารถพัฒนาและจัดการบริการแยกกัน |
|
||
| **การปรับใช้ (Deployment)** | ปรับใช้ทั้งหมดพร้อมกันเป็นแพ็กเกจเดียว | ปรับใช้ทีละบริการได้ตามความต้องการ |
|
||
| **การบำรุงรักษา** | ซับซ้อนเมื่อแอปพลิเคชันขยายขนาด | บำรุงรักษาแต่ละบริการได้แยกกัน |
|
||
| **ความทนทาน** | ปัญหาส่วนใดส่วนหนึ่งอาจส่งผลกระทบทั้งระบบ | หากบริการใดล้มเหลว บริการอื่นยังทำงานได้ |
|
||
| **การใช้เทคโนโลยี** | ใช้เทคโนโลยีเดียวทั้งระบบ | แต่ละบริการเลือกใช้เทคโนโลยีที่เหมาะสมได้ |
|
||
|
||
Microservices เป็นสถาปัตยกรรมที่ช่วยให้แอปพลิเคชันมีความยืดหยุ่นและสามารถปรับเปลี่ยนตามความต้องการขององค์กรได้ ทำให้แต่ละส่วนของระบบเป็นอิสระจากกัน ซึ่งเหมาะกับการพัฒนาแอปพลิเคชันที่มีการเปลี่ยนแปลงบ่อย หรือแอปพลิเคชันขนาดใหญ่ที่ต้องการประสิทธิภาพในการจัดการทรัพยากรและการสเกล
|
||
|
||
# API Gateway คืออะไร?
|
||
|
||
API Gateway คือส่วนกลางในการจัดการการสื่อสารระหว่างผู้ใช้ (Client) และบริการต่างๆ ภายในระบบที่ใช้สถาปัตยกรรมแบบ Microservices โดยมีหน้าที่รับคำขอจากผู้ใช้ ส่งต่อคำขอนั้นไปยังบริการต่างๆ ที่เกี่ยวข้อง และส่งผลลัพธ์กลับไปยังผู้ใช้ ซึ่งช่วยให้การสื่อสารภายในระบบเป็นไปอย่างมีประสิทธิภาพและง่ายต่อการจัดการ นอกจากนี้ API Gateway ยังมีฟังก์ชันในการจัดการการควบคุมการเข้าถึง (Access Control), การรักษาความปลอดภัย (Security), การจัดการการสเกล (Load Balancing) และการแคชข้อมูล (Caching) ทำให้เป็นส่วนสำคัญของระบบ Microservices ที่มีการจัดการหลายบริการ
|
||
|
||
# หน้าที่และการทำงานของ API Gateway
|
||
|
||
1. การควบคุมเส้นทาง (Routing): API Gateway ทำหน้าที่จัดการเส้นทางของคำขอที่เข้ามา โดยจะแยกแยะและส่งคำขอนั้นไปยังบริการที่เกี่ยวข้อง เช่น หากผู้ใช้ขอข้อมูลผู้ใช้งาน API Gateway จะส่งคำขอนั้นไปยัง User Service เป็นต้น
|
||
|
||
2. การแปลงข้อมูล (Transformation): ในบางครั้ง คำขอและการตอบกลับจำเป็นต้องมีการแปลงข้อมูลหรือจัดรูปแบบให้ตรงกับความต้องการของผู้ใช้ เช่น การแปลงข้อมูลจาก XML เป็น JSON เพื่อความสะดวกในการใช้งาน
|
||
|
||
3. การควบคุมการเข้าถึง (Access Control): API Gateway ทำหน้าที่ตรวจสอบสิทธิ์และการรับรองตัวตน (Authentication & Authorization) ของผู้ใช้ เช่น ตรวจสอบว่าเป็นผู้ใช้ที่ได้รับอนุญาตหรือไม่ก่อนส่งคำขอไปยังบริการต่างๆ ทำให้ระบบมีความปลอดภัยมากขึ้น
|
||
|
||
4. การรักษาความปลอดภัย (Security): API Gateway สามารถจัดการการป้องกันภัยคุกคามต่างๆ เช่น การป้องกันการโจมตีแบบ DDoS, การใช้ HTTPS เพื่อลดความเสี่ยงในการแอบดักข้อมูลระหว่างการสื่อสาร และการจำกัดอัตราการเรียกใช้งาน (Rate Limiting) เพื่อป้องกันการใช้งานที่มากเกินไป
|
||
|
||
5. การจัดการแคช (Caching): API Gateway มีการเก็บข้อมูลที่ถูกเรียกใช้บ่อยในหน่วยความจำ เพื่อเพิ่มประสิทธิภาพในการให้บริการ โดยไม่ต้องส่งคำขอไปยังบริการต้นทางทุกครั้ง ช่วยลดภาระงานของบริการต่างๆ
|
||
|
||
6. การควบคุมการสเกล (Load Balancing): API Gateway ช่วยกระจายคำขอที่เข้ามายังเซิร์ฟเวอร์หรือบริการต่างๆ เพื่อให้โหลดการทำงานมีความสมดุลและช่วยให้ระบบรองรับปริมาณการใช้งานที่สูงขึ้นได้อย่างมีประสิทธิภาพ
|
||
|
||
7. การตรวจสอบและวิเคราะห์ (Monitoring & Analytics): API Gateway สามารถรวบรวมข้อมูลการใช้งาน เช่น จำนวนคำขอ, ระยะเวลาการตอบกลับ, และสถิติการใช้งาน ซึ่งข้อมูลเหล่านี้สามารถนำไปวิเคราะห์เพื่อปรับปรุงบริการและแก้ไขปัญหาที่อาจเกิดขึ้นได้
|
||
|
||
# ข้อดีของการใช้ API Gateway
|
||
|
||
1. เพิ่มความปลอดภัยให้กับระบบ: API Gateway ช่วยให้สามารถรวมการจัดการด้านความปลอดภัยไว้ในจุดเดียว เช่น การจัดการการตรวจสอบสิทธิ์ (Authentication), การกำหนดนโยบายการเข้าถึง (Authorization Policy) ช่วยลดความเสี่ยงจากภัยคุกคาม
|
||
|
||
2. จัดการการสื่อสารที่ซับซ้อนได้ง่ายขึ้น: API Gateway ทำหน้าที่เป็นศูนย์กลางการสื่อสารกับบริการย่อย ทำให้การจัดการคำขอและการกำหนดเส้นทาง (Routing) เป็นไปอย่างง่ายและมีระเบียบ
|
||
|
||
3. เพิ่มประสิทธิภาพด้วยการแคช: คำขอบางคำขอ เช่น ข้อมูลที่มีการเปลี่ยนแปลงน้อย สามารถแคชไว้ใน API Gateway เพื่อลดการเรียกไปยังบริการต้นทาง ทำให้ระบบเร็วขึ้น
|
||
|
||
4. รองรับการสเกลที่ดีขึ้น: API Gateway ช่วยกระจายโหลดไปยังบริการต่างๆ และช่วยลดภาระการประมวลผลในระบบ ลดความเสี่ยงที่จะเกิดปัญหาโหลดเกินในบางบริการ
|
||
|
||
5. รวมการตรวจสอบการใช้งานไว้ในจุดเดียว: ช่วยให้นักพัฒนาสามารถตรวจสอบการใช้งานระบบแบบรวมศูนย์ ซึ่งช่วยในการตรวจหาปัญหาได้รวดเร็ว รวมถึงการบันทึกข้อมูลการใช้งานที่ช่วยวิเคราะห์และปรับปรุงบริการได้
|
||
|
||
# ข้อเสียของการใช้ API Gateway
|
||
|
||
1. เป็น Single Point of Failure: หาก API Gateway เกิดปัญหา ระบบทั้งหมดอาจไม่สามารถทำงานได้ ดังนั้นจึงต้องมีการวางแผนการทำงานแบบสำรอง (Redundancy) หรือการกระจายการใช้งานเพื่อป้องกันปัญหา
|
||
|
||
2. เพิ่มความซับซ้อนของระบบ: การเพิ่ม API Gateway จะทำให้ระบบมีโครงสร้างซับซ้อนมากขึ้น โดยเฉพาะเมื่อมีการใช้งานร่วมกับหลายบริการและมีการกำหนดนโยบายต่างๆ มากมาย
|
||
|
||
3. เกิดความล่าช้าเพิ่มขึ้น (Latency): การที่คำขอทั้งหมดต้องผ่าน API Gateway ก่อนที่จะไปยังบริการปลายทาง อาจทำให้เกิดความล่าช้าในระบบโดยเฉพาะหากมีการแปลงข้อมูลหรือแคชที่ซับซ้อน
|
||
|
||
# การใช้งาน API Gateway ในโลกจริง
|
||
|
||
- การจัดการการเข้าถึงหลายบริการในระบบ Microservices: API Gateway ช่วยให้ผู้ใช้สามารถเข้าถึงบริการต่างๆ ของระบบที่มีโครงสร้างแบบ Microservices ได้ผ่านจุดเดียว เช่น การเข้าสู่ระบบผู้ใช้ ที่ API Gateway สามารถรับคำขอและส่งต่อไปยังบริการย่อย เช่น บริการตรวจสอบตัวตน บริการจัดการข้อมูลผู้ใช้ เป็นต้น
|
||
|
||
- การจัดการแอปพลิเคชันที่รองรับผู้ใช้หลายประเภท: เช่น ระบบอีคอมเมิร์ซที่ต้องรองรับทั้งผู้ใช้ทั่วไปและแอปพลิเคชันที่เป็น Partner สามารถกำหนดสิทธิ์และการเข้าถึงได้แตกต่างกันผ่าน API Gateway เพื่อควบคุมการเข้าถึง
|
||
|
||
- การจัดการทราฟฟิกในระบบที่มีปริมาณการเข้าถึงสูง: เช่น บริการที่ใช้ในแอปพลิเคชันแบบ SaaS (Software as a Service) API Gateway จะช่วยกระจายโหลดและควบคุมปริมาณการเข้าถึง
|
||
|
||
API Gateway เป็นส่วนสำคัญในระบบ Microservices ที่ช่วยจัดการการสื่อสารระหว่างผู้ใช้และบริการต่างๆ ภายในระบบ ทำให้การจัดการการเข้าถึงมีความปลอดภัย และระบบมีความเป็นระเบียบและสามารถปรับแต่งตามความต้องการได้ เช่น การควบคุมการเข้าถึง การแปลงข้อมูล การจัดการการแคชและการกระจายโหลด การใช้ API Gateway ช่วยให้การจัดการระบบขนาดใหญ่ที่มีหลายบริการเป็นไปอย่างมีประสิทธิภาพ
|
||
|
||
# สุปการนำเอาเทคโนโลยี Container, Docker, Microservices และ API Gateway มาใช้ในการพัฒนาระบบ
|
||
|
||
การใช้ Docker Containers, Microservices, และ API Gateway เป็นแนวทางการพัฒนาแอปพลิเคชันในยุคปัจจุบันเป็นแนวทางที่ได้รับความนิยมสูงมาก เนื่องจากมันช่วยปรับปรุงในหลายๆ ด้าน ทั้งในเรื่อง ประสิทธิภาพ, ความทันสมัย, และ ความปลอดภัย นี่คือการสรุปข้อดีของการใช้แนวทางเหล่านี้:
|
||
|
||
1. **ประสิทธิภาพ (Performance)**
|
||
|
||
- Docker Containers: การใช้ Docker ช่วยให้การพัฒนาและการดำเนินงานสามารถแยกกันได้ชัดเจนระหว่างบริการต่างๆ ทำให้สามารถประมวลผลแยกกันได้ดี การจัดการกับ resource และการขยายขนาด (scaling) ทำได้ง่ายและมีประสิทธิภาพสูงขึ้น เนื่องจาก containers สามารถทำงานได้บนเครื่องหลายเครื่องหรือหลายสภาพแวดล้อมได้โดยไม่ต้องแก้ไขโค้ด
|
||
- Microservices: การแบ่งแอปพลิเคชันออกเป็น Microservices ช่วยให้สามารถพัฒนาและปรับปรุงบริการแต่ละตัวได้อย่างรวดเร็วและมีประสิทธิภาพ ไม่ต้องปรับแก้ระบบทั้งหมด ระบบสามารถขยายได้ตามความต้องการ (elastic scaling) และรองรับการทำงานในหลายภูมิภาคหรือเซิร์ฟเวอร์
|
||
- API Gateway: ทำหน้าที่เป็นตัวกลางในการจัดการการเรียกใช้งานบริการต่างๆ ของ Microservices ช่วยลดภาระการจัดการการเชื่อมต่อที่ซับซ้อนระหว่าง microservices และช่วยเพิ่มความเร็วในการประมวลผลการเรียก API รวมถึงสามารถปรับแต่งการใช้ API ได้อย่างมีประสิทธิภาพ
|
||
|
||
2. **ความทันสมัย (Modernization)**
|
||
|
||
- การใช้ Docker และ Microservices ช่วยให้การพัฒนาระบบสามารถปรับตัวได้อย่างรวดเร็วตามเทคโนโลยีใหม่ๆ ได้ง่าย เพราะแต่ละ Microservice สามารถใช้เทคโนโลยีหรือเวอร์ชันที่ต่างกันได้ตามความเหมาะสม
|
||
- API Gateway ทำให้การเชื่อมต่อระหว่างบริการต่างๆ สามารถทำได้ในลักษณะของ "Single Entry Point" ช่วยเพิ่มความสะดวกในการจัดการและบำรุงรักษาระบบ
|
||
- แนวทางเหล่านี้ช่วยให้นักพัฒนาสามารถใช้ CI/CD (Continuous Integration / Continuous Deployment) เพื่ออัพเดทระบบได้บ่อยและสะดวก ทำให้สามารถนำเทคโนโลยีและฟีเจอร์ใหม่ๆ มาใช้งานได้อย่างรวดเร็ว
|
||
|
||
3. **ความปลอดภัย (Security)**
|
||
|
||
- Docker: Docker ช่วยแยกแต่ละบริการใน containers ทำให้การจัดการสิทธิ์การเข้าถึงหรือการใช้งานระบบสามารถทำได้ดีขึ้น ถ้าเกิดการเจาะระบบใน container หนึ่งก็ไม่สามารถเข้าถึงข้อมูลใน container อื่นได้ทันที
|
||
- Microservices: การแยกบริการออกเป็น Microservices ช่วยจำกัดการเข้าถึงข้อมูลและลดการเสี่ยงจากการโจมตีแบบ "single point of failure" เนื่องจากระบบแยกออกเป็นส่วนๆ ที่สามารถควบคุมการเข้าถึงได้อย่างชัดเจน
|
||
- API Gateway: API Gateway ทำหน้าที่เป็นตัวกลางในการรับส่งข้อมูลและการเข้าถึง APIs ซึ่งช่วยให้สามารถควบคุมการเข้าถึงด้วยการใช้งานเช่นการพิสูจน์ตัวตน (Authentication), การอนุญาต (Authorization), การป้องกันการโจมตี (Rate Limiting), และการตรวจสอบความปลอดภัย (Security Auditing)
|
||
|
||
การใช้ Docker Containers, Microservices, และ API Gateway ไม่เพียงแต่ช่วยเพิ่ม ประสิทธิภาพ ในการพัฒนาและการขยายระบบ แต่ยังช่วยในการทำให้ระบบมีความ ทันสมัย และสามารถรองรับเทคโนโลยีใหม่ๆ ได้อย่างง่ายดาย พร้อมทั้งสามารถรักษาความ ปลอดภัย ของระบบได้อย่างมีประสิทธิภาพ
|
||
|
||
การนำเทคโนโลยีเหล่านี้มาปรับใช้ในการพัฒนาระบบทำให้การสร้างแอปพลิเคชันที่มีความยืดหยุ่นสูง, ปรับขยายได้ตามต้องการ และตอบสนองต่อความปลอดภัยในยุคดิจิทัลได้เป็นอย่างดี
|
||
|
||
# ขั้นตอนการติดตั้งระบบ
|
||
|
||
ผู้อ่านจำเป็นต้องมีความรู้และเข้าใจคำสั่ง และระบบไฟล์ของ Linux เป็นอย่างดีมาก่อน เอกสารจะแสดงวิธีการติดตั้งระบบของ BMA HRMS บนเทคโนโลยีคอนเทนเนอร์ มีการปูพื้นคำสั่งพื้นฐานของ Docker ที่จำเป็นให้ ลักษณะการติดตั้งและใช้งานจะอยู่ในรูปแบบเดียวกัน ทำให้สามารถจัดการบริการเพิ่มเติมที่จะเกิดขึ้นอนาคตได้ นอกจากการใช้งานผ่านคำสั่งแล้วสามารถใช้ Portainer จัดการผ่าน Web UI ได้ การติดตั้งจะอยู่ในเอกสารนี้
|
||
|
||

|
||
|
||
## Linux VM
|
||
เครื่องโฮสเป็น debian 12 แบบมาตรฐาน ตั้งค่า locale และ Time Zone ให้เหมาะสำหรับประเทศไทย
|
||
```
|
||
sudo dpkg-reconfigure locales
|
||
sudo timedatectl set-timezone Asia/Bangkok
|
||
date
|
||
```
|
||
|
||

|
||
|
||

|
||
|
||
|
||
## ติดตั้ง Docker
|
||
|
||
Docker คอนเทนเนอร์สามารถเรียนรู้ ตั้งค่า ดูแล รักษาได้ง่ายและรวดเร็ว รองรับการขยายตัว สามารถเพิ่มคลัสเตอร์ได้ง่าย และสามารถปรับเปลี่ยนเป็น Kubernates ได้ในอนาคต
|
||
สำหรับเอกสารนี้จะเป็นการติดตั้ง Docker บน debian 12 สำหรับบนวินโดว์(เพื่อการทดสอบเท่านั้น)ให้ติดตั้ง docker บน WSL2
|
||
การติดตั้งโดยละเอียดดูได้จาก [คู่มือในเวปหลักของ Docker](https://docs.docker.com/engine/install/debian/) ตัวอย่างด้านล่างเป็นวิธีการติดตั้งแบบย่อผ่าน
|
||
[convenience script](https://docs.docker.com/engine/install/debian/#install-using-the-convenience-script) ทำตามวิธีการนี้
|
||
|
||
```
|
||
sudo apt install curl
|
||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||
sudo sh get-docker.sh
|
||
sudo usermod -aG docker user_name
|
||
sudo usermod -aG sudo user_name
|
||
```
|
||
|
||
แทน user_name ด้วยยูสเซอร์ที่ใช้ดูแลระบบ ในตัวอย่างจะให้อยู่ในกรุป docker และ sudo เพื่อให้มีสิทธิ์ในจัดการ service และไฟล์ที่เกิดจาก docker
|
||
|
||
## คำสั่ง Docker พื้นฐาน
|
||
|
||
คำสั่งพื้นฐานของ docker ที่ใช้
|
||
|
||
```sh
|
||
docker ps # ดูรายการคอนเทนเนอร์ที่รันอยู่ในระบบ
|
||
docker images # ดูรายการอิมเมจที่มีในระบบ
|
||
docker pull [image_name:tag] # ดึงอิมเมจมาในระบบ
|
||
docker network ls # แสดงรายการเน็ตเวิร์กของ docker
|
||
docker network create [network_name] # สร้างเน็ตเวิร์กของ docker
|
||
```
|
||
|
||
# การใช้งานไฟล์ Docker Compose
|
||
## Docker Compose File คืออะไร?
|
||
**Docker Compose File** เป็นไฟล์ที่มีรูปแบบเป็น YAML (มักมีชื่อไฟล์ docker-compose.yml หรือ compose.yaml) ซึ่งใช้สำหรับการกำหนดค่าและจัดการการทำงานของ **หลายคอนเทนเนอร์** ในโปรเจกต์เดียวกัน ช่วยให้นักพัฒนาสามารถกำหนดบริการต่างๆ ที่คอนเทนเนอร์จะต้องรัน เช่น ฐานข้อมูล เว็บเซิร์ฟเวอร์ และบริการอื่นๆ ได้ในที่เดียว
|
||
|
||
## Docker Compose File มีไว้ทำไม?
|
||
1. จัดการบริการหลายตัวพร้อมกัน
|
||
เมื่อโปรเจกต์มีหลายคอนเทนเนอร์ เช่น ฐานข้อมูล (MySQL), แอปพลิเคชัน (Node.js), และเครื่องมืออื่นๆ Docker Compose จะช่วยจัดการทุกอย่างในไฟล์เดียว
|
||
|
||
2. ลดความซับซ้อนของคำสั่ง
|
||
แทนที่จะต้องใช้คำสั่ง docker run หลายครั้งเพื่อรันคอนเทนเนอร์ต่างๆ สามารถใช้คำสั่งเดียว (docker-compose up) เพื่อรันทุกบริการพร้อมกัน
|
||
|
||
3. กำหนดค่าที่ซับซ้อน
|
||
สามารถกำหนดค่าเครือข่าย, การเชื่อมโยงคอนเทนเนอร์, พอร์ต, Volume, และ Environment Variable ได้ในไฟล์เดียว
|
||
|
||
4. ทำให้การพกพาและย้ายโปรเจกต์ง่ายขึ้น
|
||
แชร์ docker-compose.yml ไฟล์ให้ผู้อื่นเพื่อสร้างสภาพแวดล้อมที่เหมือนกันได้อย่างง่ายดาย
|
||
|
||
## Docker Compose File ใช้งานเพื่ออะไร?
|
||
1. การตั้งค่าบริการในระบบที่ซับซ้อน
|
||
เช่น การตั้งค่าแอปพลิเคชันที่ต้องใช้ฐานข้อมูล Redis และ RabbitMQ ร่วมกัน
|
||
|
||
2. การพัฒนาและทดสอบในเครื่อง
|
||
สร้างสภาพแวดล้อมที่เหมือนกับ Production บนเครื่องนักพัฒนา
|
||
|
||
3. การจัดการ Volume และ Network
|
||
กำหนด Volume สำหรับเก็บข้อมูล และ Network เพื่อให้บริการต่างๆ สื่อสารกัน
|
||
|
||
4. รองรับการสเกลระบบ
|
||
สามารถเพิ่มจำนวนคอนเทนเนอร์ในแต่ละบริการได้ง่ายโดยใช้ docker-compose up --scale
|
||
|
||
## ตัวอย่างของไฟล์ docker-compose.yaml
|
||
เป็นตัวอย่างแบบง่ายเพื่อใช้งาน เซอร์วิส web ใช้อิมเมจโปรแกรม nginx เนื้อหาไฟล์ในโฟลเดอร์ ./html จะไปปรากฏบนคอนเทนเนอร์ที่ /usr/share/nginx/html เปิดพอร์ต 9082 บนเครื่องโฮส ถ้าไม่สั่งหยุดการทำงาน nginx จะเริ่มตัวเองเองถ้าโฮสเปิดขึ้นเครื่องใหม่ ทำงานในเน็ตเวิร์ก hrms ที่สร้างจากภายนอก
|
||
|
||
การใช้งานใช้เว็บบราวเซอร์ไปที่ http://IP:9082
|
||
|
||
```yaml
|
||
services:
|
||
web:
|
||
image: nginx
|
||
volumes:
|
||
- ./html:/usr/share/nginx/html:ro
|
||
ports:
|
||
- "9082:80"
|
||
restart: unless-stopped
|
||
networks:
|
||
hrms:
|
||
networks:
|
||
hrms:
|
||
external: true
|
||
```
|
||
|
||
## การใช้งานคำสั่ง docker compose
|
||
|
||
docker compose จะรันคอนเทนเนอร์ของ docker หลายๆตัวพร้อมกันได้ โดยดูการตั้งค่าจากไฟล์ compose.yaml หรือ docker-compose.yaml
|
||
ที่อยู่ในโฟลเดอร์ที่เรียกคำสั่ง ในการทำงานทั่วไปเพื่อง่ายต่อการใช้งานจะใช้ docker compose เป็นหลัก ซึ่งจะมีผลเฉพาะ service ที่เขียนไว้ในไฟล์ compose
|
||
|
||
คำสั่ง docker compose พื้นฐาน (ต้องมีไฟล์ compose.yaml หรือ docker-compose.yaml ในโฟลเดอร์ที่เรียกคำสั่ง)
|
||
|
||
```sh
|
||
docker compose ps # ดูรายการ service ที่ทำงานอยู่
|
||
docker compose up -d # เรียกทุก service ขึ้นมาทำงาน
|
||
docker compose up -d [service_name] # เรียกเฉพาะ service ที่ต้องการขึ้นมาทำงาน
|
||
|
||
docker compose down # หยุดและลบบริการทั้งหมด
|
||
|
||
docker compose logs # ดู Log ของบริการทั้งหมด
|
||
|
||
docker compose logs -f [service_name] # ดู Log เฉพาะ service ที่ต้องการ
|
||
```
|
||
|
||
โฟลเดอร์ที่ใช้เริ่มต้นสร้างโปรแกรม บริการต่างๆในหัวข้อต่อๆไปจะสร้างภายใต้ ~/docker/hrms และใช้เน็ตเวิร์กชื่อ hrms ในการสื่อสารระหว่างกัน ทำให้สามารถเรียกใช้ชื่อ service แทน IP Address ได้เหมือนมี DNS ภายใน
|
||
|
||
```sh
|
||
docker network create hrms # สร้างเน็ตเวิร์ก hrms
|
||
mkdir -p ~/docker/hrms # สร้างโฟลเดอร์
|
||
cd ~/docker/hrms # เข้าไปในโฟลเดอร์
|
||
```
|
||
|
||
ทดสอบการทำงานของ docker ให้สร้างโฟลเดอร์ simple-web มีไฟล์ compose.yaml สร้างโฟลเดอร์ html แล้วสร้างไฟล์ html/index.html ในโฟลเดอร์นั้นพร้อมเนื้อหาเรียกคำสั่ง docker compose up -d
|
||
|
||
```sh
|
||
mkdir -p simple-web/html
|
||
cd simple-web
|
||
nano compose.yaml # สร้างไฟล์ compose
|
||
nano html/index.html # สร้างหน้าเวปสำหรับทดสอบ
|
||
```
|
||
|
||
## Services
|
||
|
||
การออกแบบใช้สถาปัตยกรรม Microservice จะประกอบจากหลาย Service เพื่อความเป็นระเบียบจะแบ่งไว้สามโฟลเดอร์ apisix(API Gateway), bmahrms-service(3rd Party service), bmahrms(HRMS services)
|
||
|
||
```sh
|
||
mkdir -P apisix
|
||
mkdir -p bmahrms-service/{edm_config,elasticsearch_config,init_mysql,keycloak_config,report-server-templates}
|
||
mkdir -p bmahrms-service/report-server-templates/{docx,xlsx}
|
||
mkdir -p bmahrms
|
||
```
|
||
|
||
### APISIX (API Gateway)
|
||
|
||
ทำหน้าที่จัดการ https, limit, security, load balance,reverse proxy, และ route ใน Microservice ก่อนใช้งานให้ตั้งค่าโดเมนกับ Public IP ให้เรียบร้อยแล้ว Forward Port 80/443 มาที่เครื่องนี้
|
||
การตั้งค่าต่างๆจะทำผ่าน Web API ในตัวอย่างจะใช้ curl
|
||
|
||
```sh
|
||
mkdir -p apisix/apisix_conf/
|
||
nano apisix/apisix_conf/config.yaml # configuration
|
||
nano apisix/compose.yaml # compose file
|
||
docker compose up -d
|
||
```
|
||
|
||
apisix/apisix_conf/config.yaml เป็นไฟล์คอนฟิกของ APISIX แก้ค่า put_admin_api_key_here, allow_admin ให้เหมาะสม
|
||
|
||
```yaml
|
||
apisix:
|
||
node_listen: 9080 # APISIX listening port
|
||
enable_ipv6: false
|
||
enable_control: true
|
||
control:
|
||
ip: "0.0.0.0"
|
||
port: 9092
|
||
deployment:
|
||
admin:
|
||
allow_admin: # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow
|
||
- 0.0.0.0/0 # We need to restrict ip access rules for security. 0.0.0.0/0 is for test.
|
||
admin_key:
|
||
- name: "admin"
|
||
key: put_admin_api_key_here
|
||
role: admin # admin: manage all configuration data
|
||
etcd:
|
||
host: # it's possible to define multiple etcd hosts addresses of the same etcd cluster.
|
||
- "http://etcd:2379" # multiple etcd address
|
||
prefix: "/apisix" # apisix configurations prefix
|
||
timeout: 30 # 30 seconds
|
||
plugin_attr:
|
||
prometheus:
|
||
export_addr:
|
||
ip: "0.0.0.0"
|
||
port: 9091
|
||
```
|
||
|
||
apisix/compose.yaml จะมีสอง service ตัว apisix จะเป็นโปรแกรมหลัก ส่วน etcd ฐานข้อมูลแบบกระจายตัว ใช้สำหรับเก็บการตั้งค่าของ apisix เน็ตเวิร์ก apisix จะเป็นการสื่อสารระหว่างสองเซอร์วิสเท่านั้น ส่วนเน็ตเวิร์ก hrms จะเป็นการสื่อสารระหว่าง apisix กับโปรแกรมต่างๆของระบบ
|
||
|
||
```yaml
|
||
services:
|
||
apisix:
|
||
image: apache/apisix:${APISIX_IMAGE_TAG:-3.9.0-debian}
|
||
restart: always
|
||
environment:
|
||
- TZ=Asia/Bangkok
|
||
volumes:
|
||
- ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
|
||
depends_on:
|
||
- etcd
|
||
ports:
|
||
- "9180:9180/tcp"
|
||
- "80:9080/tcp"
|
||
- "9091:9091/tcp"
|
||
- "443:9443/tcp"
|
||
- "9092:9092/tcp"
|
||
networks:
|
||
hrms:
|
||
apisix:
|
||
etcd:
|
||
image: bitnami/etcd:3.5.11
|
||
restart: always
|
||
volumes:
|
||
- etcd_data:/bitnami/etcd
|
||
environment:
|
||
ETCD_ENABLE_V2: "true"
|
||
ALLOW_NONE_AUTHENTICATION: "yes"
|
||
ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379"
|
||
ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
|
||
TZ: "Asia/Bangkok"
|
||
ports:
|
||
- "2379:2379/tcp"
|
||
networks:
|
||
apisix:
|
||
networks:
|
||
hrms:
|
||
external: true
|
||
apisix:
|
||
driver: bridge
|
||
|
||
volumes:
|
||
etcd_data:
|
||
driver: local
|
||
```
|
||
|
||
วิธีการติดตั้ง certificate(HTTPS) เนื่องจากของ \*bangkok.go.th มี intermediate certificate
|
||
ให้นำ root CA รวมกับ intermediate เพื่อให้พร้อมใช้งาน การตั้งค่า APISIX จะทำผ่าน Web API ใช้ curl และ api-key ที่ตั้งไว้
|
||
|
||
```sh
|
||
# รวม intermediate เข้ากับ certificate หลัก
|
||
cat star_bangkok.go.th_2024.crt 'GeoTrust TLS RSA CA G1.crt' > star_bangkok.go.th_2024.ca-bundle
|
||
# ตั้งค่าใน APISIX
|
||
curl http://127.0.0.1:9180/apisix/admin/ssls/1 \
|
||
-H 'X-API-KEY: put_admin_api_key_here' -X PUT -d '
|
||
{
|
||
"cert" : "'"$(cat star_bangkok.go.th_2024.ca-bundle)"'",
|
||
"key": "'"$(cat star_bangkok.go.th_2024.key)"'",
|
||
"snis": ["*.bangkok.go.th"]
|
||
}'
|
||
```
|
||
|
||
ถ้ามีการเซ็ต route ผ่าน APISIX สามารถทดสอบ ผ่าน curl ได้ด้วยคำสั่งนี้(การเซ็ตค่าจะอยู่ในหัวข้ออื่น)
|
||
|
||
```sh
|
||
curl https://bma-hrms-id.bangkok.go.th -vvv
|
||
```
|
||
|
||
### 3rd Party Service (bmahrms-service)
|
||
|
||
โปรแกรมกลุ่มนี้ที่พัฒนาโดย 3rd Party หรือ Frappet ไม่ได้มีฟังก์ชั่นงานเจาะจงสำหรับ HRMS ถูกใช้โดยโปรแกรมของ HRMS(เช่นฐานข้อมูล,เวปเซิร์ฟเวอร์ ฯลฯ) จะแยกมาใส่โฟลเดอร์ bmahrms-service
|
||
การติดตั้งให้นำ compose.yaml และ คอนฟิกมาใส่โฟลเดอร์ bmahrms-service ให้เรียบร้อยก่อนใช้งาน สร้างโฟลเดอร์แต่ละ servie ทำดังนี้
|
||
|
||
- **Keycloak (bmahrms-postgres bmahrms-id)** เซิร์ฟเวอร์สำหรับจัดการยูสเซอร์และการ Authentication ในระบบ
|
||
- **MySQL (bmahrms-mysql)** เป็นฐานข้อมูลของระบบ
|
||
- **MiniO (bmahrms-s3)** เป็น Object Storage แบบเดียวกับ AWS s3 ใช้สำหรับเก็บไฟล์ มีประสิทธิ์ภาพสูงสามารถรับโหลดหนัก มีความปลอดภัยกว่าเก็บด้วยระบบไฟล์ทั่วไป สามารถขยายเพิ่มได้ในอนาคต ถูกใช้ในหลายระบบที่ต้องการเก็บไฟล์
|
||
- **Windmill** รันเวิร์กโฟลว์การทำงานอัตโนมัติจากสคริปต์ หลักๆใช้เพื่อรันตัวสำรองข้อมูล
|
||
- **Portainer (bmahrms-portainer)** ระบบจัดการ container มี UI ใช้งานง่าย สามารถใช้แทนคำสั่ง docker ได้
|
||
- **RabbitMQ (bmahrms-mq)** ระบบจัดคิวในการสือสารใน Microservice มีความน่าเชื่อถือสูง สามารถรับโหลดหนักๆในช่วงเวลาสั้นๆได้ โดยไม่ต้องเพิ่มทรัพยากรโดยไม่จำเป็น เช่นระบบการลงเวลา
|
||
- **Frappet Report Server (bmahrms-report-server)** ใช้สำหรับสร้างรายงานจากเอกสารต้นแบบ ออกแบบเองได้ในรูปของ ไฟล์ docx และ xlsx เอกสารที่สร้างสามารถส่งออกเป็น docx, xlsx, pdf ได้
|
||
- **Frappet EDM** ใช้สำหรับจัดการเอกสารที่ปลอดภัยรองรับโหลดจำนวนมากได้ จะมีระบบย่อยเบื้องหลังหลายตัว (bmahrms-edm,bmahrms-elasticsearch,bmahrms-kibana,bmahrms-mq)
|
||
|
||
docker/bmahrms-service/service.env
|
||
การตั้งค่าและรหัสผ่านของคอนเทนเนอร์ผ่านตัวแปรแวดล้อมทำได้สอบแบบ
|
||
- ทำแต่ละ services.service_name.environments ในไฟล์คอมโพส
|
||
- แยกออกมาเป็นไฟล์เพื่อใช้ร่วมกันหลาย Service ก็ได้ ในตัวอย่างนี้จะใช้ ไฟล์ service.env
|
||
ให้แก้ตัวแปรให้เหมาะสม KEYCLOAK_ADMIN_PASSWORD, KC_DB_PASSWORD, POSTGRES_PASSWORD, MINIO_ROOT_PASSWORD RABBITMQ_DEFAULT_PASS, MYSQL_ROOT_PASSWORD, MYSQL_PASSWORD
|
||
```
|
||
# Generic
|
||
TZ=Asia/Bangkok
|
||
# Keycloak
|
||
KEYCLOAK_ADMIN=admin
|
||
KEYCLOAK_ADMIN_PASSWORD=put_keycloak_admin_password_here
|
||
|
||
# Keycloak
|
||
KC_DB=postgres
|
||
#KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
|
||
KC_DB_URL_HOST=bmahrms-postgres
|
||
KC_DB_URL_DATABASE=keycloak
|
||
KC_DB_PASSWORD=put_keycloak_db_password_here
|
||
KC_DB_USERNAME=keycloak
|
||
KC_DB_SCHEMA=public
|
||
|
||
# PostgreSQL (keycloak)
|
||
POSTGRES_DB=keycloak
|
||
POSTGRES_USER=keycloak
|
||
POSTGRES_PASSWORD=put_keycloak_db_password_here
|
||
|
||
# MiniO
|
||
MINIO_ROOT_USER=admin
|
||
MINIO_ROOT_PASSWORD=put_minio_admin_password_here
|
||
MINIO_BROWSER_REDIRECT_URL=https://bmahrms-s3.bangkok.go.th/console/
|
||
|
||
# RabbitMQ
|
||
RABBITMQ_DEFAULT_USER=admin
|
||
RABBITMQ_DEFAULT_PASS=put_rabbitmq_admin_password_here
|
||
|
||
# MySQL
|
||
MYSQL_ROOT_PASSWORD=put_mysql_admin_password_here
|
||
MYSQL_DATABASE=bma_ehr
|
||
MYSQL_USER=frappet
|
||
MYSQL_PASSWORD=put_mysql_db_password_here
|
||
|
||
# Elasticsearch & Kibana
|
||
xpack.security.enabled=false
|
||
discovery.type=single-node
|
||
ELASTICSEARCH_HOSTS=http://bmahrms-elasticsearch:9200
|
||
|
||
# REDIS
|
||
REDIS_PORT=6379
|
||
REDIS_DATABASES=16
|
||
```
|
||
|
||
docker/bmahrms-service/compose.yaml จะใช้ docker volume (keycloak_data, minio_data ฯลฯ) แทน file system (ตัวอย่างก่อนหน้า) เพื่อประสิทธิ์ภาพสูงกว่าในการเก็บขอมูลที่มีการเขียนอ่านบ่อย
|
||
|
||
ให้แก้ค่า PUBLIC_KEY MINIO_ACCESS_KEY,MINIO_SECRET_KEY, ipaddress_bma_hrms_id ให้เหมาะสม
|
||
|
||
```yaml
|
||
networks:
|
||
hrms:
|
||
external: true
|
||
#clear all volume: docker volume rm $(docker volume ls -q | grep bmahrms-service)
|
||
# clear one volume docker volume rm bmahrms-service_mysql_data
|
||
volumes:
|
||
keycloak_data:
|
||
minio_data: {}
|
||
rabbitmq_data:
|
||
elasticsearch_data:
|
||
postgres_data:
|
||
mysql_data:
|
||
kibana_data:
|
||
services:
|
||
bmahrms-id:
|
||
image: quay.io/keycloak/keycloak:22.0.0
|
||
restart: unless-stopped
|
||
env_file: "service.env"
|
||
depends_on:
|
||
- bmahrms-postgres
|
||
volumes:
|
||
- /etc/localtime:/etc/localtime:ro
|
||
- keycloak_data:/opt/keycloak/data
|
||
- ./keycloak_config:/keycloak_config:ro
|
||
command:
|
||
- start-dev
|
||
- --features=token-exchange
|
||
- --https-certificate-file=/keycloak_config/keycloak.crt
|
||
- --https-certificate-key-file=/keycloak_config/keycloak.pem
|
||
- --http-enabled=true
|
||
networks:
|
||
- hrms
|
||
bmahrms-postgres:
|
||
image: postgres:15.3
|
||
restart: unless-stopped
|
||
env_file: "service.env"
|
||
volumes:
|
||
- postgres_data:/var/lib/postgresql/data
|
||
networks:
|
||
- hrms
|
||
bmahrms-s3:
|
||
image: minio/minio:RELEASE.2024-07-16T23-46-41Z
|
||
env_file: "service.env"
|
||
# mem_limit: "1g"
|
||
restart: unless-stopped
|
||
command: server /data --console-address ":9001"
|
||
volumes:
|
||
- minio_data:/data
|
||
networks:
|
||
- hrms
|
||
bmahrms-mq:
|
||
image: rabbitmq:3-management-alpine
|
||
env_file: "service.env"
|
||
mem_limit: "1g"
|
||
restart: unless-stopped
|
||
ports:
|
||
- 5672:5672
|
||
# - 9122:15672 # UI
|
||
volumes:
|
||
- rabbitmq_data:/var/lib/rabbitmq/
|
||
networks:
|
||
- hrms
|
||
bmahrms-mysql:
|
||
image: mysql:8.0.17
|
||
env_file: "service.env"
|
||
command: ["--max_connections=5000"]
|
||
restart: unless-stopped
|
||
ports:
|
||
- "9123:3306"
|
||
volumes:
|
||
- mysql_data:/var/lib/mysql
|
||
- ./init_mysql:/docker-entrypoint-initdb.d/:ro
|
||
networks:
|
||
- hrms
|
||
bmahrms-report-server:
|
||
image: docker.frappet.com/demo/report-server:latest
|
||
restart: unless-stopped
|
||
mem_limit: 1000m
|
||
volumes:
|
||
- ./report-server-templates:/app/templates
|
||
networks:
|
||
- hrms
|
||
bmahrms-elasticsearch:
|
||
image: docker.frappet.com/core/elasticsearch-icu:8.14.3
|
||
env_file: "service.env"
|
||
mem_limit: "4g"
|
||
volumes:
|
||
- elasticsearch_data:/usr/share/elasticsearch/data
|
||
- ./elasticsearch_config/config.yaml:/usr/share/elasticsearch/config/elasticsearch.yml
|
||
restart: unless-stopped
|
||
# disable below ulimits if run inside LXC
|
||
ulimits:
|
||
memlock:
|
||
soft: -1
|
||
hard: -1
|
||
networks:
|
||
- hrms
|
||
bmahrms-kibana:
|
||
image: docker.elastic.co/kibana/kibana:8.14.3
|
||
env_file: "service.env"
|
||
depends_on:
|
||
- bmahrms-elasticsearch
|
||
volumes:
|
||
- kibana_data:/usr/share/kibana/data
|
||
ports:
|
||
- 2130:5601
|
||
restart: always
|
||
networks:
|
||
- hrms
|
||
bmahrms-edm:
|
||
image: docker.frappet.com/edm/core
|
||
restart: unless-stopped
|
||
volumes:
|
||
- ./edm_config/keycloak.json:/app/static/keycloak.json:ro
|
||
environment:
|
||
- PUBLIC_KEY=put_realm_edm_public_key_here
|
||
- REALM_URL=https://bma-hrms-id.bangkok.go.th/realms/EDM
|
||
- PREFERRED_AUTH=online
|
||
- MANAGEMENT_ROLE=doc-management
|
||
- MINIO_HOST=bmahrms-s3.bangkok.go.th
|
||
- MINIO_PORT=443
|
||
- MINIO_SSL=true
|
||
- MINIO_ACCESS_KEY=put_minio_access_key_here
|
||
- MINIO_SECRET_KEY=put_minio_secret_key_here
|
||
# Bucket notification event needed to be configured
|
||
# Can use prepare script to create bucket
|
||
- MINIO_BUCKET=edm
|
||
- ELASTICSEARCH_PROTOCOL=http
|
||
- ELASTICSEARCH_HOST=bmahrms-elasticsearch
|
||
- ELASTICSEARCH_PORT=9200
|
||
# Can use prepare script
|
||
- ELASTICSEARCH_INDEX=edm-index
|
||
- AMQ_URL=amqp://admin:put_rabbitmq_admin_password_here@bmahrms-mq:5672
|
||
- AMQ_QUEUE=edm
|
||
- NODE_TLS_REJECT_UNAUTHORIZED=false
|
||
extra_hosts:
|
||
- bma-hrms-id.bangkok.go.th:ipaddress_bma_hrms_id
|
||
depends_on:
|
||
- bmahrms-postgres
|
||
|
||
networks:
|
||
- hrms
|
||
bmahrms-portainer:
|
||
image: portainer/portainer-ce:2.20.3
|
||
volumes:
|
||
- portainer_data:/data
|
||
- /var/run/docker.sock:/var/run/docker.sock
|
||
restart: unless-stopped
|
||
networks:
|
||
- hrms
|
||
```
|
||
|
||
รันคำสั่งดังนี้ในตัวอย่างเรียกใช้งานเฉพาะ Keycloak จะใช้ 2 service ตัวอย่างนี้จะเรียกใช้ฐานข้อมูลแล้วค่อยเรียกใช้โปรแกรม keycloak
|
||
|
||
```sh
|
||
docker compose up -d bmahrms-postgres
|
||
docker compose up -d bmahrms-id
|
||
```
|
||
|
||
### BMA HRMS Service
|
||
|
||
ระบบที่พัฒนาเพื่อ HRMS โดยเฉพาะ จะมี 3 ไฟล์
|
||
|
||
- be.env ค่าคอนฟิกของ Backend
|
||
- fe.env ค่าตอนฟิกของ Frontend
|
||
- compose.yaml คอนฟิกของ Docker
|
||
|
||
โปรแกรม Frntend เป็นส่วนของหน้าเวปเพื่อใช้งาน
|
||
|
||
- bmahrms เว็บไซต์สำหรับ Officer
|
||
- bmahrms-user เว็บไซต์ ระบบบริการเจ้าของข้อมูล
|
||
- bmahrms-admin ระบบ Admin
|
||
- bmahrms-checkin เว็บไซต์ ระบบลงเวลา
|
||
- bmahrms-publish เว็บไซต์ เผยแพร่ผลงาน
|
||
- bmahrms-candidate-register เว็บไซต์สำหรับรับสมัครสอบคัดเลือก
|
||
- bmahrms-qualifying-exam-cms เว็บไซต์ศูนย์ข้อมูลการสรรหาบุคคลของกรุงเทพมหานคร(CMS)
|
||
- bmahrms-manual ระบบคู่มือ
|
||
- bmahrms-faq เว็บไซต์ FAQ
|
||
- bmahrms-logs-n-backup Backup and Logs
|
||
|
||
โปรแกรม Backend ถูกเรียกใช้โดย Frontend อีกที
|
||
|
||
- bmahrms-report
|
||
- bmahrms-recruit
|
||
- bmahrms-insignia
|
||
- bmahrms-recruit-exam
|
||
- bmahrms-org-employee
|
||
- bmahrms-placement
|
||
- bmahrms-retirement
|
||
- bmahrms-report-v2
|
||
- bmahrms-probation
|
||
- bmahrms-command
|
||
- bmahrms-discipline
|
||
- bmahrms-evaluation
|
||
- bmahrms-leave
|
||
- bmahrms-org
|
||
- bmahrms-salary
|
||
- bmahrms-development
|
||
- bmahrms-kpi
|
||
|
||
docker/bmahrms/fe.env แก้ตัวแปร VITE_CLIENTSECRET_KEYCLOAK KC_SERVICE_ACCOUNT_SECRET
|
||
|
||
```
|
||
# Frontend Global
|
||
TZ=Asia/Bangkok
|
||
VITE_COMPETITIVE_EXAM_PANEL=https://bma-hrms-dashboard.bangkok.go.th/goto/KO0GpSu4z?orgId=1
|
||
VITE_QUALIFY_DISABLE_EMAM_PANEL=https://bma-hrms-dashboard.bangkok.go.th/goto/dQQzpIX4z?orgId=1
|
||
VITE_QUALIFY_EXAM_PANEL=https://bma-hrms-dashboard.bangkok.go.th/goto/cj1ZtIX4z?orgId=1
|
||
VITE_S3CLUSTER_PUBLIC_URL=https://bma-hrms-s3.bangkok.go.th/bma-ehr-fpt/organization/strueture/
|
||
VITE_REALM_KEYCLOAK=bma-ehr
|
||
VITE_URL_KEYCLOAK=https://bma-hrms-id.bangkok.go.th
|
||
VITE_CLIENTID_KEYCLOAK: "gettoken"
|
||
VITE_CLIENTSECRET_KEYCLOAK: put_client_secret_keycloak_here
|
||
VITE_API_REPORT_URL=https://bma-hrms.bangkok.go.th/api/v1/report-template
|
||
# เผยแพร่ผลงาน
|
||
VITE_API_PUBLISH_URL=https://bma-hrms-publish.bangkok.go.th
|
||
|
||
# Admin
|
||
VITE_API_URI_CONFIG=https://bma-hris.bangkok.go.th/api/v1
|
||
KC_URL=https://bma-hrms-id.bangkok.go.th
|
||
KC_REALM=bma-ehr
|
||
KC_SERVICE_ACCOUNT_CLIENT_ID=bma-ehr-dev
|
||
KC_SERVICE_ACCOUNT_SECRET=put_service_account_secret_here
|
||
MANAGEMENT_ROLE=storage_management
|
||
```
|
||
|
||
docker/bmahrms/be.env แก้ค่าของ DB_PASSWORD,AUTH_PUBLIC_KEY, MINIO_KEY, MINIO_SECRET, STORAGE_SECRET,KC_SERVICE_ACCOUNT_SECRET,REDIS_HOST,KEYCLOAK_KEY,AUTH_PUBLIC_KEY, PUBLIC_KEY
|
||
|
||
```
|
||
# Backend Global
|
||
TZ=Asia/Bangkok
|
||
ASPNETCORE_ENVIRONMENT=Development
|
||
APP_HOST=0.0.0.0
|
||
APP_PORT=80
|
||
HOST=0.0.0.0
|
||
PORT=80
|
||
DB_HOST=bmahrms-mysql
|
||
DB_PORT=3306
|
||
DB_USERNAME=root
|
||
DB_NAME=bma_ehr_organization_demo
|
||
DB_PASSWORD=DB_PASSWORD
|
||
AUTH_REALM_URL=https://bmahrms-id.bangkok.go.th/realms/bma-ehr
|
||
AUTH_PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkOrQxwoFeJE5TPXeSGL8IRDYVEL1OzmBuywNAzsL9vdcDUrjRA+Ocfp1pwLxXbNPacIgVmP1G+Cf3Steyp5ZeYAGL3u/MRHhUZA1tRbJ9sT+i/JzubmJCs9uF2pV9dLyT6kP7ZjKXmFBzHcXTS/GZMRtz8HZjB6ZzegFtV2oIrQq4+zo4BlzIAI6vaZfKn/JrTjJEbti0RQcqWfIldE918SQvZHzi3Upgn+OBopSRCrF7z3a7FEjYI1Vny42f5dBUcAmDDxOKqoJN09ArYchWkiDGvfpVarsclodptAGKwLuIDwDm9T9cnBUcBzWKNkwpQD3LvydOFVJRBqHAOrfEQIDAQAB
|
||
AUTH_PREFERRED_MODE=online
|
||
API=https://bma-hrms.bangkok.go.th/api/v1/
|
||
SECRET_KEY=put_secret_key_here
|
||
MINIO_HOST=https://bmahrms-s3.bangkok.go.th
|
||
MINIO_PORT=9000
|
||
MINIO_ACCESS_KEY=MINIO_KEY
|
||
MINIO_SECRET_KEY=MINIO_SECRET
|
||
MINIO_BUCKET=bma-ehr-fpt
|
||
API_URL=https://bmahrms.bangkok.go.th/api/v1
|
||
STORAGE_URL=https://bmahrms-edm.bangkok.go.th/api
|
||
STORAGE_REALM_URL=https://edm-id.bangkok.go.th/realms/EDM
|
||
STORAGE_SECRET=put_storage_secret_here
|
||
KC_URL=https://bmahris-id.bangkok.go.th
|
||
KC_REALM=bma-ehr
|
||
KC_SERVICE_ACCOUNT_CLIENT_ID=bma-ehr-dev
|
||
KC_SERVICE_ACCOUNT_SECRET=put_account_secret_here
|
||
MANAGEMENT_ROLE=storage_management
|
||
REDIS_HOST=192.168.1.81
|
||
REDIS_PORT=6379
|
||
|
||
KEYCLOAK_URL=https://bma-hrms-id.bangkok.go.th/realms/bma-ehr
|
||
KEYCLOAK_KEY=CNnpzJkwbk7jvI5Lb6gP5_Ok0WpDJJ50Mn0aD55Bd5E
|
||
KEYCLOAK_REALM=bma-ehr
|
||
|
||
PUBLIC_KEY=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYg0ZJvH6HgNOzyPp7PCvY3bJwD9WdsNn6gZbuvIfqJQZ8iSH1t0p3fgODO/fqwcj9UFeh1bVFOSjuW+JpnPehROqzt81KNl9zLLNXoN4LimReQHaMM3dU7DCbRylgVCouIDvObyjg8G+Cy5lZvFKWym/DPwGVpSdbvDZJ83qxq2dp7GJXS8PhOvA+MB1K009/jW5pBTUwNArLjoFccr+gIYIiOJDg2rYyIF3fDkwyWkuxr6xRt10+BRJytselwy/18kbDuJxVPaapdgTXI6wLzx7HWcDk30n5EvhJEumnIPpRst8gucqNYmB4MH+vsyoxV5WLuO3qmVRzFbtAppRQIDAQAB
|
||
REALM_URL=https://bmahrms-id.bangkok.go.th/realms/bma-ehr
|
||
PREFERRED_MODE=online
|
||
PREFERRED_AUTH=online
|
||
|
||
ELASTICSEARCH_PROTOCOL=http
|
||
ELASTICSEARCH_HOST=bmahrms-elasticsearch
|
||
ELASTICSEARCH_PORT=9200
|
||
ELASTICSEARCH_INDEX=bma-ehr-log-index
|
||
```
|
||
|
||
docker/bmahrms/compose.yaml
|
||
|
||
```yaml
|
||
networks:
|
||
hrms:
|
||
external: true
|
||
services:
|
||
# Start Frontend Section
|
||
# เว็บไซต์สำหรับ Officer
|
||
bmahrms:
|
||
container_name: bmahrms
|
||
image: docker.frappet.com/ehr/bma-ehr-app:latest
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6021:80"
|
||
networks:
|
||
- hrms
|
||
# เว็บไซต์สำหรับรับสมัครสอบคัดเลือก
|
||
bmahrms-candidate-register:
|
||
image: docker.frappet.com/ehr/bma-ehr-recruit-exam:latest
|
||
container_name: bmahrms-candidate-register
|
||
env_file: "fe.env"
|
||
restart: always
|
||
environment:
|
||
VITE_API_URI_CONFIG: "https://bmahrms.bangkok.go.th/api"
|
||
VITE_CLIENTID_KEYCLOAK: "bma-ehr-exam-vue3"
|
||
ports:
|
||
- "6022:80"
|
||
networks:
|
||
- hrms
|
||
# เว็บไซต์ศูนย์ข้อมูลการสรรหาบุคคลของกรุงเทพมหานคร(CMS)
|
||
# CMS ระบบสมัครสอบ
|
||
bmahrms-qualifying-exam-cms:
|
||
image: docker.frappet.com/demo/qualifying-exam-cms:latest
|
||
container_name: bmahrms-qualifying-exam-cms
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6023:80"
|
||
environment:
|
||
API_CMS_URL: "https://bmahrms.bangkok.go.th/api/v1/cms"
|
||
API_QUALIFYING_URL: "https://bmahrms.bangkok.go.th/api/v1/cms"
|
||
API_COMPETITIVE_URL: "https://bmahrms.bangkok.go.th/api/v1/recruit"
|
||
PUBLIC_URL_REGISTER_QUALIFY_EXAM: "https://bmahrms-apply.bangkok.go.th"
|
||
networks:
|
||
- hrms
|
||
# ระบบคู่มือ
|
||
bmahrms-manual:
|
||
image: docker.frappet.com/ehr/bma-ehr-manual:latest
|
||
container_name: bmahrms-manual
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6024:80"
|
||
networks:
|
||
- hrms
|
||
# เว็บไซต์ ระบบบริการเจ้าของข้อมูล
|
||
bmahrms-user:
|
||
image: docker.frappet.com/ehr/bma-ehr-user:latest
|
||
container_name: bmahrms-user
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6025:8087"
|
||
networks:
|
||
- hrms
|
||
# เว็บไซต์ ระบบลงเวลา
|
||
bmahrms-checkin:
|
||
image: docker.frappet.com/ehr/bma-ehr-checkin:latest
|
||
container_name: bmahrms-checkin
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6026:80"
|
||
networks:
|
||
- hrms
|
||
# เว็บไซต์ เผยแพร่ผลงาน
|
||
bmahrms-publish:
|
||
image: docker.frappet.com/ehr/bma-ehr-publish:latest
|
||
container_name: bmahrms-publish
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6027:80"
|
||
environment:
|
||
VITE_API_URI_CONFIG: "https://bmahrms.bangkok.go.th/api/v1"
|
||
VITE_API_PUBLISH_URL: "https://bmahrms.bangkok.go.th/api/v1/evaluation"
|
||
networks:
|
||
- hrms
|
||
# เว็บไซต์ FAQ
|
||
bmahrms-faq:
|
||
image: docker.frappet.com/ehr/bma-ehr-faq:latest
|
||
container_name: bmahrms-faq
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- "6028:80"
|
||
networks:
|
||
- hrms
|
||
# ระบบ Admin
|
||
bmahrms-admin:
|
||
container_name: bmahrms-admin
|
||
image: docker.frappet.com/ehr/bma-ehr-admin:latest
|
||
env_file: "fe.env"
|
||
restart: always
|
||
ports:
|
||
- "6029:8086"
|
||
environment:
|
||
VITE_CLIENTID_KEYCLOAK: "HRIS_ADMIN"
|
||
VITE_API_URI_CONFIG: "https://bma-hrms.bangkok.go.th/api/v1"
|
||
KC_REALM: "bma-ehr"
|
||
KC_SERVICE_ACCOUNT_CLIENT_ID: "bma-ehr-dev"
|
||
KC_SERVICE_ACCOUNT_SECRET: "f2mp7Xj4nz6gbgITve9J7AHXZI8dRhOd"
|
||
MANAGEMENT_ROLE: "storage_management"
|
||
networks:
|
||
- hrms
|
||
# Backup and Logs
|
||
bmahrms-logs-n-backup:
|
||
container_name: bmahrms-logs-n-backup
|
||
image: docker.frappet.com/ehr/bma-ehr-log-backup:latest
|
||
restart: always
|
||
env_file: "fe.env"
|
||
ports:
|
||
- 6030:3000
|
||
environment:
|
||
- KC_REALM_URL=https://bma-hrms-id.bangkok.go.th/realms/bma-ehr
|
||
- ELASTICSEARCH_PROTOCOL=http
|
||
- ELASTICSEARCH_HOST=192.168.1.40
|
||
- ELASTICSEARCH_PORT=9200
|
||
- ELASTICSEARCH_INDEX=bma-ehr-log-dotcom-index
|
||
- APP_HOST=0.0.0.0
|
||
- APP_PORT=3000
|
||
- WINDMILL_URL=http://host.docker.internal:20001
|
||
- WINDMILL_WORKSPACE=bma-ehr
|
||
- WINDMILL_BACKUP_FLOW_PATH=f/flow/full_backup_s3_mysql
|
||
- WINDMILL_RESTORE_FLOW_PATH=f/flow/full_restore_s3_mysql
|
||
- WINDMILL_BACKUP_DELETE_SCRIPT_PATH=f/flow/delete_backup_s3_mysql
|
||
- WINDMILL_BACKUP_LIST_SCRIPT_PATH=f/flow/list_backup_s3_mysql
|
||
- WINDMILL_API_KEY=I843JmwwcRKouMnE1DkTBRjiKl6yzkXM
|
||
- DB_HOST="bma-mysql-ehr"
|
||
- DB_PORT=3306
|
||
- DB_USERNAME=root
|
||
- DB_PASSWORD=adminVM123
|
||
- DB_LIST=bma_ehr,bma_ehr_development,bma_ehr_discipline,bma_ehr_evaluation,bma_ehr_exam,bma_ehr_history,bma_ehr_kpi,bma_ehr_leave,bma_ehr_organization,bma_ehr_probation,bma_ehr_salary,bma_ehr_support,bma_recruit
|
||
- MAIN_MINIO_USE_SSL=true
|
||
- MAIN_MINIO_HOST=bma-hrms-s3.bangkok.go.th
|
||
- MAIN_MINIO_PORT=443
|
||
- MAIN_MINIO_ACCESS_KEY=put_minio_access_key_here
|
||
- MAIN_MINIO_SECRET_KEY=put_minio_secret_key_here
|
||
- MAIN_MINIO_BUCKET=bma-ehr-fpt
|
||
- BACKUP_MINIO_USE_SSL=true
|
||
- BACKUP_MINIO_HOST=bma-hrms-s3.bangkok.go.th
|
||
- BACKUP_MINIO_PORT=443
|
||
- BACKUP_MINIO_ACCESS_KEY=put_backup_minio_access_key_here
|
||
- BACKUP_MINIO_SECRET_KEY=put_backup_minio_secret_key_here
|
||
- BACKUP_MINIO_BUCKET=bma-ehr-fpt-backup-dotcom
|
||
extra_hosts:
|
||
- host.docker.internal:host-gateway
|
||
networks:
|
||
- hrms
|
||
# End Frontend Section
|
||
|
||
# Start Backend Section
|
||
bmahrms-report:
|
||
image: docker.frappet.com/ehr/bma-ehr-report-service:latest
|
||
container_name: bmahrms-report
|
||
env_file: "be.env"
|
||
restart: always
|
||
# ports:
|
||
# - "7020:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-report.json:/app/appsettings.json
|
||
- ./appsettings-report.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-recruit:
|
||
container_name: bmahrms-recruit
|
||
image: docker.frappet.com/ehr/bma-ehr-recruit-service:latest
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7021:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-recruit.json:/app/appsettings.json
|
||
- ./appsettings-recruit.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-insignia:
|
||
image: docker.frappet.com/ehr/bma-ehr-insignia-service:latest
|
||
container_name: bmahrms-insignia
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7022:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-recruit-exam:
|
||
image: docker.frappet.com/ehr/bma-ehr-recruit-exam-service:latest
|
||
container_name: bmahrms-recruit-exam
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7023:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-recruit-exam.json:/app/appsettings.json
|
||
- ./appsettings-recruit-exam.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-org-employee:
|
||
image: docker.frappet.com/ehr/bma-ehr-org-employee-service:latest
|
||
container_name: bmahrms-org-employee
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7024:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-placement:
|
||
image: docker.frappet.com/ehr/bma-ehr-placement-service:latest
|
||
container_name: bmahrms-placement
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7025:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-retirement:
|
||
image: docker.frappet.com/ehr/bma-ehr-retirement-service:latest
|
||
container_name: bmahrms-retirement
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7026:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-report-v2:
|
||
image: docker.frappet.com/ehr/bma-ehr-report-v2-service:latest
|
||
container_name: bmahrms-report-v2
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7027:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-report-v2.json:/app/appsettings.json
|
||
- ./appsettings-report-v2.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-probation:
|
||
image: docker.frappet.com/ehr/bma-ehr-node-service:latest
|
||
container_name: bmahrms-probation
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7028:80"
|
||
environment:
|
||
DB_NAME: "bma_ehr_probation"
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-command:
|
||
image: docker.frappet.com/ehr/bma-ehr-command-service:latest
|
||
container_name: bmahrms-command
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7029:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-discipline:
|
||
image: docker.frappet.com/ehr/bma-ehr-discipline-service:latest
|
||
container_name: bmahrms-discipline
|
||
restart: always
|
||
# env_file: "be.env"
|
||
# ports:
|
||
# - "7030:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-evaluation:
|
||
image: docker.frappet.com/ehr/bma-ehr-evaluation-service:latest
|
||
container_name: bmahrms-evaluation
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7031:80"
|
||
environment:
|
||
DB_NAME: "bma_ehr_evaluation"
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-leave:
|
||
image: docker.frappet.com/ehr/bma-ehr-leave-service:latest
|
||
container_name: bmahrms-leave
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7032:80"
|
||
volumes:
|
||
- ./wwwroot:/app/wwwroot
|
||
- ./appsettings-combine.json:/app/appsettings.json
|
||
- ./appsettings-combine.json:/app/appsettings.Development.json
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-org:
|
||
image: docker.frappet.com/ehr/bma-ehr-org-service:latest
|
||
container_name: bmahrms-org
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7033:80"
|
||
environment:
|
||
DB_NAME: "bma_ehr_organization"
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-salary:
|
||
image: docker.frappet.com/ehr/bma-ehr-salary-service:latest
|
||
container_name: bmahrms-salary
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7034:80"
|
||
environment:
|
||
DB_NAME: "bma_ehr_salary"
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-development:
|
||
image: docker.frappet.com/ehr/bma-ehr-development-service:latest
|
||
container_name: bmahrms-development
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7035:80"
|
||
environment:
|
||
DB_NAME: "bma_ehr_development"
|
||
networks:
|
||
- hrms
|
||
|
||
bmahrms-kpi:
|
||
image: docker.frappet.com/ehr/bma-ehr-kpi-service:latest
|
||
container_name: bmahrms-kpi
|
||
restart: always
|
||
env_file: "be.env"
|
||
# ports:
|
||
# - "7036:80"
|
||
environment:
|
||
DB_NAME: "bma_ehr_kpi"
|
||
networks:
|
||
- hrms
|
||
# End Backend Section
|
||
```
|
||
|
||
## Configuration
|
||
|
||
การตั้งค่าเฉพาะของแต่ละ service มีสองส่วน
|
||
- เป็นการตั้งค่าเฉพาะโปรแกรมแตกต่างกันไปตามโปรแกรม
|
||
- ตั้งค่า route สำหรับ โดเมนต่างๆ(สำหรับ Frontend) และ Microservice (เป็นการรวมหลาย backend เข้าในโดเมนเดียวกันแต่อยู่คนละ Subfolder)
|
||
|
||
### Keycloak (bmahrms-id)
|
||
|
||
ใช้สำหรับการ login ในระบบ (Identity Server) เพื่อความปลอดภัยการสื่อสารเฉพาะภายใน จะเป็น https จะสร้าง self-signed certificate ขึ้นมาตัวอย่างนี้มีอายุ 10 ปี
|
||
|
||
```sh
|
||
cd bmahrms-service/keycloak_config
|
||
openssl genrsa -out keycloak.key 2048
|
||
openssl req -new -x509 -sha256 -key keycloak.key -out keycloak.crt -days 3650
|
||
cp keycloak.key keycloak.pem
|
||
cat keycloak.crt >> keycloak.pem
|
||
cd ..
|
||
```
|
||
|
||
Keycloak Route
|
||
|
||
```sh
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: put_admin_api_key_here" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-id",
|
||
"host": "bma-hrms-id.bangkok.go.th",
|
||
"uri": "/*",
|
||
"upstream": {
|
||
"scheme": "https",
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-id:8443": 1
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
### Portainer (bmahrms-portainer)
|
||
|
||
เป็นโปรแกรมสำหรับบริหารจัดการ container สามารถสิ่งเปิดปิดแก้ไขการทำงานของคอนเทนเนอร์ได้ เฉพาะผู้ดูแลระดับสูงถึงจะเข้าใช้งานส่วนนี้
|
||
|
||
```sh
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f2" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-portainer",
|
||
"host": "bmahrms-portainer.bangkok.go.th",
|
||
"uri": "/*",
|
||
"upstream": {
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-portainer:9000": 1
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
### MySQL (bmahrms-postgres)
|
||
|
||
init_mysql/\*.sql เป็นที่เก็บ SQL Script สำหรับสร้างฐานข้อมูลตั้งต้น
|
||
จะถูกเรียกใช้ครั้งแรกตอนเริ่มฐานข้อมูลเป็นข้อมูลตั้งต้นของระบบ
|
||
เนื่องจากไฟล์มีขนาดใหญ่หลายบรรทัดจะไม่ใส่ในเอกสารนี้
|
||
|
||
### Report Server
|
||
|
||
เป็น Microservice ใช้สำหรับการออกรายงาน ไม่จำเป็นต้องมี domain ของตัวเอง ให้เป็น path ในโดเมนที่มีอยู่ได้ ให้นำไฟล์ต้นแบบซึ่งสร้างจาก MS Word และ Excel มาไว้ที่โฟลเดอร์นี้
|
||
report-server-template/docx/files.docx, report-server-template/xlsx/files.xlsx
|
||
|
||
```sh
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: put_admin_api_key_here" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-report-server",
|
||
"hosts": ["bma-hrms.bangkok.go.th","bma-hrms-user.bangkok.go.th"],
|
||
"uris": ["/api/v1/report-template/*"],
|
||
"upstream": {
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-report-server:80": 1
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
### MiniO
|
||
|
||
Object Storage ใช้เพื่อเก็บไฟล์ของระบบถูกใช้โดย HRMS และ EDM
|
||
Route จะมีส่วน API กับ console การทำ route จะให้ console อยู่ใต้ subfoler https://domain/console
|
||
ในการติดตั้งบน production อาจจะไม่ได้อยู่ใน node เดียวกับ hrms และ apisix ดังนั้นควรอ้างเป็นชื่อโดเมนเต็มแทน
|
||
|
||
```sh
|
||
# bma-hrms-s3.bangkok.go.th
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: put_admin_api_key_here" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-s3",
|
||
"host": "bma-hrms-s3.bangkok.go.th",
|
||
"uri": "/*",
|
||
"upstream": {
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-s3:9000": 1
|
||
}
|
||
}
|
||
}'
|
||
# test
|
||
curl -k -I https://bma-hrms-s3.bangkok.go.th/minio/health/live
|
||
# bma-hrms-s3.bangkok.go.th/console
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: put_admin_api_key_here" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-s3-console",
|
||
"host": "bma-hrms-s3.bangkok.go.th",
|
||
"uri": "/console/*",
|
||
"plugins": {
|
||
"proxy-rewrite": {
|
||
"regex_uri": ["^/console/(.*)","/$1"]
|
||
}
|
||
},
|
||
"upstream": {
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-s3:9001": 1
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
### EDM (Enterprixe Document Management)
|
||
|
||
เป็นระบบจัดการเอกสารภายใน ประกอบไปด้วยโปรแกรมหลายตัว
|
||
|
||
- EDM ตัวโปรแกรมหลัก
|
||
- Elasticsearch ฐานข้อมูลดัชนีเอกสารเพื่อการค้นหาภาษาไทยแบบซับซ้อน อ้างผ่าน IP/PORT ไม่มี Route สู่ภายนอก
|
||
- Kibana ใน WebUI การจัดการ Elasticsearch มี Route ใช้เฉพาะนักพัฒนา
|
||
- RabbitMQ จัดการคิวงาน มี Route ใช้เฉพาะนักพัฒนา
|
||
- MiniO ใช้เพื่อเก็บไฟล์ต่างๆ มีหน้า console ใช้เฉพาะนักพัฒนา
|
||
|
||
นอกเหนือจาก compose.yaml มีไฟล์คอนฟิกสองไฟล์
|
||
|
||
```sh
|
||
nano edm_config/keycloak.json
|
||
nano elasticsearch_config/config.yaml
|
||
```
|
||
|
||
edm_config/keycloak.json
|
||
|
||
```json
|
||
{
|
||
"realm": "EDM",
|
||
"auth-server-url": "https://bma-hrms-id.bangkok.go.th/",
|
||
"ssl-required": "external",
|
||
"resource": "EDM-V1",
|
||
"public-client": true,
|
||
"confidential-port": 0
|
||
}
|
||
```
|
||
|
||
elasticsearch_config/config.yaml
|
||
|
||
```yaml
|
||
network.host: 0.0.0.0
|
||
s3.client.default.endpoint: bma-hrms-s3.bangkok.go.th
|
||
```
|
||
|
||
EDM Route
|
||
|
||
```sh
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: edd1c9f034335f136f87ad84b625c8f2" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-edm",
|
||
"host": "bma-hrms-edm.bangkok.go.th",
|
||
"uri": "/*",
|
||
"upstream": {
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-edm:80": 1
|
||
}
|
||
}
|
||
}'
|
||
```
|
||
|
||
Kibana Route
|
||
เป็น UI สำหรับ Elasticsearch สำหรับนักพัฒนามาตรวจสอบค่า ควรใช้จาก VPN และเน็ตเวิร์กภายในเท่านั้น เพื่อความปลอดภัย ให้ API gateway จะช่วยทำ Basic Authentication และ https ให้ ควรใช้ภายในเสำหรับนักพัฒนาเท่านั้น
|
||
|
||
```sh
|
||
curl "http://127.0.0.1:9180/apisix/admin/routes" \
|
||
-H "X-API-KEY: put_admin_api_key_here" -X PUT -d '
|
||
{
|
||
"id": "bmahrms-kibana",
|
||
"host": "bma-hrms-kibana.bangkok.go.th",
|
||
"uri": "/*",
|
||
"plugins": {
|
||
"basic-auth": {}
|
||
},
|
||
"upstream": {
|
||
"type": "roundrobin",
|
||
"nodes": {
|
||
"bmahrms-kibana:5601": 1
|
||
}
|
||
}
|
||
}'
|
||
# Basic Authentication
|
||
curl http://127.0.0.1:9180/apisix/admin/consumers \
|
||
-H 'X-API-KEY: put_admin_api_key_here' -X PUT -d '
|
||
{
|
||
"username": "admin",
|
||
"plugins": {
|
||
"basic-auth": {
|
||
"username": "admin",
|
||
"password": "kibana-password-here"
|
||
}
|
||
}
|
||
}'
|
||
|
||
```
|
||
|
||
# บทสรุป
|
||
ในยุคดิจิทัลที่เทคโนโลยีเปลี่ยนแปลงอย่างรวดเร็ว การออกแบบระบบซอฟต์แวร์ให้ตอบสนองความต้องการที่ซับซ้อนและเปลี่ยนแปลงได้ตลอดเวลาเป็นสิ่งจำเป็น สถาปัตยกรรม Microservice เป็นหนึ่งในแนวทางที่ได้รับการยอมรับอย่างกว้างขวาง เนื่องจากมีจุดเด่นด้านความยืดหยุ่น การปรับขยาย และการแยกส่วนการทำงานของระบบให้เป็นอิสระต่อกัน การนำเทคโนโลยีทันสมัยอย่าง Docker, RabbitMQ, Keycloak และ MinIO มาร่วมใช้งานใน Microservice ทำให้ระบบมีประสิทธิภาพยิ่งขึ้น ทั้งในด้านการพัฒนา การจัดการ และการรองรับการใช้งานในระดับสูง
|
||
|
||
การผสมผสานเทคโนโลยีอย่าง Docker, RabbitMQ, Keycloak และ MinIO ช่วยยกระดับความสามารถของระบบให้สอดคล้องกับความต้องการทางธุรกิจในยุคที่การแข่งขันสูง สถาปัตยกรรมนี้ไม่เพียงตอบสนองต่อความซับซ้อนของการพัฒนา แต่ยังช่วยเพิ่มความเร็ว ความเสถียร และความปลอดภัยของระบบ ทำให้ Microservice เป็นทางเลือกที่ทันสมัยและเหมาะสมสำหรับการพัฒนาระบบในยุคปัจจุบัน |