Docker化Node.js应用无法找到@aws-sdk/client-ses模块求助
解决Docker化Node.js应用中Cannot find module '@aws-sdk/client-ses'的问题
问题详情
在Ubuntu 22.04.4机器上启动Docker化Node.js应用时,抛出模块找不到错误,完整错误栈如下:
back-app-1 | [1] 2024-04-25T09:20:57.938Z error Error: Cannot find module '@aws-sdk/client-ses' back-app-1 | [1] Require stack: back-app-1 | [1] - /usr/src/app/app/services/send-mail.js back-app-1 | [1] - /usr/src/app/app/api/authentication/authentication.controller.js back-app-1 | [1] - /usr/src/app/app/api/authentication/authentication.routes.js back-app-1 | [1] - /usr/src/app/app/api/router.js back-app-1 | [1] - /usr/src/app/app/express.js back-app-1 | [1] - /usr/src/app/app/server.js back-app-1 | [1] - /usr/src/app/bin/www back-app-1 | [1] at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15) back-app-1 | [1] at Module._load (node:internal/modules/cjs/loader:981:27) back-app-1 | [1] at Module.require (node:internal/modules/cjs/loader:1231:19) back-app-1 | [1] at require (node:internal/modules/helpers:177:18) back-app-1 | [1] at Object.<anonymous> (/usr/src/app/app/services/send-mail.js:2:13) back-app-1 | [1] at Module._compile (node:internal/modules/cjs/loader:1364:14) back-app-1 | [1] at Module._extensions..js (node:internal/modules/cjs/loader:1422:10) back-app-1 | [1] at Module.load (node:internal/modules/cjs/loader:1203:32) back-app-1 | [1] at Module._load (node:internal/modules/cjs/loader:1019:12) back-app-1 | [1] at Module.require (node:internal/modules/cjs/loader:1231:19) back-app-1 | [1] at require (node:internal/modules/helpers:177:18) back-app-1 | [1] at Object.<anonymous> (/usr/src/app/app/api/authentication/authentication.controller.js:7:22) back-app-1 | [1] at Module._compile (node:internal/modules/cjs/loader:1364:14) back-app-1 | [1] at Module._extensions..js (node:internal/modules/cjs/loader:1422:10) back-app-1 | [1] at Module.load (node:internal/modules/cjs/loader:1203:32) back-app-1 | [1] at Module._load (node:internal/modules/cjs/loader:1019:12) back-app-1 | [1] at Module.require (node:internal/modules/cjs/loader:1231:19) back-app-1 | [1] at require (node:internal/modules/helpers:177:18) back-app-1 | [1] at Object.<anonymous> (/usr/src/app/app/api/authentication/authentication.routes.js:4:20) back-app-1 | [1] at Module._compile (node:internal/modules/cjs/loader:1364:14) back-app-1 | [1] at Module._extensions..js (node:internal/modules/cjs/loader:1422:10) back-app-1 | [1] at Module.load (node:internal/modules/cjs/loader:1203:32)
应用中send-mail.js的模块引用代码:
const nodemailer = require('nodemailer'); const aws = require("@aws-sdk/client-ses"); const { defaultProvider } = require("@aws-sdk/credential-provider-node"); const SEND_MAIL = Symbol('SEND_MAIL'); const ses = new aws.SES({ apiVersion: "2010-12-01", region: "eu-west-3", defaultProvider, });
package.json已声明相关依赖:
"dependencies": { "@aws-sdk/client-ses": "^3.451.0", "@aws-sdk/credential-provider-node": "^3.451.0", ... }
应用通过Docker部署,依赖在容器内执行npm ci安装,环境为Node.js v20.5.1、npm 10.5.2。
解决方法
1. 检查Docker构建流程的正确性
确保Dockerfile中依赖安装步骤逻辑正确:
- 先复制
package.json和package-lock.json到容器工作目录 - 执行
npm ci安装依赖(npm ci需要package-lock.json存在,且会安装精确版本) - 再复制应用代码到容器
示例正确的Dockerfile片段:
WORKDIR /usr/src/app COPY package*.json ./ RUN npm ci --only=production COPY . .
同时检查.dockerignore文件:
- 可以包含
node_modules(避免本地依赖被复制到容器) - 但不能包含
package-lock.json,否则npm ci无法正常执行。
2. 验证容器内依赖是否实际安装
启动临时容器进入查看依赖情况:
docker run --rm -it <你的镜像名称> /bin/sh # 进入应用工作目录 cd /usr/src/app # 检查@aws-sdk/client-ses是否存在 ls -la node_modules/@aws-sdk/
如果未找到该模块,查看npm ci执行时的容器日志,确认是否有下载失败、权限不足等报错(比如网络问题导致无法拉取依赖包)。
3. 确认Node.js模块加载路径
在容器内执行以下命令,检查/usr/src/app/node_modules是否在模块搜索路径中:
docker run --rm -it <你的镜像名称> node -e "console.log(module.paths)"
如果该路径不在列表中,说明工作目录设置错误,或者应用启动时的工作目录与安装依赖时的目录不一致,需要调整Dockerfile中的WORKDIR或启动命令。
4. 排查依赖版本兼容性
虽然Node.js v20.5.1与@aws-sdk/client-ses v3.451.0理论兼容,但可尝试更新依赖版本:
# 本地更新依赖并生成新的package-lock.json npm install @aws-sdk/client-ses@latest @aws-sdk/credential-provider-node@latest --save # 重新构建Docker镜像 docker build -t <你的镜像名称> .
5. 检查多阶段构建的依赖复制
如果使用多阶段构建,确保生产阶段完整复制了node_modules目录:
# 构建阶段 FROM node:20.5.1 AS builder WORKDIR /usr/src/app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 生产阶段 FROM node:20.5.1-slim WORKDIR /usr/src/app # 复制构建阶段的node_modules COPY --from=builder /usr/src/app/node_modules ./node_modules COPY --from=builder /usr/src/app/dist ./dist CMD ["node", "dist/bin/www"]
内容的提问来源于stack exchange,提问作者swiss_knight
相关产品推荐
相关产品推荐

