【问题标题】:Node Docker Build and Production Container Best PracticesNode Docker 构建和生产容器最佳实践
【发布时间】:2019-07-11 05:37:59
【问题描述】:

我有一个使用 MongoDB 的 Node 项目。对于自动化测试,我们使用Mongo Memory Server

对于Mongo Memory Server,我的Mongo不支持Alpine,所以不能在Alpine镜像上运行

来自文档:

目前没有针对 alpine linux 的官方 MongoDB 版本。这意味着我们不能为 Alpine(或 MongoDB 未正式支持的任何其他平台)提取二进制文件,但您可以使用已经内置 mongod 的 Docker 映像,然后将 MONGOMS_SYSTEM_BINARY 变量设置为指向该二进制文件.这应该允许您在可以安装 mongod 的任何系统上使用 mongodb-memory-server。

我可以使用 Node 基础映像在 Docker 容器中运行所有测试,但对于生产,我想使用 Alpine 映像来节省内存。

所以我的 Dockerfile 看起来像这样。

FROM node:x.x.x as test

WORKDIR /app

COPY . /app

npm install
npm run build # we use Typescript, this runs the transpilation
npm test # runs our automated tests

FROM node:x.x.x-alpine

WORKDIR /app

COPY --from=test /app/src /app/src
COPY --from=test /app/package.json /app/package.json
COPY --from=test /app/package-lock.json /app/package-lock.json
COPY --from=test /app/config /app/config
COPY --from=test /app/scripts /app/scripts

RUN npm install --production

RUN npm run build

进行冒烟测试,生成的 Alpine 图像似乎可以正常工作。我认为它是安全的,因为我将模块安装在 alpine 映像本身中。

我想知道,这是最佳做法吗?有没有更好的方法来做这样的事情?也就是说,对于 Node 来说,安全地拥有一个更大的测试容器和一个小的生产容器。

【问题讨论】:

    标签: node.js mongodb typescript docker alpine


    【解决方案1】:

    几点

    1. 如果您要构建两次,那么多阶段构建的意义何在。我不怎么做node 的东西。但是您想要多阶段构建的原因是您使用npm build 构建您的应用程序,该应用程序获取这些工件并将它们复制到图像并以某种方式服务/运行它。在go 世界中,这就像在构建器阶段构建然后只运行二进制文件。
    2. 您总是希望在联合文件系统的顶部拥有最变化的东西。这意味着您应该只复制package.json 并在其上运行npm install,而不是复制整个应用程序代码并运行npm install。这样,docker 可以缓存 npm install 的结果,如果顶部没有任何更改,则可以保存下载节点文件。您的应用程序代码更改方式超过package.json
    3. 在第二阶段同样的想法。如果你必须 - 先复制 package.json 并运行 npm install 然后复制其余的东西。
    4. 如果需要,您可以拥有更多阶段。游戏的名称是为了获得最精简和最干净的最终阶段图像。那就是在注册表中进行的那个。其他所有内容都可以也应该删除。

    希望对你有帮助。

    【讨论】:

    • 所以我在最终容器中进行另一个安装的原因是我不确定测试容器中的安装是否与最终容器兼容(我不确定某些库是否安装了特定的依赖项到那个架构)。第一个图像只是 Node,第二个是 Node Alpine。我不确定如果我要从test 容器中复制模块和转译代码而不是安装它们并将它们转译到最终的 Alpine 容器上,是否会有一些差异会伤害我。这是我的根本问题。
    • 我明白了!您可以在 alpine 节点上构建,复制节点模块,使用 mongo 复制到常规节点,然后再次复制到 alpine 节点作为最终映像。如果有任何失败,它将在您的测试中失败。但是你的构建和产品会很好。至于 alpine-node 的差异 需要注意的主要警告是它确实使用 musl libc 而不是 glibc 和朋友,因此某些软件可能会遇到问题,具体取决于其 libc 要求的深度。但是,大多数软件对此没有问题。
    • tl;博士;除非您使用非常特定的操作系统,否则 alpine 应该可以很好地使用。
    • 最后一个想法,这是否也有效(伪 docker)--> 在 Node 容器中安装、构建、运行测试--> 在 Node Alpine 容器中安装、构建--> 在最终节点中Alpine 容器复制转译的 js 文件以及来自以前 alpine 的模块 --> --> 已完成,或者是否有特定原因您在 alpine 上构建然后在节点(不是 alpine)中测试?
    • 我以为你说你需要一些 alpine 中没有的 mongodb 要求。如果您可以在 alpine 上测试所有内容,那么您绝对应该在 alpine 上进行测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 2017-05-22
    • 1970-01-01
    相关资源
    最近更新 更多