为什么将卷中的vendor / node_modules映射视为不好的做法?

时间:2019-10-25 06:57:58

标签: node.js docker

有人可以解释一下当您映射(成卷)您的供应商或node_module文件时会发生什么情况吗?

我遇到了一些docker环境和红色的速度问题,不需要在那里映射供应商文件,因此我将其排除在docker-compose.yml文件中,并且速度很快提高了。

所以我想知道如果您在卷中映射了供应商文件,那么幕后情况又是什么呢?

有人可以解释吗?我认为这些信息不仅对我有用。

1 个答案:

答案 0 :(得分:3)

启动容器时,Docker进行了一些复杂的文件系统设置。您有 image ,其中包含您的应用程序代码;一个容器文件系统,当容器退出时该文件系统会丢失;和 volumes ,它们在容器外部具有永久的长期存储功能。卷分为两种主要类型,即特定主机目录的 bind挂载和由Docker守护程序管理的命名卷

标准设计模式是图像是完全独立的。有了映像后,我应该可以将其推送到注册表并在未修改的另一台计算机上运行它。

git clone git@github.com:me/myapp
cd myapp
docker build -t me/myapp .  # requires source code
docker push me/myapp

ssh me@othersystem
docker run me/myapp         # source code is in the image
                            # I don't need GitHub credentials to get it

使用卷存储应用程序或node_modules目录存在三个大问题:

  1. 它破坏了“代码进入图像”模式。在实际的生产环境中,您既不想推送图像,也不想单独推送代码。击败了Docker的一大优势。如果您在开发周期中隐藏了图像中的最后每一个字节,那么您实际上就不会运行所交付的内容。

  2. Docker认为卷包含无法安全修改的重要用户数据。这意味着,如果您的node_modules树在一个卷中,并且将软件包添加到package.json文件中,则Docker将继续使用旧的node_modules目录,因为它无法修改您告诉过的重要用户数据就在其中。

  3. 特别是在MacOS上,bind mounts are extremely slow,如果将大型应用程序安装到容器中,它只会进行爬网。

我通常发现卷有三个很好的用途:在容器执行过程中存储实际的用户数据;在启动时注入配置文件;并读出日志文件。代码和库不是大量保留的好东西。

特别是对于前端应用程序,尝试在Docker中运行似乎没有太大好处。由于实际的应用程序代码在浏览器中运行,因此它无法直接访问任何Docker托管的资源,并且您的开发服务器是否在Docker中运行也没有区别。涉及Typescript和Webpack之类的工具的典型构建链没有附加的主机依赖性,因此,您的Docker设置实际上只是一种绕行方式,可对仅位于主机上的源代码运行Node。将应用程序构建为静态文件,然后使用诸如nginx之类的Web服务器为其提供服务的生产路径仍然在Docker中。我只是在主机上运行Node来开发这种东西,而不必考虑这样的问题。