想像一下國際貿易。以前搬運貨物,要把各種形狀的木箱、布袋塞進船艙,非常麻煩且容易損壞。後來發明了「標準貨櫃 (Container)」,不管裡面裝的是汽車還是蘋果,到了港口都能用標準的吊車直接放上卡車。
Docker 就是軟體界的「標準貨櫃」。
它會把你寫好的程式碼、Node.js 執行環境、依賴套件全部打包成一個名為 映像檔 (Image) 的包裹。這個包裹拿到任何安裝了 Docker 的電腦(Windows, Mac, Linux)上,都能保證 100% 跑出一樣的結果。
要打包貨櫃,我們需要寫一張「打包清單」,這張清單就叫做 Dockerfile(沒有副檔名)。
在你的 Express 專案根目錄下建立這個檔案,並填入以下內容:
# 1. 指定基底映像檔 (我們需要一個內建 Node.js 20 版本的輕量級 Linux 環境)
FROM node:20-alpine
# 2. 設定容器內的工作目錄 (把後續的操作都放在這個資料夾下)
WORKDIR /usr/src/app
# 3. 先複製 package.json 和 package-lock.json
# (先做這步是為了利用 Docker 的快取機制,只要套件沒變,就不用每次重新 npm install)
COPY package*.json ./
# 4. 安裝專案依賴
RUN npm install
# 5. 複製專案剩餘的所有原始碼到容器內
COPY . .
# 6. 宣告容器會對外開放的 Port (對應你 app.js 裡的 Port)
EXPOSE 3000
# 7. 定義容器啟動時執行的預設指令
CMD ["node", "app.js"]
打開終端機,確保你已經在電腦上安裝了 Docker Desktop 並啟動它。
步驟 A:建置映像檔 (Build Image)
# -t 用來幫這個映像檔取名 (例如 my-express-api),最後面的 . 代表目前的資料夾
docker build -t my-express-api .
步驟 B:執行容器 (Run Container)
# -p 3000:3000 代表將你電腦(主機)的 Port 3000 映射到容器內的 Port 3000
# -d 代表在背景執行
docker run -p 3000:3000 -d my-express-api
現在,打開瀏覽器輸入 http://localhost:3000,你的 API 已經在完全隔離的貨櫃中完美運行了!
實務上,我們的專案不只有 Node.js,可能還包含了昨天學的 Redis,或是 PostgreSQL 資料庫。甚至當專案變大時,我們還會需要管理包含本地套件快取機制與 Ollama 的離線 AI 開發工作流程。這時候不可能手動一個個去打 docker run 指令。
Docker Compose 允許我們用一份 YAML 檔定義多個容器的協作關係。
在專案根目錄建立 docker-compose.yml:
version: '3.8'
services:
api:
build: . # 告訴 Compose 去找當前目錄的 Dockerfile 來建置
ports:
- "3000:3000"
environment:
- REDIS_URL=redis://redis-cache:6379 # 設定環境變數指向下方的 redis 服務
depends_on:
- redis-cache # 確保 Redis 先啟動,API 才啟動
redis-cache:
image: redis:alpine # 直接從官方拉取 Redis 映像檔
ports:
- "6379:6379"
只要一行指令:docker-compose up -d,Node.js 加上 Redis 就會自動組裝完畢並互相連線,這就是現代化開發的終極浪漫!