节点 Docker 构建和生产容器最佳实践

Node Docker Build and Production Container Best Practices

我有一个使用 MongoDB 的 Node 项目。为了进行自动化测试,我们使用 Mongo Memory Server

对于 Mongo 内存服务器,我的 Mongo 不支持 Alpine,因此它不能 运行 在 Alpine 图像上

来自文档:

There isn't currently an official MongoDB release for alpine linux. This means that we can't pull binaries for Alpine (or any other platform that isn't officially supported by MongoDB), but you can use a Docker image that already has mongod built in and then set the MONGOMS_SYSTEM_BINARY variable to point at that binary. This should allow you to use mongodb-memory-server on any system on which you can install mongod.

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

所以我的 Docker 文件看起来像这样。

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,安全地拥有一个更大的测试容器和一个小的生产容器。

几分

  1. 如果您要构建两次,那么多阶段构建的意义何在。我做的事情不多 node。但是您想要多阶段构建的原因是您使用 npm build 构建应用程序,将这些工件复制到图像中,并以某种方式 serve/run 。在 go 世界中,这就像在构建器阶段构建然后 运行 编译二进制文件。
  2. 您总是希望将变化最大的东西放在联合文件系统的顶部。它的意思是,与其复制整个应用程序代码和 运行ning npm install,不如只复制 package.json 和 运行 npm install。这样 docker 可以缓存 npm install 的结果,并在顶部没有任何变化的情况下节省下载节点文件的时间。您的应用程序代码更改方式比 package.json
  3. 第二阶段同样的想法。如果您必须先复制 package.json,然后复制 运行 npm install,然后再复制其余内容。
  4. 如果你愿意,你可以有更多的阶段。游戏的名称是获得最精简和最干净的最终舞台图像。那就是在注册表中进行的那个。其他一切都可以而且应该被删除。

希望对您有所帮助。