前言

Node.js 可以直接在本機執行,但若是要在其他系統上執行,那邊的環境就需要再重新安裝。容器化後的好處就是可以直接執行,只要該系統上有 Docker,就能輕鬆部署。

本篇將教你怎麼將 Node.js 容器化,以 Ubuntu 系統為例。

系統配置

  • Ubuntu: 22.04 LTS
  • Docker: 28.2.2

什麼是 Docker

Docker 是一個開源平台,用於自動化應用程式的部署、擴展和管理。它使用容器的概念,將應用程式及其所有依賴項(程式碼、運行時、系統工具、函式庫等)打包到一個標準化的單元中。這確保了應用程式在任何環境中都能以相同的方式運行,解決了「在我機器上可以跑」的問題。

使用 apt 安裝 Docker

設定 apt 儲存庫

若是首次安裝 Docker Engine 的系統,需要先設定 Docker apt 庫,設定好之後便可直接從倉庫安裝和更新 Docker。

Bash
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# 將儲存庫新增至 Apt 來源:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

安裝 Docker Engine

Bash
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

測試是否安裝成功

Bash
sudo docker run hello-world

若有安裝成功,系統會自行下載一個鏡像並運行。容器運行後會輸出類似如下訊息。

準備 Dockerfile

首先,先進入到 Node.js 專案資料夾

Bash
cd your/project/filder

接著創建 Dockerfile 檔案,注意,此檔案沒有附檔名。

Dockerfile
# 使用一個輕量級的 Node.js 映像檔作為基礎
FROM node:20-alpine AS base

# 設定工作目錄
WORKDIR /app

# 複製 package.json 和 lock file (pnpm-lock.yaml)
# 這樣可以利用 Docker 的快取機制,如果依賴沒有改變,就不需要重新安裝
COPY package.json pnpm-lock.yaml ./

# 安裝 pnpm
RUN npm install -g pnpm

# 安裝依賴
# 使用 pnpm install --frozen-lockfile 以確保依賴版本一致
RUN pnpm install --frozen-lockfile

# 複製專案的其餘程式碼
COPY . .

# 建置 Next.js 應用程式
# 使用 output: "standalone" 可以建立一個獨立的伺服器,減少最終映像檔的大小
# 需要在 next.config.mjs 中設定 output: 'standalone'
# 參考: https://nextjs.org/docs/app/api-reference/next-config-js/output
RUN pnpm run build

# --- 運行階段映像檔 ---
# 使用一個更小的映像檔來運行應用程式,減少攻擊面
FROM node:20-alpine AS runner

WORKDIR /app

# 複製建置階段生成的 standalone 輸出
COPY --from=base /app/.next/standalone ./
COPY --from=base /app/public ./public
COPY --from=base /app/.next/static ./.next/static

# 暴露應用程式運行的埠號 (Next.js 預設是 3000)
EXPOSE 3000

# 定義容器啟動時執行的命令
# 運行 standalone 伺服器
CMD ["node", "server.js"]

*重要:為了使用 output: "standalone" 功能,需要在你的專案的 next.config.mjs 檔案中添加或修改配置:

Bash
// next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone', // 添加這一行
};

export default nextConfig;

建置 Docker 映像檔

在專案的跟目錄下打開終端機,執行以下命令來建置 Docker 映像檔:

Bash
docker build -t your-docker-name .

注意最後面的 . 很重要,一定要輸入。

運行 Docker 容器

映像檔建置完成後,就可以執行以下指令來啟動 Docker 容器:

Bash
docker run -p 3000:3000 your-docker-name

現在,你可以到瀏覽器輸入 localhost:3000 來訪問你的 Web 應用程式。

後台運行 Docker 容器

剛剛執行的容器無法在後台運行,你關掉終端機後就會自動停止,可使用以下指令讓容器在後台運行:

Bash
docker run -d -p 3000:3000 your-docker-name

自動重啟 Docker 容器

為確保容器在崩潰或伺服器重啟後自動重啟容器,可以使用 —restart 標誌:

Bash
docker run -d --restart unless-stopped -p 3000:3000 your-docker-name

小結

這就是使用 Docker 容器化 Next.js 專案並實現自動執行的基本做法。可以將建置和運行 Docker 映像檔的步驟整合到 CI/CD 流程中,實現完全自動化部署。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *