在 Visual Studio Code 的 Docker 扩展中,在 Node.js Dockerfile 模板中,node_modules 目录被移动到父目录,在这一行:
RUN npm install --production --silent && mv node_modules ../
mv node_modules ../
对我来说看起来没什么用。
有理由这么做吗?
更新:找到了“为什么”的很好解释。请参阅:处理节点模块部分。
TLDR; 让您可以在容器内外运行应用程序,而不必担心 node_modules 中特定于操作系统的项目无法在主机和容器之间工作。
原文(评论中指出错误)答案:
这是为了利用Docker中的缓存机制。通常,您的
Dockerfile
中会有以下内容:
1. RUN apt-get #bunch of stuff you want installed
2. COPY ["package.json", "package-lock.json*", "npm-shrinkwrap.json*", "./"]
3. RUN npm install --silent && mv node_modules ../
4. COPY . .
5. CMD node index.js
Docker 在“层”中构建其镜像,您可以认为每层都是在执行
Dockerfile
中的每一行时添加的。
那么我们在上面的片段中所说的是:
apt-get
并将图层提交到缓存package.json
文件从主机复制到容器,提交该层npm install
,然后将node_modules
文件夹向上移动一个目录,npm
将递归向上搜索,直到找到node_modules folder
,所以你的应用程序不会关心。提交这一层。node index.js
这个系统的美妙之处在于,Docker 只会从上次构建容器以来发生变化的点重新构建容器。因此,在我们的例子中,如果前一层发生了更改(例如更新的
npm install…
),它只会运行 package.json
。如果不是,则它不会执行 npm install
命令,即使 index.js
可能已更改。
当然,请记住,您应该在
node_modules
文件中列出 .dockerignore
,这样 COPY . .
就不会尝试选取它。
没有记录这样做的原因,但您可以向上移动
node_modules
,这样当您创建绑定挂载时(例如开发容器),您不必再次 npm i
,例如在 postStartCommand
中
对于开发容器。我再说一次npm i
,因为你已经在Dockerfile
那里做到了,或者他们做到了。请注意,您不能通过绑定挂载在 Docker 容器内重用主机中的 node_modules,因为例如,如果您在主机上运行 Windows 而容器运行 Debian,则二进制文件不兼容。
但是,仅将其向上移动一个目录,在我看来没有多大意义,将其移动到
/
更有意义,因为例如开发容器位于 /workspaces
中,并且它不会看到 /usr/src/node_modules
在您链接的这种特殊情况下。
旁注:在开发容器的情况下,您还希望为
${containerWorkspaceFolder}/node_modules
创建命名或匿名卷,否则当您通过 npm
安装某些包时,由于绑定安装,您还会写入主机文件系统。
我希望这能让您更好地了解他们为什么这样做。