Rails 部署實踐 - 使用 GitLab 的 Review Apps 機制
Review Apps 是 GitLab 所提供的一個機制,可以用於針對某個 Merge Request(合併請求)來自動部署給用來進行 QA(Quality Assurance)驗證或者專案經理檢查功能的機制。因為我們已經可以進行自動化的部署,也因此可以用來產生 Review Apps 進行驗證。
Heroku 也有提供 Review Apps 的方案可以跟 GitHub 搭配,可以根據需求調整。
Review Apps 的運作方式
GitLab 的 Review Apps 簡單來說,就是當我們發出一個 Merge Request 的時候,如果有偵測到部署的行為,就會自動在 Merge Request 的畫面上多出一個 View app
按鈕,可以用來打開被部署的環境。
要實現一個完整的 Review Apps 的流程,我們需要以下幾個設定:
- 在 Merge Request 產生時執行部署
- 在 Merge Request 合併時停止部署(移除暫時的環境)
- 在 Merge Request 的部署中載入初始化資料
啟動跟停止的部分可以利用 GitLab CI 來實現,至於初始化的測試資料則需要我們運用一些小技巧來處理。
這類初始化資料可以使用 Rails 的 Seeds 功能來實現
加入停止機制
我們在整合 GitLab CI 自動部署這篇文章中,已經可以自動的部署到正式環境,基本上只需要使用相同的方式,加入下面這段調整就可以支援 Review Apps 的啟動,然而我們還需要停止的處理。
1deploy:review:
2 image: docker:stable
3 stage: deploy
4 environment:
5 name: review/$CI_COMMIT_REF_NAME
6 url: $DEPLOY_DOMAIN
7 on_stop: review:stop
8 before_script:
9 - echo "$CI_JOB_TOKEN" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
10 - apk -Uuv add curl
11 - curl -LO https://github.com/sudo-bmitch/docker-stack-wait/raw/main/docker-stack-wait.sh
12 - chmod +x docker-stack-wait.sh
13 script:
14 - docker stack deploy -c $DEPLOY_STACK_FILE --with-registry-auth --prune $DEPLOY_NAME
15 - sleep $DEPLOY_WAIT_TIME
16 - ./docker-stack-wait.sh -r $DEPLOY_NAME
17 only:
18 - merge_requests
DEPLOY_DOMAIN
是由 elct9620/ruby-gitlab-ci 是先定義好的,如果要直接使用請自行調整
我們只需要將 name
命名為 review/$CI_COMMIT_REF_NAME
就會自動的被 GitLab 判定為不同的部署,同時還可以利用 review/
的結構讓 GitLab 已資料夾的形式呈現,把 Review Apps 合成一個群組避免畫面呈現太過複雜。
跟之前不同的地方在於,我們對 environment
設定加入了 on_stop
的設定,讓我們可以在 GitLab 認為需要停止的情況(手動點選、合併後)自動的執行對應的任務。
1review:stop:
2 image: docker:stable
3 stage: deploy
4 environment:
5 name: review/$CI_COMMIT_REF_NAME
6 action: stop
7 script:
8 - docker stack rm $DEPLOY_NAME
9 only:
10 - merge_requests
11 when: manual
對應的 review:stop
任務我們使用 when: manual
限定只在「手動操作」的狀況下才會執行,避免部署後馬上就被停止。
在 environment
的設定中,我們也另外指定了 action: stop
表示這是一個「停止」的動作,最後只需要用同樣的方式利用 GitLab Runner 操作 Docker Swarm 執行 docker stack rm
命令,用相同的命令移除掉像是 91-review-new-function
這樣登記在 Docker Swarm 的服務即可。
在這裡我們應用的關鍵技巧,主要在於像是 DEPLOY_NAME
這類環境變數,需要挑選適合的 GitLab 環境變數去組合,來讓 Docker Swarm 和 GitLab 都能順利辨識出來。
用 GitLab CI 來預載資料
基於我們的 GitLab CI 是可以直接操作 Docker Swarm 的關係,我們其實是能夠直接在 Docker Swarm 執行任意的容器,利用這樣的特性,我們就可以「刻意的」將在 Docker Swarm 執行一些一次性的命令來達到這個效果。
首先,我們原本的 Docker Swarm 是使用自動產生的 Overlay 網路,我們是無法讓其他容器連線到上面,因此需要修改 Docker Compose 的設定,手動的定義網路。
1services:
2 # ...
3 postgres:
4 # ...
5 networks: # 資料庫只限內部存取
6 - net
7
8networks:
9 net:
10 driver: overlay
11 attachable: true # 可以被附加到其他容器上
12 traefik-public:
13 external: true
如此一來,我們就可以使用 docker run --network 91-production_net
這樣的選項來將容器網路暫時性的串聯起來,因此我們就可以製作類似這樣的 GitLab CI 任務。
1# ...
2seed:
3 image: docker:stable
4 before_script:
5 - mkdir -p $HOME/.docker
6 - echo "$CI_JOB_TOKEN" | docker login -u $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
7 script:
8 - docker run --rm -t --network ${DEPLOY_NAME}_net
9 -e DATABASE_URL=postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@postgres/$POSTGRES_DB
10 registry.example.com/myapp:${VERSION:-latest}
11 rake db:seed
12 needs:
13 - review:deploy
如此一來,就可以產生一個暫時型的容器使用我們剛剛部署的 Review Apps 並且連接到對應的資料庫,執行我們想要的 rake db:seed
命令來預先載入一些測試用的資料。
然而,這個方法還是有一定程度的限制,像是沒辦法跟 Docker Compose 一樣預先設定好各種環境變數,而這個可能會影響執行命令的結果,因此並不是一個萬能的解決方案。
Docker Swarm 沒有類似 Kubernetes 的
init container
機制可以來處理這些事情,也因此我們可以評估改為使用像是 Sidekiq 之類的方式在背景進行處理。
如果想在第一時間收到更新,歡迎訂閱弦而時習之在這系列文章更新時收到通知,如果有希望了解的知識,可以利用Rails 部署實踐回饋表單告訴我。
如果對這篇文章有興趣,可以透過以下連結繼續閱讀這系列的其他文章。
- Rails 部署實踐 - 補上 Rails 教學缺少的一塊
- Rails 部署實踐 - 以容器部署 Rails 的方案
- Rails 部署實踐 - 部署前置準備
- Rails 部署實踐 - 容器化 Rails 專案概述
- Rails 部署實踐 - 上傳容器鏡像
- Rails 部署實踐 - 伺服器搭建
- Rails 部署實踐 - 撰寫 Docker Compose
- Rails 部署實踐 - 使用 HTTPS 協定加密連線
- Rails 部署實踐 - 健康檢查
- Rails 部署實踐 - 滾動更新
- Rails 實踐部署 - 使用 Alpine 製作容器鏡像
- Rails 部署實踐 - 容器化的 Bundler 最佳設定
- Rails 部署實踐 - 多階段建置
- Rails 部署實踐 - 素材預先編譯
- Rails 部署實踐 - 容器進入點
- Rails 部署實踐 - 容器相關工具
- Rails 部署實踐 - 持續部署
- Rails 部署實踐 - 使用 GitLab CI 自動化建置
- Rails 部署實踐 - 使用 GitHub Actions 自動化建置
- Rails 部署實踐 - 使用 Watchtower 自動更新
- Rails 部署實踐 - Docker Swarm 與 Docker Compose
- Rails 部署實踐 - Docker Swarm 安裝與設定
- Rails 部署實踐 - 部署到 Docker Swarm
- Rails 部署實踐 - 整合 GitLab CI 自動部署
- Rails 部署實踐 - 使用 GitLab 的 Review Apps 機制
- Rails 部署實踐 - 部署不是終點