Go CI/CD

Go CI/CD

Kể từ bài viết cuối cùng về Feature Flags thì đã lâu lắm rồi mình chưa viết bài nào. Nay tranh thủ có chút thời gian thì mình sẽ viết bài chia sẻ về quá trình cấu hình và sử dụng CI/CD cho project Go của mình. Let’s start.

Vậy CI/CD là

I. CI/CD là gì

CI là quá trình tích hợp liên tục khi phát triển/bảo trì phần mềm. Các thành viên trong team sẽ tích hợp liên tục công việc của họ với nhau. Và mỗi khi tích hợp thì project sẽ được build và test tự động nhằm phát hiện lỗi sớm nhất có thể. Và nó cho phép phát triển phần mềm nhanh và chất lượng hơn.

CD hay Continue Delivery là quá trình chuyển giao liên tục. Mỗi khi quá trình tích hợp được build và test thành công thì hệ thống sẽ phân phối bản build tới kho chứa. Từ đó giảm thời gian mà các thành viên phải deploy source code lên các môi trường. Và sẵn sàng deploy bản build đó bất cứ lúc nào.

Vậy tóm gọn CI/CD là mô hình hiện đại được áp dụng nhiều tại các công ty lớn nhằm giảm thời gian phát triển phần mềm và nâng cao chất lượng.

II. CI/CD hoạt động như thế nào

Ở đây mình sẽ giải thích flow hoạt động của Github action. Các nền tảng CI/CD khác cũng tương tự hoặc khác 1 chút.

Khi developer push code lên trên github thì trigger thay đổi đó sang Github Actions. Nó sẽ kiểm tra cấu hình trong repo này và chạy các pipeline tương ứng như chúng ta đã cấu hình. Chút nữa thì chúng ta sẽ thực hiện test, build và push docker image lên docker hub.

Github Actions flow

III. Thiết lập CI/CD

Ở đây chúng ta sẽ thực hiện cấu hình CI/CD sử dụng Github Actions. Ngoài github Action thì các bạn có thể sử dụng rất nhiều platform khác như Gitlab, Travis CI, Circle CI hay thậm chí là Jenkins.

Github có 2 loại runner là GitHub-hosted runners và self-hosted runners. Github-hosted runners là các máy tính để chạy CI/CD được cung cấp và vận hành bởi Github. Còn self-hosted runners thì là máy tính của chúng ta nhưng được github hỗ trợ để sử dụng chạy CI/CD. Trong phạm vi bài viết này chúng ta sẽ sử dụng self-hosted runners.

Bảng giá của github. Thời gian cho Github Actions là có giới hạn

1. Cấu hình môi trường để chạy CI/CD

Để thực hiện cấu hình thì các bạn bật terminal và thực hiện các bước sau.

2.1 Update apt source

sudo apt-get update

2.1 Cài đặt docker

sudo apt-get install docker.io docker-compose up
sudo systemctl enable docker

2.2 Cài đặt Go

sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go

2.3 Thêm user vào docker group

sudo usermod -a -G docker $(whoami)

2. Cấu hình Github Actions self-hosted runners

2.1 Thêm self-hosted runners

Đầu tiên chúng ta truy cập vào setting Actions của repo trên Github.

Và sau đó chúng ta chọn thêm runner. Ở đây Github hướng dẫn chúng ta rất chi tiết từ việc download app về, cấu hình và chạy. Bước này chúng ta chỉ làm một lần. Khi nào khỏi động lại máy tính hoặc tắt runners đi rồi thì chỉ việc chạy ./run.sh để chạy lại thôi.

Sau khi thực hiện xong các bước thì back về trang cấu hình Actions để xem kết quả.

self-hosted runners của chúng ta đã lên sóng.

2.2 Thêm biến môi trường

Để push được docker image lên docker hub thì chúng ta cần phải login cho docker. Vì vậy chúng ta phải thêm cấu hình biến môi trường cho tài khoản và mật khẩu của docker hub.

Chúng ta vào trang cấu hình Secrets trong setting của repo.

Thực hiện thêm secret bằng nút nhấn vào nút New Secret

Chúng ta cần thêm 2 biến là DOCKER_USERNAMEDOCKER_PASSWORD

IV. Cấu hình CI/CD cho project Go

1. Viết Dockerfile

Chúng ta sẽ dùng docker để build project go này. Dockerfile là file cấu hình và từ đó chúng ta sẽ build nó thành docker image. Thực hiện tại file Dockerfile tại thư mục chính của project.

FROM golang:alpine as BUILDER
WORKDIR /go/src/app
COPY . .
RUN go mod vendor
RUN GOOS=linux go build -o main
FROM alpine
EXPOSE 80
WORKDIR /app
COPY --from=BUILDER /go/src/app/main /app
CMD /app/main

2. Cấu hình Github Actions

Tạo thư mục có tên .github tại gốc của project.

Trong thư mục .github tiếp tục tạo thư mục workflows.

Trong thư mục workflows chúng ta sẽ tạo file cấu hình cho Github Actions. File cấu hình được viết theo syntax YAML.

Thực hiện tạo file main.yml trong thư mục workflows

name: CI
on:
  push:
    branches: [ master, develop ]
  pull_request:
    branches: [ master, develop ]
jobs:
  test:
    runs-on: [self-hosted, Linux]
    steps:
      - uses: actions/checkout@v2
      - name: Install dependency
        run: go mod download
      - name: Unit test
        run: make test
        continue-on-error: false
  build:
    runs-on: [self-hosted, Linux]
    needs: [test]
    steps:
      - name: Login docker registry
        run: sudo docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD}
        env:
          DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
          DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
      - name: Change script permission
        run: chmod +x build_image.sh
      - name: Build
        run: sudo ./build_image.sh

Sau khi commit file cấu hình và đẩy lên github thì Github Actions sẽ chạy. Thử vào check và kết quả như sau

Github Actions đang chạy
Sau khi chạy thành công thì đã có dấu tick xanh.

Chúng ta thử vào trang docker hub để kiểm tra.

Code của chúng ta đã được build và đẩy lên docker hub rồi. Giờ chúng ta có thể deploy sử dụng image này.

V. Deploy sử dụng docker

Giờ để deploy lên server thì tất nhiên cần phải ssh lên server rồi 😀

Đầu tiên chúng ta thực hiện login vào docker hub nếu chưa login. Sau khi gọi lệnh login thì docker sẽ hỏi tài khoản và mật khẩu docker hub của chúng ta.

sudo docker login

Tiếp theo, chúng ta tạo file docker-compose.yml để cấu hình (nếu chưa có)

version: '3'
services:
  api:
    image: thanhdev2703/demogocicd
    restart: always
    ports:
      - 80:80
    volumes:
      - /data/log:/app/log
      - ./.env:/app/.env
    network_mode: "host"

Sau khi tạo xong file docker-compose.yml thì thực hiện lệnh sau để deploy (lần đầu).

sudo docker-compose up -d

Để thực hiện deploy code mới thì thực hiện như sau

sudo docker-compose pull
sudo docker-compose down
sudo docker-compose up -d

VI. Tổng kết

Như vậy chúng ta đã cấu hình xong CI/CD cho project dùng go. Thật đơn giản phải không nào.

Các bạn có thể tham khảo repo tại đây: https://github.com/ThanhDev2703/DemoGo-CICD

Tham khảo:
https://github.com/features/actions
https://github.com/actions/setup-go
https://docs.github.com/en/actions/building-and-testing-code-with-continuous-integration/about-continuous-integration

Leave a Reply

%d bloggers like this: