前一章已經選定目標系統使用的程式語言、框架、測試工具與建置工具。多人開始實作前,還要把這些選擇轉換成共同的開發環境。只有版本名稱留在文件中,仍可能因為安裝來源、預設設定、環境變數或操作順序不同,產生「只有特定環境可以執行」的問題。
一致的開發環境需要同時具備三項條件:
Git、遠端儲存庫與開發容器分別處理這三項工作中的版本紀錄、團隊共用及環境建立。
共同環境的範圍以會影響專案結果的項目為主。編輯器主題、快捷操作與其他不影響建置、測試、啟動或除錯結果的輔助工具,可以保留個人選擇。
可以按照下列範圍建立環境基準:
| 類別 | 需要記錄的內容 | 驗證方式 |
|---|---|---|
| 基礎執行環境 | 開發容器使用的基礎作業系統、映像檔及版本識別 | 建立後輸出實際版本,確認符合共同定義 |
| 程式語言與工具 | 語言執行環境、編譯器、套件管理工具、測試工具及建置工具版本 | 執行統一的版本確認指令 |
| 專案相依項目 | 套件資訊清單、鎖定檔案及安裝入口 | 從乾淨狀態安裝後執行建置與測試 |
| 建置目標 | 目標格式、必要參數及產生結果的位置 | 使用共同指令產生可以比較的結果 |
| 環境設定 | 必要欄位、非敏感預設值及設定範本 | 缺少必要欄位時停止啟動並說明原因 |
| 其他相依項目 | 實際需要的項目、版本、啟動順序及初始狀態 | 確認各項目可以啟動、檢查及重設 |
容器外仍需要能建立開發容器的工具。專案應該記錄支援的容器執行工具及開發工具版本,讓成員知道開始前要具備哪些條件。開發容器固定的是容器內的工具與執行環境,無法自動消除容器外工具之間的所有差異。
環境是否一致,最後要由結果判斷。成員從相同 Git 版本開始,按照同一份文件建立環境,再執行相同的建置與測試指令。如果實際版本符合定義,結果也符合共同驗收條件,這套環境才可以作為團隊基準。
Git 可以讓原始碼與環境設定維持相同版本。當程式改用新的語言執行環境或建置工具時,對應的開發容器設定、初始化指令及操作文件可以在同一項變更中更新。之後只要取得指定提交,就能找到當時使用的完整環境定義。
適合納入 Git 的內容包括:
| 內容 | 用途 |
|---|---|
.devcontainer/devcontainer.json |
定義開發容器的建立方式、工作目錄、共同工具與生命週期指令 |
Dockerfile |
在現有映像檔上安裝專案需要的工具,或建立自訂映像檔 |
| Docker Compose 設定 | 在目標系統包含多個相依項目時,定義需要共同啟動的容器 |
| 開發工具設定 | 統一開發環境的擴充功能、程式碼檢查與格式化規則 |
| 初始化與驗證指令 | 安裝相依套件、建立初始狀態、執行建置及測試 |
| 設定範本 | 說明必要欄位及非敏感範例,不保存實際敏感內容 |
| 操作文件 | 記錄取得原始碼、建立環境、重設狀態及處理常見錯誤的步驟 |
提交紀錄也要說明環境變更的原因與影響範圍。只寫「更新環境」無法讓其他成員判斷需要重新建立哪些內容。較完整的紀錄應該指出變更的工具、原版本與新版本、需要重新執行的步驟,以及已完成的驗證。
Git 遠端儲存庫讓團隊取得及分享同一組提交。GitHub、GitLab 等平台在遠端儲存庫之外,還提供分支、變更審查與自動化驗證等協作功能。平台可以不同,團隊仍要指定共同儲存庫、主要分支及可採用的版本識別方式。
環境設定可以採用下列變更流程:
主要分支代表團隊目前共同採用的環境定義,提交識別則指出可以精確重現的版本。在通過驗證前,功能分支中的設定只作為候選內容。遠端儲存庫的寫入範圍也要按照工作責任設定,避免尚未確認的環境變更直接進入主要分支。
如果專案使用持續整合(Continuous Integration, CI),可以在環境設定變更時執行乾淨重建、建置與測試。GitHub Actions 工作流程與 GitLab CI/CD Pipeline都能按照儲存庫事件執行自動化工作。自動化流程應該呼叫和開發人員相同的專案指令,避免另外維護一套只有平台能執行的步驟。
開發容器規格使用 devcontainer.json 描述適合開發工作的容器環境。支援這項規格的工具可以讀取 .devcontainer/devcontainer.json,再按照設定取得映像檔、建立容器、掛載專案內容並執行生命週期指令。
開發容器可以使用三種主要建立方式:
| 建立方式 | 適用情況 | 需要固定的內容 |
|---|---|---|
| 直接使用映像檔 | 現有映像檔已經具備所需的語言環境與工具 | 映像檔來源、版本識別及必要設定 |
使用 Dockerfile |
需要安裝額外工具或調整映像檔內容 | 基礎映像檔、安裝指令及建置參數 |
| 搭配 Docker Compose | 目標系統需要共同啟動多個容器 | Compose 檔案、主要開發容器及其他相依項目 |
devcontainer.json 還可以設定工作目錄、環境變數、需要轉送的連接埠、掛載內容、容器內的執行身分及開發工具專用設定。共同設定只放入完成專案工作所需的內容。個人使用的外觀、快捷操作或非必要擴充功能,可以留在個人設定中,減少共同環境的建立時間與維護範圍。
映像檔需要使用明確版本。直接使用未固定內容的版本名稱,可能讓不同時間的重建取得不同結果。每次更新映像檔或工具版本時,都要在同一項變更中更新環境定義並重新驗證。
開發流程只需要單一開發容器時,可以直接使用映像檔或 Dockerfile。系統如果包含需要一起啟動的資料來源、處理程序或其他容器化相依項目,再使用 Compose 描述各項目的映像檔、設定、初始狀態與互動方式。
啟動順序只能說明先建立哪個項目,不能保證該項目已經可以處理後續工作。Docker Compose 啟動順序文件指出,容器進入執行狀態時,內部功能可能仍在初始化。相依項目需要提供健康狀態檢查或等效的可用性判斷。通過檢查後,才開始執行需要該項目的建置、測試或系統功能。
共同設定還要提供重設方式。測試產生的狀態如果一直保留,下一次執行可能因為前次內容而得到不同結果。可以按照系統實際情況提供建立固定初始狀態、清除測試結果及重新載入測試資料的指令。這些指令只能處理開發環境中的內容,不能連接或修改正式環境。
環境設定能被工具讀取,仍不代表整套開發流程已經可以重現。套件安裝、初始狀態建立、建置、測試與啟動如果依賴口頭說明,成員仍可能使用不同順序或參數。固定工作應該整理成專案指令,再由開發容器的生命週期設定或操作文件呼叫。
各階段可以分成下列責任:
| 階段 | 共同指令要完成的工作 |
|---|---|
| 建立映像檔 | 安裝固定版本的系統工具與語言執行環境 |
| 建立容器後 | 按照套件資訊清單與鎖定檔案安裝相依套件,建立必要的初始內容 |
| 每次啟動 | 檢查必要設定與相依項目是否可以使用 |
| 日常開發 | 提供一致的建置、測試、啟動與除錯入口 |
| 重設環境 | 清除開發期間產生的狀態,恢復已知初始條件 |
| 驗證環境 | 輸出實際版本並執行代表性的建置與測試 |
同一個指令重複執行時,應該能辨識已完成的工作,或安全地重新建立結果。缺少必要條件時要立即停止並指出缺少的項目,避免忽略錯誤後繼續產生難以比較的狀態。套件版本範圍、鎖定檔案及更新方式會在後續章節說明,本章只要求環境建立流程使用專案已經決定的安裝入口。
遠端儲存庫會把提交內容提供給具有讀取範圍的成員,也可能交給自動化流程執行。放入儲存庫前,需要先按照用途分類:
| 類型 | 保存方式 |
|---|---|
| 共同環境設定 | 納入 Git,跟隨原始碼一起審查及更新 |
| 設定範本 | 納入 Git,只保存欄位、格式與非敏感範例 |
| 個人設定 | 保留在個人環境,不影響共同建置與測試 |
| 敏感資訊 | 由開發環境或平台的安全設定機制提供,不寫入原始碼、映像檔或執行紀錄 |
| 產生內容 | 按照用途保存或排除,不讓前次結果影響乾淨重建 |
devcontainer.json、Dockerfile、Compose 設定與初始化指令都要接受相同檢查。Docker 建置敏感資訊文件指出,透過建置引數或環境變數提供敏感值,可能讓內容留在映像檔、後設資料或建置歷程中。共同設定只描述需要哪些值及如何提供,實際內容則透過適合的安全設定機制注入。錯誤訊息應該指出缺少的欄位,不顯示收到的值。
自動化流程也要遵守相同邊界。環境驗證應該盡量使用測試專用設定與可替代內容,並且避免把敏感資訊傳給來源尚未確認的變更。無法在缺少敏感資訊時執行的測試,需要另外限制執行時機與可讀取範圍。
原建立者可以使用開發容器,不足以證明其他成員能得到相同環境。正式採用前,應該從新的工作目錄執行一次完整流程:
驗證過程中出現的臨時操作都要回寫成設定、指令或文件。較好的確認方式是請未參與環境建立的成員按照文件操作。只要過程仍需要詢問特定人員、手動修正容器內容或沿用先前狀態,這套環境就還沒有成為團隊可以重建的共同基準。
如果遠端儲存庫平台已有自動化流程,可以在開發容器設定、映像檔定義或初始化指令變更時重跑相同驗證。開發人員與自動化流程使用相同入口,可以提早發現某個步驟仍依賴未提交的個人設定。
開發環境會跟著目標系統變更。語言執行環境、套件管理工具或測試工具升級時,應該建立獨立分支,記錄變更原因,重新建立環境並執行完整測試。一次調整過多版本會增加問題定位範圍,適合按照相依關係拆分變更,確認前一項穩定後再繼續。
環境文件也要隨設定更新。已經由共同指令處理的人工步驟應該從文件移除,停止使用的工具與擴充功能則要從開發容器刪除。新成員的建立紀錄、持續整合失敗及只能在特定環境重現的問題,都可以用來找出共同定義仍缺少的內容。
開發容器包含建置、測試、除錯及編輯工具,正式部署環境只需要目標系統執行所需的內容。如果正式部署也使用容器,可以共用經過確認的基礎映像檔或建置階段,再分別產生開發與部署用途的設定。正式部署採用其他形式時,仍要另外建立並驗證對應流程,不能直接把開發容器視為正式環境定義。
Dockerfile 或 Docker Compose 建立共同環境,其他相依項目則要按照目標系統的實際組成加入。