หลังจากที่คราวก่อนได้โม้เกี่ยวกับ gitlab ไปแล้วว่าทำไมทีมผมจึงใช้งานมัน โดยประโยชน์ของมันหลักๆ ที่ผมชอบก็คือ รองรับการเขียน CICD ตั้งแต่การใช้งานฟรีเลย ฉะนั้นแล้วพวกเรามาทำ CICD กันเถอะ
CICD ย่อมาจาก Continuous integration and continuous delivery ผมขออธิบายแบบสั้นๆ ก็คือการทำให้โปรเจ็คของเราทำงานแบบอัตโนมัติทั้งหมด ตั้งแต่การ run unitest, build, packing ไปจน deploy หรือใครจะมี flow แบบอื่นก็แล้วแต่จะใส่เข้าไป
ก่อนที่จะเริ่มเขียน gitlab ci กันผมอยากให้ทุกคนต้องใช้ git และ docker เป็นก่อนนะ และเข้าใจการทำงานของ Container ด้วย เพราะการทำพวกระบบ CICD เราจะใช้ docker เข้าช่วย หากใครไม่รู้ ก็ไปรู้ซะ…
แน่ละจะใช้ของเขาก็สมัครของเขาด้วยเพื่อจะได้ใช้งานได้ https://gitlab.com/users/sign_in#register-pane
สมัครเลยมันฟรี!!!
ใน gitlab จะใช้คำว่า project แทน repository
ให้เราสร้างไฟล์ .gitlab-ci.yml
ไว้ที่ root project ซึ่งทุกครั้งที่เรา push ขึ้นมา gitlab จะมาอ่านไฟล์นี้ทุกครั้ง
ผมจะขอยกตัวอย่างการเขียนจาก https://gitlab.com/twin-opensource/laravel-nginx-phpfpm-k8s/blob/master/.gitlab-ci.yml ทุกคนสามารถโหลด project นี้ไปทดสอบได้
Ref: https://area51.twinsynergy.co.th/structure-laravel5-nginx-phpfpm-k8s/
stages:
- build
- test
- release
- deploy
stages
เป็นการกำหนด flow การทำงานของ pipeline นี้ให้กับ job
ต่างๆ โดยมันจะเรียงตามลำดับที่เราได้กำหนดไว้ เช่น
build
ถ้าสำเร็จมันก็จะไปที่ test
และถ้าใน build
นั้นมีหลาย jobs มันก็จะทำงานพร้อมกันเป็นแบบ parallelbuild
ทำงานสำเร็จทั้งหมด test
ถึงจะทำงานต่อtest
ทำงานสำเร็จทั้งหมด release
ถึงจะทำงานต่อrelease
ทำงานสำเร็จทั้งหมด deploy
ถึงจะทำงานต่อdeploy
ทำงานสำเร็จทั้งหมด ก็คือจบ pipeline มันจะขึ้นว่า successjob
คือการกำหนดว่าจะให้ทำอะไรใน stage
นั้นๆ เช่น
job1:
script: "execute-script-for-job1"
job2:
script: "execute-script-for-job2"
โดยภายใน job จะมีค่ากำหนดเพิ่มเติมอีกเช่น image, before_script, script เป็นต้น
npm:
stage: build
image: node:10-alpine
before_script:
- apk add --no-cache --update make gcc g++ libc-dev libpng-dev automake autoconf libtool
script:
- cd laravel/
- '[ -f package-lock.json ] && rm package-lock.json'
- npm install
- npm run prod
cache:
key: cache-node
paths:
- laravel/node_modules/
- laravel/public/
only:
- master
ตัวอย่างข้างบนคือ job ที่ชื่อว่า npm โดยค่าอื่นๆ มีดังนี้
stage
คือการบอกว่า job นี้อยู่ใน stage ไหนimage
กำหนด docker image มาใช้งานโดยมันจะเอามาจาก hub.docker.combefore_script
ก่อนเริ่ม script
ให้มันทำอะไร โดยเราสามารถใส่คำสั่ง command ของ docker image ที่เลือกมาจาก image
ได้ เช่นในตัวอย่างผมให้มันติดตั้ง make gcc g++ libc-dev libpng-dev automake autoconf libtool
เพื่อไว้เตรียมตัวติดตั้ง packet ต่างๆ ของ nodescript
เป็นการกำหนดคำสั่ง command ให้มันทำอะไรcache
เราสามารถให้มัน cache ไฟล์หรือโฟล์เดอร์ไว้ เพื่อนำไปใช้งานใน job อื่นต่อ เช่นในตัวอย่างผมทำการ cache โฟล์เดอร์ laravel/node_modules/
และ laravel/public/
และตั้งชื่อ cache นี้ว่า cache-node
only
เป็นการกำหนดว่าให้ job นี้ทำงานเฉพาะ branch หรือ tag ชื่อ master
นั้นหมายความว่าเมื่อไรก็ตามที่ผมทำการ push code หรือ merge request เข้าไปยัง branch master หรือสร้าง tag ชื่อ master ไป job นี้จะถูกทำงานทันทีจากโค็ดด้านบนผมได้ทำการ cache ไฟล์ชื่อ cache-node
ใน job npm ไว้แล้ว คราวนี้เรามาดูวิธีการให้ job ที่เราต้องการดึง cache ชุดนี้มาใช้
release-nginx:
stage: release
image: docker:latest
services:
- docker:dind
cache:
key: cache-node
paths:
- laravel/public/
policy: pull
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build --pull -t $CI_REGISTRY_IMAGE:nginx -f Dockerfile-nginx .
- docker push $CI_REGISTRY_IMAGE:nginx
only:
- master
ที่นี่เรามาดูในส่วนของ cache
จากโค็ดชุดนี้กัน มันจะมี policy
เพิ่มขึ้นเป็นการกำหนดว่า job นี้จะให้มันทำการ pull
หรือดึงข้อมูลมาจาก cache ที่ชื่อว่า cache-node
ทุกครั้งก่อนทำการ script
และเรายังสามารถเลือกได้ว่าจะให้เอาเฉพาะไฟล์ หรือโฟล์เดอร์ไหนมา ซึ่งในตอนแรกผมผมทำการ cache โฟล์เดอร์ laravel/node_modules/
และ laravel/public/
ไว้ แต่เวลา pull
ลงมาผมเลือกเฉพาะ laravel/public/
เพียงเท่านี้เราก็สามารถเขียน pipeline ให้กับโปรเจ็คของเราได้แล้วง่ายๆ ซึ่งในบทความต่อๆ ผมจะบอกวิธีการใช้งาน .gitlab-ci.yml
เพิ่มเติม