02/06/2017

Build a custom docker image for test and deploy app on Gitlab CI



Hôm trước mình có viết bài cấu hình Gitlab CI để test app python trước khi deploy sang production, hôm nay mình nối tiếp và bổ sung một số mục cần thiết để cấu hình CI stable nhất.

Nội dung gồm có:
  • - Cài đặt Gitlab Runner như một Docker services.
  • - Build custom docker image để tiết kiệm thời gian setup environment (vì app mình là python nên mỗi lần exec phải cần install đầy đủ dependencies).
  • - Cấu hình file .gitlab-ci.yml để link các services database bằng docker.
  • - Hiển thị code coverge sau khi test (py.test in this case).
  • - Dùng dpl để deploy code sang heroku (có trong bài trước).
  • - Collectstatic fast.
  • - Chuyển các command exec khi deploy code (migrate).
1. Cài đặt Gitlab Runner như một Docker services.


Mình tạo 2 VPS Vultr gói 5$ với CoreOS (mình dùng CoreOS vì nó khá lightweight và support Docker). Cài đặt Gitlab Runner bằng Docker khá dễ, theo tài liệu từ Gitlab mình có command sau:

If you plan on using Docker as the method of spawning Runners, you will need to mount your docker socket like this:
docker run -d --name gitlab-runner --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  gitlab/gitlab-runner:latest
Ở trên mình có mount 2 volume là /var/run/docker.sock (để container có thể spawning các service bên ngoài, vd như database lúc nãy có nói qua), và /srv/gitlab-runner/config để store cấu hình.

Sau đó link Runner với Gitlab. Token các bạn lấy ở đây: https://gitlab.com/tên-của-bạn-không-phải-của-mình/tên-project-của-bạn-luôn/settings/ci_cd
docker exec -it gitlab-runner gitlab-runner register

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
https://gitlab.com
Please enter the gitlab-ci token for this runner
xxx
Please enter the gitlab-ci description for this runner
my-runner
INFO[0034] fcf5c619 Registering runner... succeeded
Please enter the executor: shell, docker, docker-ssh, ssh?
docker
Please enter the Docker image (eg. ruby:2.1):
ruby:2.1
INFO[0037] Runner registered successfully. Feel free to start it, but if it's
running already the config should be automatically reloaded!
Nếu như kiểm trang tại link bên tên và thấy đã có runner trong danh sách, chúc mừng bạn đã hoàn thành xong bước 1.


2. Build custom image

Bước này là điểm nhấn của bài viết. Lúc trước vì mỗi lần test mình phải cài đặt dependencies nên sẽ spent ý nhất 15p để done bước này, thật là vô ích nếu mỗi lần test phải mất chừng ấy thời gian.

Mình tham khảo post này và nảy sinh ý định custom image http://www.greysonparrelli.com/post/setting-up-android-builds-in-gitlab-ci-using-shared-runners/

B1: trong bài viết tác giả tạo 1 repo khác, nhằm giảm thời gian build image vì quá trình clone source code sẽ mất thời gian; mình thì dùng ngay trên repo chính luôn, chỉ tạo ra 1 branch name "build-image" (đặt tên gì cũng được nha các bạn)

B2: mình xóa hết source code trong này đi, chỉ để lại 3 file là .gitlab-ci.yml, Dockerfilerequirements.txt


- File .gitlab-ci.yml mình cấu hình khi nào có push commit mới lên thì sẽ chạy stage build_image. Script ở chỗ này sẽ build image từ file Dockerfile, sau đó upload lên Gitlab Container Registry, $CI_JOB_TOKEN là variable mặc định ở đâu đó của Gitlab (mình ko biết :D) dùng để login và upload image.

 - File Dockerfile: inherited từ image python:2 (app mình dùng python 2.7), sau đó copy file requirements.txt lúc nào vô, sau đó install dependencies trong đó. Mình có setup thêm phantomjs vì có test frontend. - File requirements.txt: file này chứa dependencies của python, cái này bạn nào cũng biết :D Sau khi push branch này lên, Gitlab sẽ build ra image, bạn kiểm tra tại đây: 
(trong này không có source code của mình đâu, các bạn đừng sợ :D)

3. Cấu hình .gitlab-ci.yml dùng custom image

Sau khi build xong thì dùng chứ để làm gì.

Quay lại branch master, mình cấu hình như sau:



- Trong file có link luôn các database: redis, mongodb, postgresql mà không cần mất phút giây nào để setup.

- Mình cấu hình là dùng image custom đó, thì khi install lại requirements sẽ không mất thời gian ở bước này (cái nào setup rồi thì sẽ được bỏ qua). Sau khi test xong, nếu ref nào có regex match vô là /^staging.*$/thì sẽ được chuyển sang app staging, nếu ở master thì sẽ push qua production server.

Đây là bằng chứng mình chạy test nhanh đến kinh khủng (từ 40p -> 22p)

3. Hiển thị code coverge sau khi test (py.test in this case)

Trong hướng dẫn của Gitlab thì dùng regex \d+\%\s*$ nhưng trong trường hợp mình không được bởi dòng coverge không phải là dòng cuối cùng. Mình đang nghiên cứu thêm, nhưng bạn nào không xuất summary bên dưới thì vẫn chạy ổn. Mình hay test trên trang này http://regexr.com/



4. Collectstatic fast

Bên mình dùng S3 để store static, mỗi lần collect django sẽ upload lên toàn bộ file nên sẽ rất nặng nề và tốn công. May thay đã có collectfast đã giải quyết vấn đề này. Mỗi lần exec command collect thì collectfast sẽ kiểm tra AWS_PRELOAD_METADATA, chỉ upload những file có thay đổi.

5. Migrate database on heroku

Hồi trước mỗi khi deploy lên heroku thì mình phải xài heroku toolbelt trên server test để chạy migrate bằng command: heroku run python manage.py migrate, nhưng sẽ có secure risk ở đây là khi login account vô heroku toolbelt thì nếu ai vô được server test sẽ full control account của bạn.

Mình thêm dòng này vào Procfile

release: python manage.py migrate


Command trên Heroku tham khảo ở đây: https://devcenter.heroku.com/articles/release-phase#getting-started




Không có nhận xét nào:

Đăng nhận xét