我正在使用 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/