Bcrypt、Docker和Sails.JS:无效的ELF头文件

19

我的 Node Dockfile

# Set the base image to ubuntu
FROM ubuntu

# Define working directory
ADD . /src
WORKDIR /src

# Install Node.js & other dependencies
RUN apt-get update && \
        apt-get -y install curl && \
        apt-get -y install sudo && \
        curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash - && \
        apt-get -y install python build-essential nodejs

RUN npm install -g node-gyp && \
        node-gyp clean && \
        npm cache clean

RUN node -v

# Install nodemon
RUN npm install -g nodemon


ADD package.json /src/package.json
RUN cd /src && npm install


# Expose port
EXPOSE  8080

# Run app using nodemon
CMD npm install; nodemon /src/app.js

这是我的 docker-compose.yml 文件:

nginx:
    build: ./nginx
    links:
        - node1:node1
        - node2:node2
        - node3:node3
    ports:
        - "80:80"
redis:
    image: redis
    ports:
        - "6379"
node1:
    build: ./node
    links:
        - redis
    ports:
        - "8080"
node2:
    build: ./node
    links:
        - redis
    ports:
        - "8080"
node3:
    build: ./node
    links:
        - redis
    ports:
        - "8080"

docker-compose build 成功运行,Redis / Nginx 在 docker-compose up 中正确设置,但是节点实例却抛出了以下错误:

node2_1 | /src/node_modules/bcrypt/node_modules/bindings/bindings.js:83
node2_1 |         throw e
node2_1 |               ^
node2_1 | Error: /src/node_modules/bcrypt/build/Release/bcrypt_lib.node: invalid ELF header
node2_1 |     at Error (native)
node2_1 |     at Module.load (module.js:355:32)
node2_1 |     at Function.Module._load (module.js:310:12)
node2_1 |     at Module.require (module.js:365:17)
node2_1 |     at require (module.js:384:17)
node2_1 |     at bindings (/src/node_modules/bcrypt/node_modules/bindings/bindings.js:76:44)
node2_1 |     at Object.<anonymous> (/src/node_modules/bcrypt/bcrypt.js:3:35)
node2_1 |     at Module._compile (module.js:460:26)
node2_1 |     at Object.Module._extensions..js (module.js:478:10)
node2_1 |     at Module.load (module.js:355:32)
node2_1 |     at Function.Module._load (module.js:310:12)
node2_1 |     at Module.require (module.js:365:17)
node2_1 |     at require (module.js:384:17)
node2_1 |     at Object.<anonymous> (/src/api/models/User.js:10:14)
node2_1 |     at Module._compile (module.js:460:26)
node2_1 |     at Object.Module._extensions..js (module.js:478:10)
node2_1 | 19 Aug 20:21:11 - [nodemon] app crashed - waiting for file changes before starting...

我搜索了很多地方,似乎找不到可行的解决方案。我尝试使用常规的设置url:https://deb.nodesource.com/setup,特别是安装python2.7并使用ubuntu:15.04映像。

我读到说,当人们在OS X(我的操作系统)上构建bcrypt后,在Linux环境中尝试使用它时会出现这种情况,但我认为这不应该是问题,因为我正在使用docker和boot2docker构建所有内容。


你能展示一个完整的复现程序吗? - user2915097
“reproducer” 是什么意思? - gblock
让任何人都能够像您一样执行相同任务的最短代码。 - user2915097
1
如果之前的回答没有起作用,那么从 bcrypt 切换到 bcryptjs 对我来说似乎很好用。 - ppak10
我在Windows上使用Linux Docker镜像。在Windows上运行npm install将文件同步到Docker镜像中。在容器内删除node_modules并运行npm install解决了问题。 - totymedli
10个回答

43

请确保您没有复制node_modules文件夹。当我使用官方的Node.js "onbuild"镜像时,就出现了这个错误,因为它会复制所有内容...

现在我使用:

.dockerignore

node_modules

Dockerfile

FROM node:6.4.0

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app

CMD [ "npm", "start" ]

EXPOSE 6969

编辑:Github上官方的NodeJS Docker启动镜像项目已经接受了我的pull request,其中在README中指示明确忽略node_modules。


这难道不意味着每次我更改应用程序代码时都必须重新构建Docker镜像吗?如果是这样,如果我的package.json中有很多依赖项并且npm install需要很长时间,那么查看更改实时效果可能需要一段时间。在这种情况下,它不适合开发目的。 - through.a.haze

28

我也遇到了同样的问题,尽管使用的是Express而不是Sails。我尝试了这里的每一个建议,但都没有成功。最终解决方法是将npm模块bcrypt更换为bcryptjs:

npm uninstall bcrypt
npm install bcryptjs --save

然后将您的 require 更改为类似以下内容

var bcrypt   = require('bcryptjs');

现在它运行得非常完美。


1
请尝试按照S.O.指南格式化此内容!谢谢! - fileyfood500
2
bcrypt-nodejs不再维护 - 请勿使用它,改用bcryptjs。 - neurona.dev
这对我起作用了。 - Urchboy

5
在我的软件包配置文件中,我有 "bcrypt":"^0.8.0"。当我去掉了 ^ 并将其改为 "bcrypt":"0.8.0" 时,我成功地使一切运行起来了。
问题在于它试图运行bcrypt 0.8.5,这是由于某种原因引起问题的原因。

很好知道是什么原因导致了这个问题。我查看了变更日志,但没有引起我的注意。 - Lucas
@Lucas 如果这个问题仍然存在,尝试删除 node_modules 文件夹并在 Docker 容器中进行全新的 npm install。Bcrypt 需要在其运行的架构上进行构建,因此如果您将其从 OS X 复制到 Linux,则需要重新构建。虽然我不记得这是否也是这个问题的一部分。 - gblock
开发人员决定引入破坏性更改,可在问题#150中看到 https://github.com/barrysteyn/node-scrypt/issues/150“好的,我对抛出错误没有问题。” - Sandwich

3

仅仅是添加一个新的可能原因。我尝试为一个Node.js应用程序构建我的Docker镜像,但是我遇到了错误invalid ELF header。在我的情况下,我通过从.dockerignore文件中添加node_modules/*解决了这个问题。


1
根本原因是 => Docker上下文。Docker上下文会将您的根文件夹中的所有内容复制到目标容器工作目录中。
因此,您需要添加一个 .dockerignore 文件,并添加这些条目(以及您想要忽略的任何其他文件)。
  • node_modules
  • npm-debug.log

现在,当您构建容器时,它将根据容器的操作系统构建所有内容。


1
我发现排除整个本地的node_modules目录将不允许你安装npm包,并且在容器内实时跟踪这些变化。每次都需要重建容器。为了避免这种情况,只需在容器卷中指定bcrypt目录,并允许docker在安装或删除其他包时跟踪更改即可。
volumes: 
  - .:/app
  - /app/node_modules/bcrypt/

1

我有一个简单的方法解决了这个问题,我认为这也可以帮助你在Docker中。只需将以下指令添加到您的docker文件的运行指令中即可。

1. 卸载bcrypt

npm uninstall bcrypt

2.- 再次安装bcrypt

npm i bcrypt

编辑Docker文件的这一部分,添加以下行:

ADD package.json /src/package.json
RUN cd /src && npm install


#Solve the problem reinstaling bcrypt
RUN npm uninstall bcrypt
RUN npm i bcrypt


# Expose port
EXPOSE  8080

错误发生的原因是在安装bcrypt时,npm会为您的计算机和操作系统安装推荐版本,但当您在其他计算机上时,这种方法不起作用。
-------- 更新 ----------------------------------------
我认为另一个解决方案是授予bcrypt安装的root权限,这是因为bcrypt使用自己的用户但没有权限,所以:
1. 您必须授予项目文件夹的root权限。离开项目文件夹并执行以下操作:
sudo su

然后输入您的根密码以获取根用户权限。
2. 授予您的项目文件夹权限。
chmod -R 777 <project_folder>

请到您的项目文件夹中安装bcrypt。
cd <project_folder>

AND

npm i bcrypt --unsafe-perm=true --allow-root --save

准备好了,如果一切顺利,您的bcrypt模块将无问题地安装。


0
包括一个 .dockerignore 文件,可以为我解决这个错误。
基本的 .dockerignore 文件如下。
# See https://help.github.com/articles/ignoring-files/ for more about 

ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

0

我花了很多时间尝试在使用docker-composedocker容器中运行bcrypt。容器在Linux下工作,但开发是在Windows下进行的,需要挂载代码卷,但bcrypt创建了冲突文件。因此,我将这个问题留给未来解决。 bcrypt必须只安装在容器内,并复制以隔离。例如,可以将其放置在阻止目录中或发送到dev/null。

    volumes:
      - ${WORKER_DIR}/api:${HOME}/api
      - /dev/null/:/api/node_modules/bcrypt/

0
在我的情况下,我通过将以下行添加到Dockerfile中来修复它。
CMD [ "npm", "uninstall", "bcrypt" ]
CMD [ "npm", "install", "bcrypt" ]

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接