iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
Vibe Coding

夢幻甜品師闖工程世界:Vibe Coding vs 專業開發的 0→1 冒險攻略系列 第 27

Day27|網站終於有自己的連結了,這樣就算部署完成了嗎?從 Deployment 看懂 Environment 與 CI/CD

  • 分享至 

  • xImage
  •  

昨天,我們把候選時段演算法一路拆到最後,核心開發也走到了尾聲。

接下來,這些原本只在開發者電腦裡運作的功能,終於要真正走到使用者面前了。

一開始,我對 Deployment(部署)的理解其實很模糊。

只知道部署完成之後,網站就會有自己的連結。原本只能在我的電腦上跑的東西,也就終於可以分享給朋友們一起玩玩看了!

那時候,我覺得這件事很神奇,卻又不太明白它到底是怎麼發生的。

明明還是同一份 Code,為什麼離開 localhost 之後,就能從「只有我看得到」,變成「任何拿到連結的人都能使用」?

今天就從這個問題開始,進入「實際運行&優化」這一關的第一步,看看 Deployment 到底把一個網站帶去了哪裡吧~


網站有了連結,背後到底發生了什麼?

Deployment(部署),可以先理解成:

把準備好的應用程式版本,送進指定的執行環境,讓它能在那裡建置、啟動並提供服務。

所以 Deployment 不只是把 Source Code 上傳到網路。

一份應用程式真的要運作,還會依賴:

  • Runtime(執行環境)
  • Dependencies(套件依賴)
  • Environment Variables(環境變數)
  • Database(資料庫)
  • Domain 與 Network Configuration(網域與網路設定)
  • External Services(外部服務)

例如在自己的電腦開發時,我們可能會在 Terminal 輸入:

npm run dev

接著用瀏覽器打開:

http://localhost:5173

網站就能正常運作。

localhost 指向的是:

目前正在使用的這台電腦。

朋友即使拿到這串網址,也只會連回他自己的電腦,不會自動跑進我的電腦看網站。我們也不能期待自己的電腦永遠開著 Terminal,替所有使用者維持服務。

因此,Deployment 真正要送出去的,不只是某個資料夾裡的 Code。

而是:

一個能在目標環境裡正確建置、啟動並持續提供服務的版本。

不過,這裡所說的「目標環境」到底是什麼?

明明還是同一份 Code,為什麼只是換個地方執行,就可能得到不一樣的結果?


Code 換了地方,周圍的條件也跟著變了

Environment(環境),指的是:

程式實際執行時,周圍所有會影響它運作的條件。

開發流程裡常見的 Environment,可以先分成三種:

Environment 主要用途
Development(開發環境) 開發者平常寫 Code、除錯、測試功能的地方
Testing / Staging(測試/預備環境) 正式上線前,用來執行測試,或在接近正式環境的條件下驗證
Production(正式環境) 真正提供給使用者使用的環境

不同團隊不一定都有完全相同的三套環境。

有些小型專案只有 Development 和 Production;有些團隊則會把 Testing、Staging、UAT 分得更細。

重點不在名稱一定要怎麼取,而是每個 Environment 負責哪一階段的驗證。

以 BuJo 來說,Code 合併進 dev 後,會先部署到測試環境;確認穩定之後,才繼續合併到 main,進入正式環境。

這裡也要分清楚:

devmain 是 Branch,不是 Environment。

只是 BuJo 把不同 Branch 的變化,設定成會觸發不同環境的部署。

因此,測試環境的價值不只是多準備一個網址。

它真正多出來的是:

一個讓部署後才會出現的問題,先被看見的地方。


Code 可以過去,設定不會自己跟上

很多設定在本機早就存在,所以平常開發時不太會注意。

但 Code 被 Push 到 GitHub,不代表這些條件也會自動出現在新的 Environment 裡。

因此部署時,通常還要一起確認:

要確認什麼 本機正常,部署後卻可能出問題的原因
Environment Variables .env 通常不會跟著 Git 上傳,部署平台需要另外設定
Dependencies 目標環境必須知道要安裝哪些 Package
Build / Start Command 平台要知道怎麼建置,以及怎麼啟動應用程式
Runtime / Version Node.js、作業系統、Timezone 等執行條件可能不同
URL / Domain localhost 要換成正式的 Frontend、Backend 與 Callback URL
Database Migration Code 已經使用新 Schema,Database 卻可能還停在舊版本
External Services OAuth、Storage、Email 等服務也可能需要正式網址與 Credential

例如 Backend 本機可能已經設定好:

DATABASE_URL
JWT_SECRET
GOOGLE_CLIENT_ID
GOOGLE_CLIENT_SECRET

但 Password、Secret、API Key 這類敏感資訊,本來就不應該直接寫進 Code,或跟著 Commit 進 Git。

所以部署到 Render、Vercel 或其他平台時,還要在對應的 Environment 裡另外設定。

這裡還有一個容易忽略的差異:

Environment Variable 是在 Build Time 還是 Runtime 被讀取?

  • Build Time(建置階段):建立應用程式產物時,就把設定值寫進去
  • Runtime(執行階段):程式真正啟動或處理 Request 時,才讀取設定

例如 Vite 的 VITE_ Environment Variables,會在 Build Time 進入前端產物,最後也能被瀏覽器讀到。

因此:

  • VITE_ 變數不能拿來存放 Secret
  • Build 完才修改變數,原本的前端產物不會跟著改變
  • 要讓新值生效,通常還需要重新 Build

所以 Deployment 真正要確認的,不只是:

Code 有沒有成功上傳?

而是 Code 周圍那整套執行條件,有沒有一起準備好。


這麼多檢查,總不能每次都靠人記得吧?

假設每次準備合併 Code 前,都要由工程師自己記得:

  • 執行 Lint
  • 執行 Test
  • 確認 Build 成功
  • 檢查必要設定
  • 確認沒有破壞原本功能

一兩次可能還記得。

但當團隊成員和修改次數變多,只靠每個人手動執行,就很容易少做其中一步。

所以開發流程會把適合重複執行的檢查自動化。

這就來到:

CI(Continuous Integration,持續整合)。

CI 的核心概念是:

開發者持續把修改整合進共同的 Codebase,並透過自動化檢查,盡早發現整合問題。

常見的 CI 檢查包括:

檢查 主要確認什麼
Lint Code 有沒有違反設定好的規則
Unit Test 單一函式或模組的行為是否正確
Integration Test 多個元件或模組接在一起後是否正常
Build 專案能不能成功產生可部署的版本
Type Check 型別是否符合規則
Security Scan 是否出現已知的 Dependency 或程式碼風險

不同專案不一定會把這些檢查全部放進 CI。

重點是根據專案真正需要把關的事情,挑出適合自動執行的項目,再把它們固定進同一套流程。

所以 CI 不等於 Test。

Test 很重要,但它只是 CI Pipeline 裡可能出現的一個關卡。

機器檢查完了,還是得有人看

CI 和 Code Review 看的是不同問題。

檢查方式 適合處理的問題
CI 自動檢查 Test 有沒有通過、格式有沒有違規、專案能不能 Build
Code Review 設計是否合理、命名是否清楚、需求有沒有漏掉、後續是否容易維護

CI 擅長檢查那些可以被寫成明確規則、反覆自動執行的事情。

但它很難只靠一條規則判斷:

這個函式是不是承擔太多責任?
這個命名會不會讓下一個人誤解?
這個功能雖然能跑,但真的符合需求嗎?

因此自動化不是取代 Review,而是先把適合機器處理的部分交給機器。


檢查過關,下一站要去哪裡?

CI 後面經常接著看到 CD

不過 CD 可能代表兩個不同概念:

名稱 核心差異
Continuous Delivery(持續交付) 自動把版本準備到隨時可以發布的狀態,最後是否進入 Production 可以保留人工決定
Continuous Deployment(持續部署) 通過整套流程後,自動繼續部署到 Production

兩個名字很像,差異主要在最後進入 Production 前,是否還保留人工決定。

假設 Code 已經通過所有檢查:

  • Continuous Delivery 可能停在「版本已經準備好,等人決定是否發布」
  • Continuous Deployment 則會繼續把版本部署到 Production

因此大家說的 CI/CD Pipeline,可以理解成:

Code 從整合、自動檢查,一路走到可以交付或部署的整套流程。

Pipeline 不一定只有一種正確走法。

有些團隊會在最後保留人工核准,有些團隊則會在所有條件通過後自動部署;有些專案還會加入安全掃描、端對端測試或其他關卡。

真正需要先想清楚的不是「一定要自動到哪一步」,而是:

一份 Code 必須滿足哪些條件,才有資格前往下一個 Environment?


把該跑的關卡交給 GitHub Actions

GitHub Actions 是 GitHub 提供的 Workflow Automation(工作流程自動化)工具。

它可以設定:

當某個 Event 發生時,自動執行哪些 Job。

一份 GitHub Actions Workflow 裡,常會遇到幾個重要角色:

名稱 負責什麼
Event 什麼事情發生時啟動,例如 Push 或 Pull Request
Workflow 整套自動化流程
Job 一組要完成的工作,例如 Test 或 Build
Step Job 裡依序執行的單一步驟
Runner 實際執行 Workflow 的環境

放回 BuJo 的 CI,其中一個 Event 設定是:

on:
  pull_request:
    branches: [dev, main]

這段可以直接讀成:

當有人建立以 devmain 為目標的 Pull Request 時,啟動這套 Workflow。

接下來,Frontend 和 Backend 會分別執行自己需要的檢查:

專案 CI 主要步驟
Frontend 準備 Node.js → npm ci → Lint → Vitest → Build
Backend 準備 PostgreSQL 與 Environment Variables → npm ci → 套用 Prisma Migration → 產生 Prisma Client → Jest Test

這些檢查不是直接在我的 MacBook 裡執行。

GitHub Actions 會在 Runner 裡重新準備專案,再按照 Workflow 設定好的 Step 依序執行。

因此它不只是在確認:

「我的電腦現在跑得過 Test。」

也會進一步確認:

「這份專案放進 Workflow 指定的 Runner 後,還能不能重新完成安裝、建置和測試?」

這裡的 Runner 是執行 CI 檢查的環境,不等同於 BuJo 部署後使用的測試環境或 Production。

有 GitHub Actions,不等於整條路都自動了

CI/CD 是開發、檢查、交付與部署的流程概念。

GitHub Actions 則是可以拿來實作這些流程的工具之一。

就像 Test 是一種開發方法,Jest、Vitest 是執行 Test 的工具;CI/CD 是流程,而 GitHub Actions、GitLab CI/CD、Jenkins 則是能把流程自動化的工具。

GitHub Actions 可以只負責 CI:

  • Lint
  • Test
  • Build

也可以繼續負責 Deployment:

  • 建立部署產物
  • 上傳到 Hosting Platform
  • 部署到 Testing / Staging
  • 部署到 Production

實際做到哪裡,要看專案怎麼設定。

所以看到一個專案「有 GitHub Actions」,不能直接推論它已經完成整套 CI/CD。

還是要打開 Workflow,看看裡面究竟設定了哪些 Event、Job 和 Step。


Demo 前一天,時間突然差了 8 小時

BuJo 就曾經在 Demo 前一天,正面撞上一個由 Environment 差異造成的 Bug。

建立活動後,本機顯示的時間完全正常;部署到測試環境,同一個功能卻固定差了 8 小時。

當時大家真的超崩潰啊!!!

隔天就要 Demo 了,明明已經在本機再三確認過沒有問題,怎麼一部署,時間還是整整差了 8 小時?

更讓人困惑的是,Code 明明是同一份,問題也不在活動本身的業務邏輯,而是程式處理時間時依賴了系統時區。

本機使用台北時區,部署環境卻有自己的預設值。

同一段時間處理邏輯進入不同的 Environment,因而得到了不同的結果。

後來,Backend 明確設定:

TZ=Asia/Taipei

測試與 CI 使用的 Environment 也一起固定,避免每個地方各自依賴不同的預設時區。

這個 Bug 最直接地證明了一件事:

本機測試正常,只能證明 Code 在目前的 Development Environment 正常。

換到另一套執行條件後,還是要在那個 Environment 裡重新驗證。


AI 幫忙把網站放上去了,然後呢?

那麼今天的主題——Deployment(部署),在 Vibe Coding 和專業開發上的差異在哪呢?

現在請 AI 建立 CI Workflow、設定部署平台,甚至一步一步把網站 Deploy 出去,都可以很快。

輸入幾個指令後,原本只存在本機的網站也真的有了網址。

但如果需求只寫成:

「幫我把網站部署上去。」

最後的驗收就很容易停在:

「網址打得開。」

Environment Variables、Database Migration、OAuth Callback URL,或 Runtime 的差異,仍然可能沒有被檢查。

  • Vibe Coding:如果只用「幫我把網站部署上去」作為 Prompt 和驗收條件,流程很容易停在「網址打得開」。
  • 專業開發:先定義 Code 要通過哪些檢查、帶著哪些設定、進入哪些 Environment,再驗證整套系統能不能正常運作。

差別不在 AI 能不能完成 Deployment。

而是使用 AI 時,有沒有把 Code 以外的執行條件,也一起放進「成功部署」的標準裡。


那張終於能分享的連結,背後原來有一整條路

一開始,我最期待 Deployment,是因為網站終於有了自己的連結,可以真的傳給朋友使用。

現在再看那張連結,我還是覺得這件事很神奇,只是終於知道,它背後不只是按下一次 Deploy。

Code 離開本機之後,會進入另一套 Runtime、Database、Domain 與 Configuration;而 CI/CD 的價值,就是把沿途重要的檢查與部署步驟固定下來,讓它們不必每一次都靠人重新記得。

那張可以分享出去的連結,不只是網站被放上網路的證明,也代表這份 Code 已經走過一條能被檢查、也能反覆執行的路。

網站終於真的走到了使用者面前。

接下來,當使用者和資料越來越多,原本一下就能查到的內容,會不會開始變慢?

下一篇,就回到 Day6 曾經先看過一眼的 Index(索引),看看它到底怎麼影響 Database Query 的效能。


上一篇
Day26|大家都有空,但到底哪個時段最好?從候選時段演算法看懂時間怎麼切、算再合回
下一篇
Day28|查得到就夠了嗎?從 Index Design 看懂 Query 怎麼決定索引怎麼加
系列文
夢幻甜品師闖工程世界:Vibe Coding vs 專業開發的 0→1 冒險攻略30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言