关于linux:ELF标头或Docker容器中bcrypt的安装问题

ELF Header or installation issue with bcrypt in Docker container

有点遗憾,但是有人在Linux容器(特别是docker)中使用bcrypt时遇到任何问题,并且知道自动解决方法吗?我和这两个有相同的问题:

AWSBox上带有节点bcrypt的无效ELF标头

运行节点应用程序时bcrypt无效的elf标头

我的Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Pull base image
FROM node:0.12

# Expose port 8080
EXPOSE 8080

# Add current directory into path /data in image
ADD . /data

# Set working directory to /data
WORKDIR /data

# Install dependencies from package.json
RUN npm install --production

# Run index.js
CMD ["npm","start"]

如果我的node_modules中已经安装了bcrypt,我会得到前面提到的无效的ELF标头错误,但是如果我删除了它(只是它本身或我的所有软件包),则在构建容器时由于某种原因它没有被安装。我必须在构建后手动输入容器并将其安装在内部。

有自动解决方法吗?

或者,也许,用Node堆栈替代bcrypt的更好选择是什么?


利亚姆(Liam)的评论是关于钱的,只是将其扩展到互联网上的未来旅行者。

问题是您已将node_modules文件夹复制到了容器中。这是一个问题,其原因是bcrypt是本机模块。它不仅是javascript,而且还包含一堆在安装时会编译的C代码。

该编译产生的二进制文件存储在node_modules文件夹中,并且已根据其生成位置进行了自定义。将它们从OSX宿主移植到陌生的Linux土地上会导致它们表现异常,并抱怨ELF标头和妖精的脚。

解决方案是echo node_modules >> .dockerignore并作为Dockerfile的一部分运行npm install。这意味着本机模块将在容器内部而不是在笔记本电脑外部进行编译。

安装此命令后,无需在启动CMD之前运行npm install。只需将其放在Dockerfile的构建阶段即可。

protip:默认情况下,官方节点映像设置为NODE_ENV = production,npm与--production标志相同。在大多数情况下,这是一件好事。当您的Dockerfile还包含一些依赖开发依赖项的构建步骤(Webpack等)时,这不是一件好事。在这种情况下,您需要NODE_ENV=null npm install

pro protip:通过将package.json单独复制到其余代码中,可以更好地利用Docker的缓存。使您的Dockerfile看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Pull base image
FROM node:0.12

# Expose port 8080
EXPOSE 8080

# Set working directory to /data
WORKDIR /data

# Set working directory to /data
COPY package.json /data

# Install dependencies from package.json
RUN npm install

# Add current directory into path /data in image
ADD . /data

# Run index.js
CMD npm start

这样,Docker只会在您更改package.json时重新运行npm install,而不是在每次更改一行代码时都重新运行。


好的,所以我有一个可行的自动化解决方法:

在CMD指令中调用npm install --production。我将挥舞一下双手,弄清楚为什么在执行容器时必须安装bcrypt,但是它可以工作。

更新的Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Pull base image
FROM node:0.12

# Expose port 8080
EXPOSE 8080

# Add current directory into path /data in image
ADD . /data

# Set working directory to /data
WORKDIR /data

# Install dependencies from package.json
RUN npm install --production

# Run index.js
CMD npm install --production; npm start