我浏览了为数不多的好的 dockerizing Vue.js教程之一,有一件事我不明白为什么在Dockerfile
中是强制性的:
# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json /usr/src/app/package.json #not sure though how it relates to PATH...
我在这里只找到一种解释,它说:
我们将所有 Node.js 二进制文件公开给我们的 PATH 环境变量和 将我们的项目包.json复制到应用程序目录。复制 JSON 文件而不是整个工作目录允许我们采取 Docker 缓存层的优势。
不过,这并没有让我变得更聪明。有人能用简单的英语解释吗?
错误预防
我认为这只是防止 Docker 无法找到正确的可执行文件(或任何可执行文件(的错误的一种简单方法。除了为您的图像添加另一层之外,据我所知,将该行添加到您的Dockerfile
中通常没有任何缺点。
它是如何工作的?
向PATH
环境变量添加node_modules/bin
可确保找到在npm build
或yarn build
过程中创建的可执行文件。还可以将本地生成的node_modules
文件夹COPY
到映像,但建议在 Docker 容器中生成它,以确保所有二进制文件都适应容器中运行的基础操作系统。最佳做法是使用多阶段构建。
此外,在PATH
环境变量的开头添加node_modules/bin
可确保使用这些可执行文件(来自node_modules
文件夹(,而不是可能安装在 Docker 映像内的系统上的任何其他可执行文件。
我需要它吗?
简短回答:通常不会。它应该是可选的。
长答案:将WORKDIR
设置为node_modules
所在的路径就足够了,以便在Dockerfile
中发出RUN
、CMD
或ENTRYPOINT
命令,以找到正确的二进制文件,从而成功执行。但是例如,我有一个案例,Docker无法找到文件(我有一个非常复杂的设置,在VSCode中有一个所谓的devcontainer
(。添加行ENV PATH /app/node_modules/.bin:$PATH
解决了我的问题。
因此,如果您想提高 Docker 设置的稳定性以确保一切按预期工作,只需添加该行即可。
所以我认为这一行的好处是将 Docker 容器的node_modules路径添加到相关容器上的PATH
列表中。如果你在Mac(或者我认为是Linux(上运行:
$ echo $PATH
您应该看到用于从终端运行全局命令的路径列表,即gulp
、husky
、yarn
等。
上面的命令会将node_modules路径添加到 docker 容器中的 PATH 列表中,以便在需要时可以在容器内全局运行此类命令。
.bin("二进制文件"的缩写(是一个隐藏目录,bin 之前的句点表示它是隐藏的。此目录包含应用模块的可执行文件。
PATH 只是包含可执行文件的目录/文件夹的集合。 当您尝试执行需要特定可执行文件的操作时,shell 会在 PATH 中的目录集合中查找该文件。
ENV PATH /app/node_modules/.bin:$PATH
将 .bin 目录添加到此集合中,以便当 node 尝试执行需要特定模块可执行文件的操作时,它将在 .bin 文件夹中查找它。
对于每个命令,如FROM
、COPY
、RUN
、CMD
、...,Docker 都会使用此命令的结果创建一个映像,并且这些映像称为层。最终图像是所有图层合并的结果。
如果使用COPY
命令将所有代码存储在一个层中,它将大于存储具有代码路径的环境变量。
这就是为什么缓存层是一个好处。
有关图层的详细信息,请查看这篇非常好的文章。