The Twelve Factors - SilverSky9/DevToolNo1 GitHub Wiki
The Twelve Factors
1. Codebase
One codebase tracked in revision control, many deploys
คือโค้ดอยู่ที่เดียวกัน version เดียวกัน โดย control version ที่ git, sub version โดย 1 โปรเจคควรมีแค่ที่เดียว ถึงแม้ว่าจะทำ microservice ที่มีหลายๆ service ก็ควรอยู่ที่ repository เดียวกัน การใช้โปรเจ็คร่วมกันเพื่อลดปัญหาการ comunication กันภายใน ก่อนที่จะแยก repo ควรทำแบบที่รวม repo กัน แล้วทำงานให้ได้ก่อน แล้วเมื่อทำงานได้แล้วจะแยกแต่ละ service ออกจากกันที่หลังก็ได้
2. Dependencies
Explicitly declare and isolate dependencies
Dependencies มักจะไม่ประกาศในโปรเจคตรงๆ แต่จะเป็นแค่การประกาศเพียงแค่ว่าเราจะใช้ library ตัวไหน version อะไรบ้าง เช่น package.json
3. Configuration
Store config in the environment
configuration ที่ดีไม่ควรอยู่ใน Application ควรจะต้องถูกแยกออกมาอยู่ใน System environment, configuration server หรือ remote configuration เพื่อที่จะสามารถแก้ไขได้ โดยที่จะไม่กระทบกับ code ใน application ตัวอย่างเช่น การกำหนด Environment Variable ที่ใช้ในระบบ ในไฟล์ .env นอกจากนี้ไม่ควรเก็บ configuration ไว้ที่ Database เพียงเพื่อจะทำให้สามารถแก้ไขได้ โดยการ reload configuration ใหม่
4. Backing services
Treat backing services as attached resources
ระบบการทำงานต้องมีความง่ายต่อการ deploy สามารถเปลี่ยนได้ง่าย ยกตัวอย่าง ถ้าหากต้องการเปลี่ยน Database หรือ File system ของ service ก็สามารถเปลี่ยนได้ โดยมี Downtime ให้น้อยที่สุด
5. Build, release, run
Strictly separate build and run stages
ควรแยก process ในการ Build, Release, Run แยกออกจากกัน การ build คือการเอา source code ทุกอย่างมาทำ software test จากนั้นก็ ค่อย release แล้ว run ให้จบไปเป็น step step ไป จะไม่รวมกันเป็น step เดียว เพราะว่า ถ้ามีการผิดพลาดในแต่ละขั้นตอนแล้ว เราจะสามารถแก้ไขได้ง่าย และรู้ได้ว่าเกิดข้อผิดพลาดจากตรงไหนได้ง่ายขึ้น
6. Processes
Execute the app as one or more stateless processes
ทุกๆ service ควรทำให้เป็น stateless process Service ต่างๆ ไม่ควรจะเป็นข้อมูลอะไรไว้ใน service ของตัวเอง เพราะถ้าหากต้องการจะย้ายข้อมูลจะลำบาก ควรให้ server ทำตามแค่หน้าที่ตาม Business logic เท่านั้น ยกตัวอย่าง พวกไฟล์รูป ควรเก็บอยู่ใน Nas storage ไม่ควรเก็บอยู่ที่ข้อมูล ใน contrainner เพราะถ้าหากต้องการย้าย หรือเปลี่ยนข้อมูล ไฟล์รูปต่างๆ ก็จะต้องถูกขนย้ายออกมาด้วย
7. Port binding
Export services via port binding
เป็นเรื่องของ contrainner ปกติคือ สามารถที่จะรัน port เดียวกันได้ หลายตัวบนเครื่องเดียวกัน โดยหากต้องการใช้ port ก็ expose port ออกมา ก็จะสามารถเรียกใช้งานได้ ทำให้ไม่ต้องแก้ port เพื่อให้ service ต่างๆทำงานได้
8. Concurrency
Scale out via the process model
เป็น model ในการ scale ตามแต่ละ service ถ้า service ไหนที่การใช้งานเยอะ ก็ scale เฉพาะ service นั้นให้มีจำนวนเครื่องที่ใช้ให้เหมาะสมตามการใช้งานของ service
9. Disposability
Maximize robustness with fast startup and graceful shutdown
ระบบงานต้อง start ได้เร็วและจบลงได้สวย เพื่อลด Downtime ยกตัวอย่าง java spring boot ใน contrainner. contrainner start ขึ้นมาเสร็จแล้ว แต่ตัว spring ยัง start ยังไม่เสร็จ หมายความว่า service จะยังไม่พร้อมใช้งานจนกว่า spring boot จะ start เสร็จ ซึ่งจะทำให้เกิด Downtime ของ service นั้นเพิ่มขึ้น
10. Dev / prod parity
Keep development, staging, and production as similar as possible
ควรทำให้ environment ให้เหมือนกันที่สุดเท่าที่จะทำได้ เหมือนกันในที่นี้หมายถึงโครงสร้างของ environment ยกตัวอย่าง หาก production มี load balance ที่ dev ก็ควรจะมี load balance ด้วย เพือทำให้ environment เหมือนกันมากที่สุด หรือ หาก database ที่ production เป็นแบบ multi master ที่ dev ก็ควรจะเป็นเหมือนกัน
11. Logs
Treat logs as event streams
ทำ centralized log พยายามคิดว่า log ต่างๆ เป็น steam โดยที่อยากจะเก็บอะไรก็ค่อยเอา tool ต่างๆมาเก็บข้อมูลที่เราอยากจะเก็บ
12. Admin processes
Run admin/management tasks as one-off processes
พยายามทำให้ทุกๆ เครื่อเหมือนกัน admin task ของแต่ละ service ถ้า admin ต้องการจะทำอะไรควรทำผ่านช่องทางหรือชุดคำสั่งที่กำหนดไว้ให้ ไม่ควรทำเองโดยไม่่ผ่านชุดคำสั่ง ในของแต่ละ service นั้นๆ เพื่อลดปัญหาในการเปลี่ยนแปลงที่จะไม่เหมือนกันในแต่ environment
ตัวอย่างการนำ Twelve Factors ไปใช้ภายในโปรเจค
1. Codebase
- ใช้ Git Version Control ในการทำงาน
2. Dependencies
- กำหนด Dependencies ต่างๆที่ต้องการใช้ในไฟล์ package.json
3. Configuration
- กำหนด Environment Variable ภายในไฟล์ .env
4. Build, release, run
- ใช้ Dockerfile และ docker-compose.ymal
5. Port binding
- มีการกำหนด Port ที่ต้องการใข้งานใน docker-compose.ymal