运行 Grunt / Gulp 在 Docker 容器内还是在容器外?

Run Grunt / Gulp inside Docker container or outside?

我正在尝试确定使用 grunt/gulp 部署在 docker 容器内的 nodejs 应用程序构建过程的良好实践。

我对以下顺序非常满意:

但在我发现的每个示例中,我都看到了不同的方法:

IMO,第一种方法生成更轻、更高效的容器,但所有示例都使用第二种方法。我错过了什么吗?

我看到的唯一区别是您可以在第二种方法中重现完整的 grunt 安装。

对于第一个,您依赖于可能在不同环境中以不同方式完成的本地操作。

容器应该基于可以轻松复制的图像,而不是依赖于包含 "what is needed" 的主机文件夹(不知道该部分是如何完成的)


如果安装附带的构建环境开销对于 grunt 映像来说太多了,您可以:

  • 创建专用于安装的映像“app.tar”(I did that for Apache, that I had to recompile, creating a deb package in a shared volume)。
    在您的情况下,您可以创建已安装应用程序的存档 ('tar')。
  • 使用第一个容器中的卷从基本映像创建容器

    docker run --it --name=app.inst --volumes-from=app.tar ubuntu untar /shared/path/app.tar
    docker commit app.inst app
    

然后最终结果是应用程序存在于其文件系统上的图像。

这是方法 1 和方法 2 的混合。

我想推荐第三种方法,即我为静态生成的网站所做的,即单独的构建图像。

在这种方法中,您的主要 Dockerfile(项目根目录中的那个)成为构建和开发映像,基本上在第二种方法中完成所有操作。但是,您在 运行 时覆盖 CMD,即将 tar 构建的 dist 文件夹放入 dist.tar 或类似文件夹。

然后,您有另一个文件夹(类似于 image),其中包含 Dockerfile。这张图片的作用只是服务于dist.tar的内容。所以我们做一个docker cp <container_id_from_tar_run> /dist。然后 Dockerfile 只安装我们的网络服务器并有一个 ADD dist.tar /var/www

摘要是这样的:

  • 构建 builder Docker 图像(这将为您提供一个没有网络服务器的工作环境)。此时,应用程序已构建。我们可以 运行 使用 grunt serve 开发中的容器,或者使用任何命令来 tar 构建我们的内置开发服务器。
  • 代替 运行 连接服务器,我们将默认命令覆盖到 tar 我们的 dist 文件夹。像 tar -cf /dist.tar /myapp/dist.
  • 这样的东西
  • 我们现在有一个带有 /dist.tar 工件的临时容器。使用 docker cp <container_id_from_tar_run> /dist.tar ./image/.
  • 将其复制到我们称为 image 的实际部署 Docker 文件夹
  • 现在,我们可以构建小型 Docker 图像,而无需使用 docker build ./image 的所有开发依赖项。

我喜欢这种方法,因为它仍然是所有 Docker。这种方法中的所有命令都是 Docker 命令,您可以真正精简最终部署的实际映像。

如果您想使用这种方法查看图像,请查看 https://github.com/gliderlabs/docker-alpine,它使用构建器图像(在构建器文件夹中)构建 tar.gz 文件,然后将其复制到他们各自的 Dockerfile 文件夹。

解决方案 1 的一个变体是 "parent -> child",这使得项目的构建非常快。 我会有 docker 文件,如:

FROM node
RUN mkdir app
COPY dist/package.json app/package.json
WORKDIR app
RUN npm install

这将处理节点依赖项的安装,并有另一个 docker 文件来处理应用程序 "installation",例如:

FROM image-with-dependencies:v1
ENV NODE_ENV=prod
EXPOSE 9001
COPY dist .
ENTRYPOINT ["npm", "start"]

这样您就可以继续您的开发,并且 docker 映像的 "build" 将比您需要 "re-install" 节点依赖项时更快。如果您在节点上安装新的依赖项,只需重新构建依赖项映像即可。

我希望这对某人有所帮助。

此致