คราวก่อนได้ทำ CICD ให้กับ Golang บน Gitlab กันแล้วมาคราวนี้ผมจะทำ nodejs ให้ดูกันบ้างว่ามีวิธีการยังไง

อันนี้เป็นโค็ดตัวอย่างที่ผมได้รองทำไว้สามารถ clone มาลองใช้งานได้เลย

https://gitlab.com/twin-opensource/nodejs-cicd

เรามาดูไฟล์ .gitlab-ci.yml กันก่อน

stages:
  - build
  - release

npm:
  stage: build
  image: node:10-alpine
  script:
    - '[ -f package-lock.json ] && rm package-lock.json'
    - npm i
  cache:
    key: npm-cache
    paths:
      - node_modules

create-docker-image:
  stage: release
  image: docker:latest
  services:
    - docker:dind
  cache:
    key: npm-cache
    paths:
      - node_modules
    policy: pull
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build --pull -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME

ขั้นตอนโดยภาพรวม

ขั้นตอนของการทำ cicd ให้กับ nodejs จะเป็นดังนี้

  • ติดตั้ง node_modules แล้วก็ cache เก็บไว้
  • โหลด node_modules ที่ได้มาแล้วทำ docker image
  • นำ docker image ที่ได้มาไปใช้งาน

ติดตั้ง node_modules

npm:
  stage: build
  image: node:10-alpine
  script:
    - '[ -f package-lock.json ] && rm package-lock.json'
    - npm i
  cache:
    key: npm-cache
    paths:
      - node_modules

ใน build stage นั้นผมจะให้มันลบไฟล์ package-lock.json ออกก่อนเพื่อไม่ให้เวลาติดตั้ง node_modules แล้วมันไปอ้างอิง libs จากไฟล์นี้ จากนั้นก็ค่อยสั่ง npm i เพื่อทำการติดตั้ง node_modules แล้วก็ทำการ cache เก็บไว้

ประโยชน์ของการทำ cache เก็บไว้ขั้นตอนนี้ทำให้เราสามารถนำ node_modules ที่ได้มาไปใช้ใน stage อื่นๆ ได้ และเมื่อมีการ run pipeline ตัวนี้ใหม่ มันก็จะโหลด node_modules มาให้เลย แล้วก็ค่อย npm i ทำให้การติดตั้งเร็วขึ้น ไม่ต้องติดตั้ง package ใหม่ทั้งหมดทุกครั้ง

ทำ Docker image

create-docker-image:
  stage: release
  image: docker:latest
  services:
    - docker:dind
  cache:
    key: npm-cache
    paths:
      - node_modules
    policy: pull
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build --pull -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME

ใน release stage ผมจะให้มันโหลด node_modules มาจาก build stage จากนั้นก็ทำการ login ไปยัง docker registry ของ gitlab แล้วก็สั่งให้มัน docker build จาก dockerfile

FROM node:10-alpine
LABEL name="NodeJs CICD" \
    version="1.0.0" \
    org.label-schema.vcs-url="https://gitlab.com/twin-opensource/nodejs-cicd" \
    org.label-schema.vendor="Twin synergy"
WORKDIR /usr/src/app
COPY ./ ./
RUN apk --no-cache add ca-certificates \
    && apk add --update tzdata \
    && cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime \
    && apk del tzdata
EXPOSE 8080
CMD [ "npm", "start" ]

ซึ่งใน dockerfile ก็เพียงแค่ทำการ COPY ./ ./ คัดลอกไฟล์ทั้งหมดลงมายัง /usr/src/app ไว้จากนั้นก็สั่ง npm start เพื่อทำให้แอพพลิเคชั่นทำงาน

แล้วค่อยสั่ง docker push ไปเก็บไว้ที่ docker registry ของเรา

ทดสอบการใช้งานหน่อย

ลองเรียกใช้ด้วย docker จากนั้นทดสอบดู

$ docker run -d -p 8080:8080 registry.gitlab.com/twin-opensource/nodejs-cicd:master
$ curl http://localhost:8080
Hello world

ได้ Hello world มาแล้ว

ขอให้สนุกกับการเขียน gitlab-ci นะครับ