You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保容器内griddb_node针对Node.js v18(ABI108)编译解决ERR_DLOPEN_FAILED

解决GridDB Node.js客户端Docker环境下ABI版本不匹配问题

问题背景

开发基于Node.js/Express.js的应用,使用官方griddb_node客户端连接GridDB Cloud,在Docker容器内运行initdb.js脚本时触发ERR_DLOPEN_FAILED错误:griddb_client.node是针对NODE_MODULE_VERSION 64编译的,而容器内Node.js v18对应ABI版本为108。

已尝试操作

  • 在npm install前设置ENV npm_config_build_from_source=true
  • 在Docker镜像中安装build-essential、python3、make、g++等构建工具
  • 添加.dockerignore排除宿主机node_modules
  • 在Dockerfile中执行npm rebuild griddb_node --build-from-source
  • 删除宿主机node_modules并重新构建

但容器内仍存在ABI-64版本的griddb_client.node。

相关配置文件

Dockerfile

FROM node:18-slim

WORKDIR /usr/src/app

# Copy the pre-downloaded GridDB C Client package into the image
COPY debs/griddb-c-client_5.8.0_amd64.deb /tmp/

# Install runtime deps, the GridDB C client, and build tools
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      libssl3 \
      libstdc++6 \
      ca-certificates \
      wget \
      build-essential \
      python3 \
      make \
      g++ && \
    dpkg -i /tmp/griddb-c-client_5.8.0_amd64.deb && \
    rm -rf /var/lib/apt/lists/* /tmp/griddb-c-client_5.8.0_amd64.deb

# Copy package manifests and force rebuild of native modules at install
ENV npm_config_build_from_source=true
COPY package.json package-lock.json ./
RUN npm install --production

# Copy the rest of your application source
COPY . .

# Expose the application port
EXPOSE 3000

# Start the application
CMD ["node", "app.js"]

docker-compose.yml

version: '3.8'
services:
  studyive:
    build: .
    dns:
      - 8.8.8.8
      - 1.1.1.1
    ports:
      - "3000:3000"
    env_file:
      - .env
    volumes:
      - ./uploads:/usr/src/app/uploads
      - ./public:/usr/src/app/public
    restart: unless-stopped

initdb.js核心代码

// initdb.js
const store = require('./config/griddb');
const griddb = require('griddb_node');

async function init() {
  await Promise.all([
    // users容器创建
    store.putContainer({
      name: 'users',
      columnInfoList: [
        ['id', griddb.Type.STRING],
        ['username', griddb.Type.STRING],
        ['passwordHash', griddb.Type.STRING],
        ['role', griddb.Type.STRING],
      ],
      type: griddb.ContainerType.COLLECTION,
      rowKey: true
    }),
    // assignments容器创建
    store.putContainer({
      name: 'assignments',
      columnInfoList: [
        ['id', griddb.Type.STRING],
        ['userId', griddb.Type.STRING],
        ['title', griddb.Type.STRING],
        ['dueDate', griddb.Type.TIMESTAMP],
        ['done', griddb.Type.BOOL],
        ['notes', griddb.Type.STRING]
      ],
      type: griddb.ContainerType.COLLECTION,
      rowKey: true
    }),
    // 其他容器创建逻辑...
  ]);

  console.log('Containers created.');
  process.exit(0);
}

init().catch(console.error);

错误输出

执行docker-compose build --no-cache构建成功,但运行docker-compose run --rm studyive node initdb.js时报错:

WARN[0000] /mnt/c/Users/unita/StudyIve/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
node:internal/modules/cjs/loader:1460
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: The module '/usr/src/app/node_modules/griddb_node/lib/griddb_client.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 64. This version of Node.js requires
NODE_MODULE_VERSION 108. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
    at Module._extensions..node (node:internal/modules/cjs/loader:1460:18)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12)
    at Module.require (node:internal/modules/cjs/loader:1231:19)
    at require (node:internal/modules/helpers:177:18)
    at Object.<anonymous> (/usr/src/app/node_modules/griddb_node/lib/griddb_node.js:1:14)
    at Module._compile (node:internal/modules/cjs/loader:1364:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
    at Module.load (node:internal/modules/cjs/loader:1203:32)
    at Module._load (node:internal/modules/cjs/loader:1019:12) {
  code: 'ERR_DLOPEN_FAILED'
}

Node.js v18.20.8

解决方案

1. 修正Dockerfile构建逻辑

修改Dockerfile中的依赖安装步骤,强制从源码构建并避免锁定预编译包:

# 移除原有的package-lock.json复制和安装步骤,替换为:
RUN rm -f package-lock.json
ENV npm_config_build_from_source=true
COPY package.json ./
RUN npm install --production --build-from-source && \
    npm rebuild griddb_node --build-from-source

原因:package-lock.json会锁定预编译二进制包的版本,删除后重新安装会强制基于当前容器的Node.js环境从源码编译griddb_node。

2. 确保griddb_node与C Client版本匹配

在package.json中明确指定griddb_node版本为5.8.0(与已安装的GridDB C Client版本一致):

"dependencies": {
  "griddb_node": "5.8.0"
}

3. 完善.dockerignore配置

确保.dockerignore包含以下内容,防止宿主机文件干扰容器构建:

node_modules/
package-lock.json
npm-debug.log

4. 彻底清理缓存后重新构建

执行以下命令构建镜像,确保无缓存干扰:

docker-compose build --no-cache --force-rm

5. 验证编译结果

进入容器验证griddb_node的ABI版本是否匹配:

docker-compose run --rm studyive bash
# 查看容器内Node.js的ABI版本
node -p "process.versions.modules" # 应输出108
# 检查griddb_node的安装状态
npm ls griddb_node

关键原因

griddb_node的npm包默认提供的预编译二进制包针对旧版Node.js(NODE_MODULE_VERSION 64对应Node.js 10.x),而Node.js 18对应ABI 108,必须强制在容器内基于当前Node.js环境从源码编译,同时确保GridDB C Client依赖已正确安装。

内容的提问来源于stack exchange,提问作者Sadaf Farooqi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 21:34:59