适配better-sqlite3的Node.js16项目Dockerfile及K8s部署需求
Node.js 16项目better-sqlite3编译失败解决及Docker/K8s配置文件
项目背景
项目基于Node.js 16构建,搭配TypeORM 0.3.20、better-sqlite3 ^9.4.1,计划采用Docker+Kubernetes微服务架构。但在Windows和MacOS本地安装依赖时,均出现better-sqlite3编译失败的问题,MacOS下具体报错如下:
# dalthon@MacBookPro in ~/Documents/project on git:main x [23:25:11] C:1 $ yarn yarn install v1.22.19 [1/4] 🔍 Resolving packages... [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... [4/4] 🔨 Building fresh packages... [1/2] ⠄ better-sqlite3 error /Users/dalthon/Documents/project/node_modules/better-sqlite3: Command failed. Exit code: 1 Command: prebuild-install || node-gyp rebuild --release Arguments: Directory: /Users/dalthon/Documents/project/node_modules/better-sqlite3 Output: prebuild-install warn install No prebuilt binaries found (target=16.20.0 runtime=node arch=x64 libc= platform=darwin) gyp info it worked if it ends with ok gyp info using node-gyp@9.1.0 gyp info using node@16.20.0 | darwin | x64 gyp info find Python using Python version 3.12.1 found at "/Users/dalthon/.pyenv/versions/3.12.1/bin/python3" gyp info spawn /Users/dalthon/.pyenv/versions/3.12.1/bin/python3 gyp info spawn args [ gyp info spawn args '/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py', gyp info spawn args 'binding.gyp', gyp info spawn args '-f', gyp info spawn args 'make', gyp info spawn args '-I', gyp info spawn args '/Users/dalthon/Documents/project/node_modules/better-sqlite3/build/config.gypi', gyp info spawn args '-I', gyp info spawn args '/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/addon.gypi', gyp info spawn args '-I', gyp info spawn args '/Users/dalthon/Library/Caches/node-gyp/16.20.0/include/node/common.gypi', gyp info spawn args '-Dlibrary=shared_library', gyp info spawn args '-Dvisibility=default', gyp info spawn args '-Dnode_root_dir=/Users/dalthon/Library/Caches/node-gyp/16.20.0', gyp info spawn args '-Dnode_gyp_dir=/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp', gyp info spawn args '-Dnode_lib_file=/Users/dalthon/Library/Caches/node-gyp/16.20.0/<(target_arch)/node.lib', gyp info spawn args '-Dmodule_root_dir=/Users/dalthon/Documents/project/node_modules/better-sqlite3', gyp info spawn args '-Dnode_engine=v8', gyp info spawn args '--depth=.', gyp info spawn args '--no-parallel', gyp info spawn args '--generator-output', gyp info spawn args 'build', gyp info spawn args '-Goutput_dir=.' gyp info spawn args ] Traceback (most recent call last): File "/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py", line 42, in <module> import gyp # noqa: E402 ^^^^^^^^^^ File "/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/__init__.py", line 9, in <module> import gyp.input File "/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/gyp/pylib/gyp/input.py", line 19, in <module> from distutils.version import StrictVersion ModuleNotFoundError: No module named 'distutils' gyp ERR! configure error gyp ERR! stack Error: `gyp` failed with exit code: 1 gyp ERR! stack at ChildProcess.onCpExit (/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:284:16) gyp ERR! stack at ChildProcess.emit (node:events:513:28) gyp ERR! stack at Process.ChildProcess._handle.onexit (node:internal/child_process:293:12) gyp ERR! System Darwin 23.4.0 gyp ERR! command "/Users/dalthon/.nvm/versions/node/v16.20.0/bin/node" "/Users/dalthon/.nvm/versions/node/v16.20.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--release" gyp ERR! cwd /Users/dalthon/Documents/project/node_modules/better-sqlite3 gyp ERR! node -v v16.20.0 gyp ERR! node-gyp -v v9.1.0 gyp ERR! not ok
报错原因
核心问题有两个:
prebuild-install找不到对应Node.js 16.20.0的better-sqlite3预编译二进制包,只能触发本地编译流程;- 本地使用的Python 3.12默认移除了
distutils模块,而当前版本的node-gyp依赖该模块,导致编译失败。
Dockerfile配置(彻底规避编译问题)
使用Node.js 16官方镜像,在容器内构建时确保编译环境完整,避免本地环境差异:
# 阶段1:构建依赖和代码 FROM node:16-bullseye-slim AS builder # 安装编译依赖(解决better-sqlite3编译问题) RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ python3-distutils \ && rm -rf /var/lib/apt/lists/* # 设置工作目录 WORKDIR /app # 复制package.json和yarn.lock COPY package.json yarn.lock ./ # 安装依赖(包括编译better-sqlite3) RUN yarn install --frozen-lockfile --production=false # 复制项目源码 COPY . . # 编译TypeScript代码(如果项目用TS) RUN yarn build # 阶段2:生产镜像(精简体积) FROM node:16-bullseye-slim # 安装运行时依赖(better-sqlite3需要的系统库) RUN apt-get update && apt-get install -y --no-install-recommends \ libsqlite3-0 \ && rm -rf /var/lib/apt/lists/* WORKDIR /app # 从构建阶段复制生产依赖和编译后的代码 COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY package.json ./ # 设置环境变量 ENV NODE_ENV=production # 暴露端口(根据项目实际端口调整) EXPOSE 3000 # 启动命令 CMD ["node", "dist/index.js"]
Kubernetes部署配置
1. Deployment文件(app-deployment.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: node-app labels: app: node-app spec: replicas: 1 selector: matchLabels: app: node-app template: metadata: labels: app: node-app spec: containers: - name: node-app image: your-registry/node-app:latest # 替换为你的镜像地址 ports: - containerPort: 3000 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "500m" memory: "256Mi" # 如果需要持久化sqlite数据库文件,添加volume挂载 volumeMounts: - name: sqlite-data mountPath: /app/data # 替换为项目中sqlite文件的存储路径 volumes: - name: sqlite-data persistentVolumeClaim: claimName: sqlite-pvc
2. PersistentVolumeClaim文件(sqlite-pvc.yaml)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: sqlite-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
3. Service文件(app-service.yaml)
apiVersion: v1 kind: Service metadata: name: node-app-service spec: selector: app: node-app ports: - protocol: TCP port: 80 targetPort: 3000 type: ClusterIP # 如果需要外部访问,可改为NodePort或LoadBalancer
本地开发临时修复方案
如果需要在本地解决编译问题:
- MacOS:安装Python 3.10(自带distutils),执行
brew install python@3.10,然后通过pyenv切换版本:pyenv local 3.10.x; - Windows:安装Python 3.10并勾选“Add to PATH”,或者安装Visual Studio Build Tools(勾选“C++ build tools”组件)。
内容的提问来源于stack exchange,提问作者dalthonmh
相关产品推荐
相关产品推荐

