在之前的文章中,我們探討了如何使用GitLab CI/CD自動部署到Heroku。那個設置會在我們每次將代碼推送到main
分支時,將應用部署到生產環境。
在本文中,我們將考慮一種稍微複雜一點的方法:如果我們有多個環境會怎麼樣?大多數工程組織至少使用三個環境:本地開發環境、預發環境和生產環境。
此外,一些工程團隊遵循Gitflow分支策略,他們有dev
分支和main
分支。這種策略目前已經不被推崇,並被主幹基於開發取代,但仍然不難發現有些組織仍在遵循這種做法。
今天,我們將了解如何配置 GitLab CI/CD,以便當我們向 dev
分支推送時,將我們的應用部署到預發環境;當我們向 main
分支推送時,將我們的應用部署到生產環境。
開始使用
在開始之前,我們需要兩樣東西:一個 Heroku 帳戶和一個 GitLab 帳戶。
Heroku 是一個非常好的應用托管和部署平台。作為一個平台即服務(PaaS),Heroku 讓您可以專注於構建酷炫的事物,同時抽象掉大部分基礎設施的复杂性。您可以在此處創建一個 Heroku 帳戶。
GitLab 是存放代碼的好地方。除了僅僅作為一個源代碼管理工具之外,GitLab 還提供了原生 CI/CD 功能,這樣您可以設定管道來測試和部署代碼,而不需要其他第三方工具。您可以在此處創建一個 GitLab 帳戶。
本文中展示的演示應用使用了 GitLab 和 Heroku。您可以在此處找到 GitLab 倉庫中的所有代碼。
在本地運行我們的應用
您可以通過克隆倉庫、安裝依賴和運行啟動命令在本地運行應用。在您的終端中,執行以下操作:
$ git clone https://gitlab.com/tylerhawkins1/heroku-gitflow-staging-production-gitlab-cicd-demo.git $ cd heroku-gitflow-staging-production-gitlab-cicd-demo $ npm install $ npm start
啟動應用後,在您的瀏覽器中訪問這個本地主機,您將看到應用在本地運行:
演示 Heroku 應用
將我們的應用部署到 Heroku
現在應用已在本地運行,讓我們將其部署到 Heroku,這樣您就可以在任何地方訪問,而不僅僅是在您的電腦上。
記住,我們將把您的應用部署到預發環境和生產環境。這意味著我們將基於同一個 GitLab 倉庫創建兩個 Heroku 應用。
如果您在電腦上還未安裝Heroku CLI,在繼續操作之前,您需要安裝它。
安裝完 Heroku CLI 之後,從終端運行以下命令以切換到main
分支,創建新的生產 Heroku 應用,將其部署到您的生產環境,並在瀏覽器中打開:
$ git checkout main $ heroku create heroku-gitlab-ci-cd-production --remote heroku-production $ git push heroku-production main $ heroku open --remote heroku-production
如此,您應該會看到同樣的應用,但這次是運行在 Heroku URL 上,而不是本地主機。做得好 — 您已經將您的 Heroku 應用部署到生產環境!
但是,我們還沒有完成。我們還需要配置和部署您的預發應用。為此,運行以下類似的命令集:
$ git checkout dev $ heroku create heroku-gitlab-ci-cd-staging --remote heroku-staging $ git push heroku-staging main $ heroku open --remote heroku-staging
現在您將再次部署相同的應用程式,但這次是部署到一個不同的URL,該URL將作為您的預發環境。現在您的兩個環境都已經配置好了!
注意生產應用程式和預發應用程式的命令之間的差異和相似之處:
- 生產應用程式使用
main
分支,而預發應用程式使用dev
分支。 - 生產應用程式名為
heroku-gitlab-ci-cd-production
,預發應用程式名為heroku-gitlab-ci-cd-staging
。 - 生產應用程式的git遠端名為
heroku-production
,預發應用程式的git遠端名為heroku-staging
。 - 生產應用程式和預發應用程式的git遠端都使用
main
分支,因為Heroku只有在代碼被推送到其主分支時才會部署應用程式。
請記住,這個 main
分支與您的 main
和dev
分支是不同的。您這裡推送的main
分支是您git遠端上的main
分支——在這個例子中,是Heroku。
當您在本地main
分支上並運行git push heroku-production main
時,您正在將您的main
分支推送到Heroku生產應用程序的main
分支。當您在本地dev
分支上並運行git push heroku-staging main
時,您正在將您的dev
分支推送到Heroku預發應用程序的main
分支。
對我們的應用程序進行更改
現在我們的Heroku應用程序已經運行起來,如果我們想要進行一些更改怎麼辦?遵循Gitflow分支策略的大致近似,我們可以這樣做:
- 切換到
dev
分支 - 對代碼進行更改
- 添加、提交並將這些更改推送到
dev
分支 - 通過運行
git push heroku-staging main
將這些更改部署到預發Heroku應用程序 - 切換到
main
分支 - 將
dev
分支合並到main
分支 - 通過運行
git push heroku-production main
將這些更改部署到生產Heroku應用程序
(如果我們真正遵循Gitflow,我們會創建一個特性分支以合並到dev
,以及一個發布分支以合並到main
,但為了簡化我們省略了這些步驟。)
現在,如果我們能夠自動部署到我們的任一環境,而不是每次都手動部署,那不是很好嗎?
這就是GitLab CI/CD發揮作用的地方。
持續整合/持續部署
持續整合(CI)主要是關於頻繁提交並始終保持构建的良好狀態。通常,您會通過在CI管道中運行檢查來驗證构建是否處於良好狀態。這些檢查可能包括語法檢查器、單元測試和/或端到端測試。
持續部署(CD)主要是關於頻繁部署。如果CI管道中的檢查通過,則會部署构建。如果CI管道中的檢查失敗,則不會部署构建。
使用GitLab CI/CD,我們可以配置CI管道精確地做到這一點——運行我們的測試,然後如果所有測試都通過,將我們的應用部署到Heroku。對於我們的設置最重要的是,我們可以在CI管道中配置規則以指定應用應部署到哪裡。
配置GitLab CI/CD
我們可以使用.gitlab-ci.yml
文件在GitLab中以程序化的方式創建CI管道。我們的文件長這樣:
image: node:20.10.0
cache:
paths:
- node_modules/
before_script:
- node -v
- npm install
stages:
- test
- deploy
unit-test-job:
stage: test
script:
- npm test
deploy-job:
stage: deploy
variables:
HEROKU_APP_NAME: $HEROKU_APP_NAME_PRODUCTION
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
variables:
HEROKU_APP_NAME: $HEROKU_APP_NAME_PRODUCTION
- if: $CI_COMMIT_REF_NAME =~ /dev/
variables:
HEROKU_APP_NAME: $HEROKU_APP_NAME_STAGING
script:
- apt-get update -yq
- apt-get install -y ruby-dev
- gem install dpl
- dpl --provider=heroku --app=$HEROKU_APP_NAME --api-key=$HEROKU_API_KEY
GitLab CI管道由階段和任務組成。每個階段可以包含一個或多個任務。在我們的管道中,我們有兩個階段:test
和deploy
。在test
階段,我們在unit-test-job
中運行我們的單元測試。在deploy
階段,我們在deploy-job
中將應用部署到Heroku。
我們只有在前一個階段的所有任務都通過後才能進入下一個階段。這意味著如果單元測試失敗,則不會部署應用,這是好事!我們不會想要在應用處於不良狀態時部署它。
您會發現deploy
階段有一個rules
部分,其中包含一些條件邏輯。這是我們指定應用程序應該部署到哪個環境的地方。如果我們在main
分支上,那麼我們將部署我們的生產應用程序。如果我們在dev
分支上,那麼我們將部署我們的預發應用程序。
您也會注意到deploy
階段引用了幾個變量,名為$HEROKU_APP_NAME_PRODUCTION
、$HEROKU_APP_NAME_STAGING
和$HEROKU_API_KEY
。這些是存儲為GitLab中的CI/CD變量。
如果您在自己的GitLab賬戶中設置這項,您需要先在您的Heroku賬戶中找到API密钥。在您的Heroku賬戶設置中,應該有一個用於API密钥的部分。如果您還沒有生成API密钥,現在請生成一個。

接下來,在您的GitLab專案中,單擊設置 > CI/CD > 變量。展開該部分並添加三個新的變量:
- 變量
$HEROKU_API_KEY
的值將是您Heroku賬戶中的API密钥。 - 變量
$HEROKU_APP_NAME_PRODUCTION
的值將是您的生產Heroku應用程序的名稱。我的生產應用程序的名稱是heroku-gitlab-ci-cd-production
,但由於Heroku應用程序名稱是全球唯一的,您的將會有所不同。

$HEROKU_APP_NAME_STAGING
的值將是您預置 Heroku 應用程序的名稱。我的預置應用程序的名稱是 heroku-gitlab-ci-cd-staging
。再一次,由於 Heroku 應用程序名稱是全宇宙獨一的,所以您的會有所不同。
如此一來,您的 GitLab CI 管道已經準備就緒!讓我們來測試一下。
讓我們切換到 dev
分支,並對我們應用程序中的代碼進行更改。我對標題文字進行了一個簡單的更改,並在 UI 的文字中添加了幾行新內容。您可以在您的代碼中進行類似的更改。
現在,添加、提交並將這個更改推送至 dev
分支。這將啟動 GitLab CI 管道。您可以在 GitLab 內查看管道,並實時看到進度。

如果一切順利,您應該會看到 test
和 deploy
階段都已通過。現在,請查看您在預置環境 URL 的托管 Heroku 應用程序。GitLab CI 管道已為您部署應用程序,所以您現在會在預置環境中看到您的更改已經生效!

有了預置環境,您現在就有了在一個托管環境中手動測試代碼的絕佳場所。這也是讓 QA 測試員或產品經理在將更改推送到生產環境之前驗證更改的完美位置。
現在,請查看您的生產應用程序 URL。您會發現它仍然顯示舊的 UI,沒有最新的更改。這是因為 GitLab CI 管道只將更改部署到了預置環境,而不是生產環境。
我們已經驗證代碼在我們的預發環境中運行良好,所以讓我們將其提升到生產環境。
將我們的Heroku應用部署到生產環境
讓我們檢查一下main
分支,然後將dev
分支合並到你的main
分支。你可以通過拉取請求來完成這個操作,或者運行git merge dev
然後git push
。
這將再次啟動GitLab CI流水線,但這次它將準備部署你的生產應用。

你也可以在GitLab的流水線頁面上查看所有流水線運行,以看到你的dev
和main
分支的各種構建:

當流水線完成後,訪問你的生產Heroku應用的URL。現在應該可以看到你的更改也已經部署到生產環境。做得很好!
結論
A good CI pipeline allows you to ship new features quickly and confidently without manually managing the deployment process. Having multiple environments configured for local development, staging, and production gives you more control over where and when code is released.
Heroku和GitLab CI/CD讓你可以自動化所有這些,讓你的DevOps流程變得輕鬆!
Source:
https://dzone.com/articles/deploying-heroku-apps-to-staging-and-production