Node.js應用的持續部署
翻譯前
翻譯自:https://blog.risingstack.com/continuous-deployment-of-node-js-applications/
正文
持續部署是...
不,讓我們退一步來看持續集成、持續交付、持續部署的區別。
持續集成
持續集成是一天多次/持續地把開發的成果和主分支合并到一起的過程。有助于:
- 盡早捕獲異常
- 防止「集成地獄」
大部分工作是靠自動測試完成的。
持續交付
持續交付是只將代碼部署到一個可以被QA團隊或者客戶審查的環境。當改動被批準,他們才可以被部署到生產環境。
持續部署
你可以把持續部署看成是持續交付的下一步。在這一步,傳遞到自動測試的變更會被自動地部署到生產環境。持續部署非常依賴于某些基礎設施,這些基礎設施將測試、集成、部署新功能的過程自動化。
在這篇文章里,我們將梳理這些自動化步驟、講述大部分的原則。
一個簡化的持續部署工作流如下:
從源代碼控制到生產環境
假設我們要做這樣一件事,當一個新的功能將要被開發出來并且我們想看到它運行在生產環境。我們要看一下這個代碼變更從提交到在生產環境運行起來的全部聲明周期。
一切從一次提交開始
每次將代碼提交到主分支,都應該觸發一個包含測試的新構建。但是當添加新的功能時,你不會想在生產環境中看到半成品的功能。
功能開關
為了解決這個問題,持續部署的創建一般伴隨著功能開關。功能開關是指一個切換功能,可以允許開發者發布包含未完成內容的產品版本。這些未完成的功能會被生產環境中的開關隱藏起來。
// 用一個偽造的例子來講述風格切換
// https://www.npmjs.org/package/feature-toggles
var featureToggles = require('feature-toggles');
// 定義切換
var toggles = {
foo: true,
bar: false
};
// 把它們加載到模塊中
featureToggles.load(toggles);
// 檢查某個功能是否被開啟
if (featureToggles.isFeatureEnabled('foo')) {
// do something
}
當這個功能已經完成,這個功能開關可以被移除。
持續部署工具
但是在哪觸發一個新的構建呢?針對這個例子,你需要一個持續集成工具。已經有很多現成的工具,如 Jenkins、Travis、Codeship、Strider,其中Strider是用Node.js編寫的,Jenkins和Strider是開源的,可以在你的基礎設施上進行操作。
當前,我們在閉源項目使用Strider,開源項目使用Travis。
上述每個工具都支持提交鉤子,所以現在就創建一個吧!如此一來,你的持續集成工具不用像平常一樣拉取代碼。
提交時構建
當你選的工具收到了一個新的提交通知,它會啟動一個新的構建。構建可以包含很多步驟,有些可以同時運行。說到Node.js應用,將經歷如下步驟:
- 從NPM安裝依賴(公共的或者私有的)
- 運行單元測試
- 構建靜態資源,如css和JavaScript
- 運行集成測試和端到端的測試
- 創建發布包(把node_modules文件夾也打包進去,這樣部署的時候就不用依賴NPM了)
自動化測試
自動化測試是構建步驟中最關鍵的部分。
你的模塊必須被單元測試覆蓋,你也需要有集成測試來檢查各部分能否協同工作。對于這類測試,你可以使用mocha/tap/Jasmine和斷言庫,如chai.
基于你構建的應用是包含前端的還是只有API,你可以選擇不同的端到端測試工具。
如果你的程序沒有前端頁面,只有API,你可以用hippie或supertest做端到端的測試。
當開發包含前端頁面的程序時,你還可以對用戶界面進行測試。使用Protractor來測試AngularJS程序或者使用Nightwatch。為了確保程序在所有支持的瀏覽器中運行,需要在Selenium集群上運行端到端測試。也可以使用Sauce Labs或者 Browserstack 服務。
我要不斷地強調這件事:沒有足夠的測試覆蓋率,持續集成將導致一系列的生產問題。
創建發布包
如果所有的測試都已經通過,那么就可以從構建打包了。發布包必須包含運行應用程序的每個文件。所以你的成產服務不用再進行重新構建。
一個簡單的tar filename.tar *
可以做這件事。然后確保文件位置可以被生產服務器訪問,這樣你才能獲取到它。如AWS的S3或者任何的其它存儲。
部署
由于我們剛創建的發布包包含程序所有的靜態資源,我們只需要進行如下操作:
- 下載最新發布包
- 解壓到一個新的文件夾
- 更新symlink,讓它指向剛創建的文件夾
- 重啟Node應用
毫無疑問,這些步驟必須自動化,無需任何手動操作。像Ansible、Chef或者Puppet可以幫忙。
回滾
如果發生了錯誤,早晚會發生。確保有一個回滾的腳本。最快、最簡單的方式是將symlink指向到前一個構建并重啟node應用。
推薦閱讀:
具有可操作性的運行Node.js的建議。
文章列表