[docker][node.js] Cannot find package ‘multer’ imported from /app/server.js

直接使用 npm run dev, 網頁正常執行, 但打包為映像檔之後, 執行卻會出錯.

打包映像檔,名稱自訂為 my-web-app

docker build -t my-web-app .

啟動容器,將本機的 8080 埠對應到容器的 8080 埠

docker rm -f my-running-site
docker run -d -p 8080:8080 --name my-running-site my-web-app

在 docker 看到錯誤訊息:

2026-03-13 08:30:43.727 | node:internal/modules/esm/resolve:873
2026-03-13 08:30:43.727 | throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base), null);
2026-03-13 08:30:43.727 | ^
2026-03-13 08:30:43.727 |
2026-03-13 08:30:43.727 | Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'multer' imported from /app/server.js
2026-03-13 08:30:43.727 | at packageResolve (node:internal/modules/esm/resolve:873:9)
2026-03-13 08:30:43.727 | at moduleResolve (node:internal/modules/esm/resolve:946:18)
2026-03-13 08:30:43.727 | at defaultResolve (node:internal/modules/esm/resolve:1188:11)
2026-03-13 08:30:43.727 | at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:708:12)
2026-03-13 08:30:43.727 | at #cachedDefaultResolve (node:internal/modules/esm/loader:657:25)
2026-03-13 08:30:43.727 | at ModuleLoader.resolve (node:internal/modules/esm/loader:640:38)
2026-03-13 08:30:43.727 | at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:264:38)
2026-03-13 08:30:43.727 | at ModuleJob._link (node:internal/modules/esm/module_job:168:49) {
2026-03-13 08:30:43.727 | code: 'ERR_MODULE_NOT_FOUND'
2026-03-13 08:30:43.727 | }
2026-03-13 08:30:43.727 |
2026-03-13 08:30:43.727 | Node.js v20.20.1

這個錯誤代表 Node.js 在執行 server.js 時,找不到名為 multer 的套件。雖然你可能在本地電腦開發時有安裝,但 Docker 容器是一個獨立的環境,必須確保套件也被安裝在容器內部。

檢查 package.json 設定

請確認你的 package.json 檔案中,dependencies 區塊是否包含 multer。如果沒有,請在本地資料夾執行 npm install multer,這會自動更新設定檔。

修改 Dockerfile

請檢查 Dockerfile,確保有執行安裝指令。通常正確的順序是先複製 package.json,執行安裝,再複製其餘程式碼。以下是一個標準的寫法範例:

Dockerfile

FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "server.js"]

重新構建鏡像

如果你剛新增了套件,必須重新編譯 Docker 鏡像,否則容器會一直使用舊的狀態。請執行以下指令:

docker build -t 你的鏡像名稱 .

檢查掛載卷的問題

如果你使用 docker-compose 並且掛載了整個開發目錄,有時候本地的 node_modules 會覆蓋容器內的環境。建議在 docker-compose.yml 中使用匿名卷來保護容器內的套件:

YAML

services:
  web:
    build: .
    volumes:
      - .:/app
      - /app/node_modules

這樣做可以確保容器使用自己在構建階段安裝的 multer,而不是抓取本地可能不相容或遺漏的資料夾。


問題出在多階段構建(Multi-stage build)的邏輯。你在第二階段只安裝了生產環境套件,但你的 server.js 卻引用了 multer。

核心原因

在第二階段的指令 RUN npm install –production 中,npm 只會安裝 package.json 裡面 dependencies 區塊的套件。如果你的 multer 被歸類在 devDependencies,或者你在第一階段安裝後沒有將 package.json 同步更新,第二階段就不會安裝它。

解決方法

請檢查 package.json,確保 multer 位於 dependencies 而非 devDependencies:

JSON

{
  "dependencies": {
    "multer": "^1.4.5-lts.1",
    "express": "^4.18.2"
  }
}

如果 multer 已經在 dependencies 中,但仍然報錯,通常是因為 server.js 依賴的是第一階段編譯後的產物,或是 node_modules 沒被正確帶入。

建議的 Dockerfile 修正

你可以嘗試將安裝好的 node_modules 從第一階段直接複製過來,這樣可以確保兩邊環境完全一致,也不用再執行一次 npm install:

Dockerfile

# 第一階段:編譯
FROM node:20-alpine AS build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 第二階段:執行
FROM node:20-alpine
WORKDIR /app
# 直接從 build-stage 複製安裝好的 production 套件
COPY --from=build-stage /app/node_modules ./node_modules
COPY --from=build-stage /app/dist ./dist
COPY --from=build-stage /app/package.json ./package.json
COPY server.js ./

EXPOSE 8080
CMD ["node", "server.js"]

檢查 server.js 的路徑

如果你的 server.js 裡面有一行 import multer from ‘multer’,但它其實是在執行 dist 資料夾裡的內容,請確認路徑是否正確。通常在執行 node server.js 時,它會在當前目錄的 node_modules 找套件。


error:

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'cors' imported from /app/server.js
at packageResolve (node:internal/modules/esm/resolve:873:9)
at moduleResolve (node:internal/modules/esm/resolve:946:18)
at defaultResolve (node:internal/modules/esm/resolve:1188:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:708:12)
at #cachedDefaultResolve (node:internal/modules/esm/loader:657:25)
at ModuleLoader.resolve (node:internal/modules/esm/loader:640:38)
at ModuleLoader.getModuleJobForImport (node:internal/modules/esm/loader:264:38)
at ModuleJob._link (node:internal/modules/esm/module_job:168:49) {
code: 'ERR_MODULE_NOT_FOUND'
}

出現這個錯誤的原因與剛才的 multer 完全相同,這代表你的 server.js 雖然引用了 cors 套件,但 Docker 容器的環境中並沒有安裝它。

檢查 package.json 的依賴設定

請打開你的 package.json 檔案,確認 dependencies 區塊中是否有 cors。如果沒有,請在本地終端機執行:

npm install cors

這會將 cors 寫入 package.json。因為你在 Dockerfile 的第二階段使用了 RUN npm install –production,如果 package.json 裡沒有列出這個套件,Docker 就不會安裝它,導致程式執行時找不到模組。

package.json:

"dependencies": {
    ...
    "cors": "^2.8.6",
    ...
}

為什麼會連續出現找不到套件的錯誤

這通常是因為你在開發 server.js 時,直接使用 npm install <package> 安裝了多個套件(如 multer, cors),但可能沒有成功同步到 Docker 構建流程中。

建議的解決步驟

  1. 確保所有 server.js 用到的套件(如 express, multer, cors)都出現在 package.json 的 dependencies 中。
  2. 重新執行 Docker 編譯指令,確保緩存被更新:docker build –no-cache -t 你的鏡像名稱 .
  3. 檢查 server.js 的開頭,確保引用的名稱與安裝的套件名稱一致:import cors from ‘cors’;

如果你的 package.json 已經有這些套件卻還是報錯,建議檢查 Dockerfile 是否有正確執行到第二階段的 npm install。

發佈留言

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