升级Node.js至v16后,Docker容器中SQLite3模块缺失问题求助
问题描述
将Node.js从v14升级到v16后,Docker容器启动Node.js 16应用时出现MODULE_NOT_FOUND错误,找不到sqlite3的绑定文件。镜像构建成功,但启动时报错,错误日志和Dockerfile如下:
错误日志
Error: Cannot find module '/usr/src/app/node_modules/sqlite3/lib/binding/napi-v6-linux-glibc-x64/node_sqlite3.node' Require stack: - /usr/src/app/node_modules/sqlite3/lib/sqlite3-binding.js - /usr/src/app/node_modules/sqlite3/lib/sqlite3.js - /usr/src/app/build/entity/data-service/sqlite.helper.js - /usr/src/app/build/entity/data-service/dataservice.controller.js - /usr/src/app/build/route.js - /usr/src/app/build/index.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:985:15) at Function.Module._load (node:internal/modules/cjs/loader:833:27) at Module.require (node:internal/modules/cjs/loader:1057:19) at require (node:internal/modules/cjs/helpers:103:18) at Object.<anonymous> (/usr/src/app/node_modules/sqlite3/lib/sqlite3-binding.js:4:17) at Module._compile (node:internal/modules/cjs/loader:1155:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1209:10) at Module.load (node:internal/modules/cjs/loader:1033:32) at Function.Module._load (node:internal/modules/cjs/loader:868:12) at Module.require (node:internal/modules/cjs/loader:1057:19) { code: 'MODULE_NOT_FOUND', requireStack: [ '/usr/src/app/node_modules/sqlite3/lib/sqlite3-binding.js', '/usr/src/app/node_modules/sqlite3/lib/sqlite3.js', '/usr/src/app/build/entity/data-service/sqlite.helper.js', '/usr/src/app/build/entity/data-service/dataservice.controller.js', '/usr/src/app/build/route.js', '/usr/src/app/build/index.js'
Dockerfile
FROM node:16-alpine AS builder RUN mkdir -p /myloc/usr/src/app WORKDIR /myloc/usr/src/app COPY package.json ./ #build all the local images in the base node container RUN npm install COPY . . RUN npm run build #RUN npm run test FROM node:16-slim RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY --from=builder /myloc/usr/src/app . # Add user nodejsuser RUN groupadd --gid 2000 nodejsuser \ && useradd --uid 1300 --gid nodejsuser --shell /bin/bash --create-home nodejsuser RUN chown -R nodejsuser:nodejsuser /usr/src/app USER nodejsuser EXPOSE 4000 EXPOSE 3000 CMD ["npm", "start"]
原因分析
sqlite3是原生Node.js模块,编译时会依赖底层系统的C库。你的builder阶段用的是node:16-alpine(基于musl libc),但运行阶段用的是node:16-slim(基于glibc),两者的C库不兼容。在alpine上编译生成的sqlite3绑定文件(node_sqlite3.node)无法在glibc环境中被识别,导致启动时找不到对应路径的模块。
解决方法
方法1:统一基础镜像(推荐)
将builder和运行阶段的镜像统一为同一个,避免跨libc环境的问题。比如都用node:16-slim:
修改后的Dockerfile:
FROM node:16-slim AS builder RUN mkdir -p /myloc/usr/src/app WORKDIR /myloc/usr/src/app COPY package.json ./ RUN npm install COPY . . RUN npm run build FROM node:16-slim RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY --from=builder /myloc/usr/src/app . RUN groupadd --gid 2000 nodejsuser \ && useradd --uid 1300 --gid nodejsuser --shell /bin/bash --create-home nodejsuser RUN chown -R nodejsuser:nodejsuser /usr/src/app USER nodejsuser EXPOSE 4000 3000 CMD ["npm", "start"]
如果坚持用alpine,运行阶段也用node:16-alpine,但需要在builder阶段安装编译原生模块的依赖:
FROM node:16-alpine AS builder RUN mkdir -p /myloc/usr/src/app WORKDIR /myloc/usr/src/app # 安装alpine编译原生模块所需依赖 RUN apk add --no-cache python3 make g++ COPY package.json ./ RUN npm install COPY . . RUN npm run build FROM node:16-alpine RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY --from=builder /myloc/usr/src/app . RUN addgroup -g 2000 nodejsuser \ && adduser -u 1300 -G nodejsuser -s /bin/sh -D nodejsuser RUN chown -R nodejsuser:nodejsuser /usr/src/app USER nodejsuser EXPOSE 4000 3000 CMD ["npm", "start"]
方法2:在运行阶段重新安装sqlite3
如果必须跨镜像,在运行阶段重新编译sqlite3以适配glibc环境:
修改运行阶段的Dockerfile部分:
FROM node:16-slim RUN mkdir -p /usr/src/app WORKDIR /usr/src/app COPY --from=builder /myloc/usr/src/app . # 安装编译依赖,重新安装sqlite3 RUN apt-get update && apt-get install -y python3 make g++ \ && npm install sqlite3 --force \ && apt-get purge -y python3 make g++ \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* # Add user nodejsuser RUN groupadd --gid 2000 nodejsuser \ && useradd --uid 1300 --gid nodejsuser --shell /bin/bash --create-home nodejsuser RUN chown -R nodejsuser:nodejsuser /usr/src/app USER nodejsuser EXPOSE 4000 3000 CMD ["npm", "start"]
内容的提问来源于stack exchange,提问作者Kranthi
相关产品推荐
相关产品推荐

