Node.js Docker:微服務時代的容器化部署基礎實戰

「在我這台電腦可以跑,為什麼部署到伺服器就壞了?」這是開發者最怕遇到的環境差異問題。Docker 透過容器化技術,將你的 Node.js 程式及其所需的環境(OS 層、Node 版本、套件依賴)打包成一個獨立的映像檔 (Image),確保從開發到生產環境的表現完全一致。

關鍵技術:撰寫高效的 Dockerfile

Dockerfile 是建立容器的劇本。為了讓映像檔更小、啟動更快,我們需要遵循一些最佳實務。

推薦:生產環境用的 Dockerfile (Multi-stage Build)

# 第一階段:編譯/安裝階段
FROM node:20-alpine AS builder
WORKDIR /app
# 利用 Docker 快取層:先複製 package.json,若沒變動就跳過 npm install
COPY package*.json ./
RUN npm install

# 第二階段:執行階段 (只保留必要的檔案,縮小體積)
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .

# 安全性建議:不要以 root 身份執行
USER node

EXPOSE 3000
CMD ["node", "app.js"]

核心操作指令

1. 建立映像檔 (Build)

# -t 指定名稱, . 代表當前目錄
docker build -t my-node-app .

2. 啟動容器 (Run)

# -p 外部埠口:內部埠口, -d 代表背景執行
docker run -d -p 8080:3000 --name web-server my-node-app

使用 Docker Compose 管理多容器

當你的 Node.js 需要連接 MongoDB 或 Redis 時,手動啟動多個容器很麻煩。Docker Compose 讓你用一個 YAML 檔就能啟動整組服務。

docker-compose.yml 範例:

services:
  web:
    build: .
    ports:
      - '3000:3000'
    depends_on:
      - db
  db:
    image: mongo:latest
    ports:
      - '27017:27017'

優化與安全性最佳實務

  1. 基礎映像檔:優先選用 alpine 版本,體積通常只有標準版的 1/10。
  2. .dockerignore:務必建立此檔案並排除 node_modules.git,否則會讓 Build 過程變得極慢且浪費磁碟空間。
  3. 環境變數:不要在 Dockerfile 中寫死密鑰,應透過 ENV 或 Docker Compose 的 environment 動態帶入。

總結

  1. Docker 解決了環境一致性的終極難題。
  2. Multi-stage Build 能幫你產出只有幾十 MB 的超輕量生產環境映像檔。
  3. 熟悉 Docker Compose 是邁向微服務架構開發的第一步。