Skip to content

[BUG] 无法在docker node:*-alpine 镜像中运行 #44

Closed

Description

@wtone

只要是 docker node:*-alpine 镜像 就会有问题,在Docker node:18-alpine 镜像容器中,新建一个测试脚本

docker run -it --rm node18:alpine sh
mkdir test
cd test
npm init
npm i imagescript sharp
vi test.js

//test.js

const { arch, platform } = require('os');
console.log(arch(), platform())
try { 
     module.exports = require(`imagescript/codecs/node/bin/${arch()}-${platform()}.node`); 
}catch (err) { throw new Error('unsupported arch/platform: ' + err.message); }

执行就会报错 :Segmentation fault (core dumped)

同样的引用node原生模块,sharp库就不会报错

console.log(platformAndArch())
try {
    module.exports = require(`sharp/build/Release/sharp-${platformAndArch()}.node`);
} catch (err) {
    throw new Error('unsupported arch/platform: ' + err.message);
}

比较后,发现主要是因为platform这个变量取值以及Alpine 的 musl libc 兼容性问题,主要原因是:

1、musl 与 glibc 二进制不兼容

.node 文件是 Node.js 原生模块(C/C++ 编译的二进制文件),若该文件是在 glibc 系统(如 Ubuntu、CentOS)上编译的,而 Alpine 使用 musl libc,两者的二进制接口不兼容,会导致 Node.js 无法正确加载模块(即使文件存在)。

2、获取当前运行环境的平台信息的方式有问题:

// imagescript/codecs/node/index.js

const { arch, platform } = require('os');
module.exports = require(`./bin/${arch()}-${platform()}.node`);

简单通过os.platform获取的值,无法区分linux(Ubuntu、CentOS) 和 linuxmusl(Docker alpine容器),可以参考 sharp库的做法写一个方法来获取platform和arch:

function platformAndArch() {
    const arch = env.npm_config_arch || process.arch;
    const platform = env.npm_config_platform || process.platform;
    const libc = process.env.npm_config_libc ||
        /* istanbul ignore next */
        (detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '');
    const libcId = platform !== 'linux' || libc === detectLibc.GLIBC ? '' : libc;

    const platformId = [];
    if (arch === 'arm') {
        const fallback = process.versions.electron ? '7' : '6';
        platformId.push(`armv${env.npm_config_arm_version || process.config.variables.arm_version || fallback}`);
    } else if (arch === 'arm64') {
        platformId.push(`arm64v${env.npm_config_arm_version || '8'}`);
    } else {
        platformId.push(arch);
    }
    platformId.push(`${platform}${libcId}`);

    return platformId.join('-');
}

在Docker alpine 容器中调用platformAndArch()将得到的platform和arch是 “x64-linuxmusl”

3、本身提供的imagescript/codecs/node/bin/*.node 文件中也没有包含支持x64-linuxmusl.node的文件

需要重新编译一份适配linuxmusl的模块文件(x64-linuxmusl.node),并添加到imagescript/codecs/node/bin/目录下。

Originally posted by @wtone in #30

Activity

  1. added this to the v3 milestone on Oct 14, 2026
  2. self-assigned this
    on Oct 14, 2026
  3. matmen commented on Oct 14, 2026

    @matmen
    Collaborator

    Fixed in 3.0.0: ImageScript no longer ships any WebAssembly or native binaries. Every codec is plain TypeScript, so there’s nothing to load, bundle or compile per platform, and it runs on Alpine/musl, in bundled serverless functions, Deno, Bun and browsers. npm install imagescript@3; see the changelog for breaking changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions