node.js - 构建 Dockerfile - 在中间容器之间保留文件

标签 node.js docker dockerfile pm2

我正在使用 keymetrics 官方图片构建一个非常基本的容器 docker hub link here

然而,这不是一个 node.js 或 pm2 问题,它在很大程度上是一个 Docker 问题,尤其是 docker build

Dockerfile 中的一个步骤 (npm install) 将 Node 包下载到 node_modules 文件夹中——它工作正常。文件夹已创建,文件已下载并显示在构建输出中(如下)。

问题是在 RUN 命令完成后,中间容器被删除,我丢失了 node_modules 文件夹。

我的 dockerfile 有几个 ls -l 命令来阐明文件的情况。

唯一保留在工作目录 (/app) 中的文件是我使用 COPY 命令从主机复制的文件

这是我的Dockerfile:

FROM keymetrics/pm2:latest

# Bundle APP files
COPY src src/
COPY package.json .
COPY pm2.json .

# Install app dependencies
ENV NPM_CONFIG_LOGLEVEL info
RUN pwd && ls -l /app && npm install && ls -l

# Show current folder structure in logs
RUN ls -l

CMD [ "pm2-docker", "start", "pm2.json" ]

构建命令: docker build -t localapps/pm2_test_app:0.0.4 .

构建输出

Sending build context to Docker daemon  13.31kB
Step 1/8 : FROM keymetrics/pm2:latest
 ---> 6aa333f957ec
Step 2/8 : COPY src src/
 ---> Using cache
 ---> 6b73b4463af5
Step 3/8 : COPY package.json .
 ---> Using cache
 ---> d27a2e75fdde
Step 4/8 : COPY pm2.json .
 ---> Using cache
 ---> 9864d9dd73a9
Step 5/8 : ENV NPM_CONFIG_LOGLEVEL info
 ---> Using cache
 ---> 9f711fe6bada
Step 6/8 : RUN pwd && ls -l /app && npm install && ls -l
 ---> Running in 668eb2e2c1e8
/app
total 12
-rw-r--r--    1 root     root           323 Nov  8 17:33 package.json
-rw-r--r--    1 root     root           123 Nov  8 16:59 pm2.json
drwxr-xr-x    2 root     root          4096 Nov  8 18:10 src
npm info it worked if it ends with ok
npm info using npm@5.5.1
npm info using node@v9.0.0
... <omitting useless npm logs> ...

added 8 packages in 2.001s
npm info ok
total 20
drwxr-xr-x   10 root     root          4096 Nov  8 19:49 node_modules
-rw-r--r--    1 root     root          1833 Nov  8 19:49 package-lock.json
-rw-r--r--    1 root     root           323 Nov  8 17:33 package.json
-rw-r--r--    1 root     root           123 Nov  8 16:59 pm2.json
drwxr-xr-x    2 root     root          4096 Nov  8 18:10 src
 ---> 0d749171a431
Removing intermediate container 668eb2e2c1e8
Step 7/8 : RUN ls -l
 ---> Running in fc2132121c96
total 12
-rw-r--r--    1 root     root           323 Nov  8 17:33 package.json
-rw-r--r--    1 root     root           123 Nov  8 16:59 pm2.json
drwxr-xr-x    2 root     root          4096 Nov  8 18:10 src
 ---> c689180648c9
Removing intermediate container fc2132121c96
Step 8/8 : CMD pm2-docker start pm2.json
 ---> Running in e70b2b89b3c8
 ---> 299c26f883e8
Removing intermediate container e70b2b89b3c8
Successfully built 299c26f883e8
Successfully tagged localapps/pm2_test_app:0.0.4

^^ 注意到 node_modules 目录存在并且可以在第 6 步完成后进入吗?!

从构建输出证明 npm install 已运行并将包下载到适当的目录....

但是在第 7 步它不见了?!此外,在最终图像上它已经消失了。应用程序无法运行,因为 node_modules 中的依赖项在最终图像中被破坏了。

为什么?没有 node_modules 目录,应用程序将无法运行,它们是依赖项。

我能让它工作的唯一方法是在构建之外运行 npm_install,然后使用 COPY 复制文件夹,这绝对不是一个有效的解决方案...但这是一个行之有效的解决方法。

我知道它使用有意义的中间容器,但我如何才能使在 RUN 命令中创建的文件保留到最后?

编辑: 进一步调查显示源图像 dockerfile found here在其 dockerfile 中声明了一个 VOLUME——这是我的问题所在吗?他们的示例表明,只需执行 npm install 即可开箱即用,但事实并非如此,因为它会清除安装下载的文件。

最佳答案

keymetrics/pm2 图像在其 Dockerfile 中包含以下行:

VOLUME ["/app"]

这会中断任何后续步骤和修改 /app 目录的子图像。来自 docker's documentation :

Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

您需要在不同的目录中运行您的构建,制作一个不包含该行的不同基础镜像,或者说服上游作者删除该行。

我已经 blogged about the issues with volumes defined in Dockerfiles之前,这是其中一个问题。在他们的 Dockerfile 中加入这一行确实没有任何好处。

关于node.js - 构建 Dockerfile - 在中间容器之间保留文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47188500/

相关文章:

docker - 最小化 Docker-in-Docker 容器内的 `docker build` 执行时间

docker - Dockerfile 之间的重复

node.js - 错误 : Cannot find module 'webpack/lib/node/NodeTemplatePlugin'

javascript - Node.js:如何防止两个回调同时运行?

mysql - 如何将 MySQL 服务添加到 Consul Docker 容器中?

docker - 使用Docker的Kubernetes无法从默认端口80更改

javascript - 我从 API Server 收到 200 状态响应,但该帐户仍然存在

jquery - 将函数的值赋给变量

docker - 从 docker 安装的 Nextcloud。如何下载和安装自定义应用程序?

docker - 在裸机上运行带有机器的 docker-machines