Đến thời điểm hiện nay, tôi thường yêu cầu các dự án của mình phải có CI. Nếu viết bằng script như nodejs thì CI sẽ có nhiệm vụ check syntax, để các thành viên trong nhóm cùng một kiểu viết giống nhau, và chạy các mức test khác nhau như unit test, CDC test.
Điểu tuyệt vời của gitlab là nó đi kèm với bộ CI miễn phí cho cả dự án private (yay). Blog này sẽ trình bày chiến lược để thiết lập ENV test trên Gitlab CI để build docker image, và upload nó lên gitlab registry.
Gitlab runner
Là nơi chương trình test của bạn sẽ được chạy. Bạn có thể có một PC riêng biệt cho việc build và test. Gitlab cung cấp một chương trình khá tiện https://gitlab.com/gitlab-org/gitlab-ci-multi-runner để thiết lập runner cục bộ. Cá nhân tôi chỉ sử dụng multi runner này khi chương trình cần tài nguyên lớn.
Phần lớn thời gian tôi sử dụng shared runner https://about.gitlab.com/gitlab-com/settings/#shared-runners. Xin cảm ơn sự tử tế của Digital Ocean khi cho mỗi build một tài nguyên 4GB chạy trong mỗi máy ảo riêng biệt.
Shared runner chạy trên docker, nên có thể khai báo các docker có sẵn khá tiện (yay).
.gitlab-ci.yml
Là file cấu hình cho gitlab CI. Dưới đây là một ví dụ trong đó khai báo một trạng thái của test pipeline là unit test. Phần sau dựa trên giả thuyết tôi đang xây dựng một web app với nodejs, và chạy unit test với npm run test
.
image: node:boron-alpine stages: - unit_test unit_test_job: stage: unit_test script: - npm install - npm run test
Với mỗi git push
lên CI được trigger. CI sẽ pull về docker image node:boron-alpine
giống với docker chạy trong staging và production environment của web app này. Stages khai báo các bước của CI. Trong trường hợp này, tôi chỉ có một bước duy nhất là unit test khai báo trong unit_test_job
.
Nhưng tôi tin vào 12factor, và tôi muốn có quá trình build trước. CI hay staging hay production sẽ khác nhau ở ENV truyền vào docker như trình bày ở https://12factor.net/build-release-run. Tôi sẽ tạo một job để tạo artifact, và chạy test trên artifact này.
image: docker:1.12 services: - docker:dind stages: - build variables: CONTAINER_TEST_IMAGE: registry.gitlab.com/company/project:$CI_BUILD_REF_NAME before_script: - docker info build_image_job: stage: build script: - docker build -t $CONTAINER_TEST_IMAGE . - docker run $CONTAINER_TEST_IMAGE npm run test
Setup này sử dụng docker in docker (dind) để build docker image trong một docker (nơi CI đang chạy). Đều này đạt được do shared runner chạy với privileged
enable.
Như vậy lúc này CI sẽ tạo một docker có tên biến CONTAINER_TEST_IMAGE
, và chạy test trong image này.
Tôi muốn tiến thêm một bước nữa, pipeline bao gồm: build, test, và release. Quá trình release xảy ra khi tôi tag git tag -a version
, nó sẽ tạo ra tag latest
và upload lên gitlab registry.
Khoa, gitlab registry? Đúng vậy, gitlab cho phép bạn lưu các image lên host của họ. Bạn sẽ có CI, và registry (miễn phí).
image: docker:1.12 services: - docker:dind stages: - build - test - release - deploy variables: CONTAINER_TEST_IMAGE: registry.gitlab.com/company/project:$CI_BUILD_REF_NAME CONTAINER_RELEASE_IMAGE: registry.gitlab.com/company/project:latest before_script: - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com build: stage: build script: - docker build --pull -t $CONTAINER_TEST_IMAGE . - docker push $CONTAINER_TEST_IMAGE unit_test: stage: test script: - docker pull $CONTAINER_TEST_IMAGE - docker run $CONTAINER_TEST_IMAGE npm run unit_test cdc_test: stage: test script: - docker pull $CONTAINER_TEST_IMAGE - docker run $CONTAINER_TEST_IMAGE npm run cdc_test release-image: stage: release script: - docker pull $CONTAINER_TEST_IMAGE - docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE - docker push $CONTAINER_RELEASE_IMAGE only: - tags - triggers
Gitlab rất hào phóng khi cung cấp đầy đủ các công cụ và dịch vụ để bạn có thể xây dựng một quá trình CI khá hoàn chính, từ việc chạy các test đến việc lưu trữ các image của bạn.
Hy vọng bạn sẽ tìm thấy sự hữu dụng trong ecosystem của gitlab.