菜单

Docker 最佳实践

相关源文件

本文档概述了使用 Docker 容器化 Node.js 应用程序的基本实践。这些建议侧重于创建安全、高效且生产就绪的 Docker 镜像,这些镜像针对 Node.js 环境进行了优化。有关一般的 Node.js 生产实践,请参阅生产实践

目录

多阶段构建,打造更精简的镜像

多阶段构建对于分离构建时依赖项与运行时需求至关重要。这种方法可以显著减小最终镜像的大小,从而实现更快的部署、更小的攻击面和更好的资源利用率。

主要优势

  • 将开发依赖项排除在生产镜像之外
  • 显著减小最终镜像大小
  • 降低安全漏洞
  • 更好的关注点分离

实现示例

始终在 npm install 或你的包管理器中使用 --production 标志来排除开发依赖项。使用缓存清理命令进一步减小镜像大小。

来源: sections/docker/multi_stage_builds.md sections/docker/install-for-production.md sections/docker/clean-cache.md

容器初始化与运行时

使用 Node 直接启动容器

在启动容器时,应直接使用 node 命令,而不是 npm 脚本。这可以确保正确的信号处理,并避免不必要的进程嵌套。

进程对比

启动方式进程树信号处理容器关闭
CMD ["node", "server.js"]单个 Node 进程直接干净利落
CMD "npm start"npm → sh → node中断可能出现孤儿进程

来源: sections/docker/bootstrap-using-node.md

优雅地处理关闭信号

正确处理终止信号 (SIGTERM),以确保您的应用程序在容器停止或重启时能够优雅地关闭。

来源: sections/docker/graceful-shutdown.basque.md

安全考量

避免在参数中使用构建时秘密

切勿通过构建参数传递秘密,因为它们会保留在镜像历史中。请改用 Docker 的秘密挂载功能或多阶段构建。

安全方法

  1. Docker 构建秘密(推荐)

  2. 多阶段构建

来源: sections/docker/avoid-build-time-secrets.md

使用 .dockerignore 防止泄露秘密

通过使用全面的 .dockerignore 文件,防止敏感文件和目录被复制到 Docker 镜像中。

示例 .dockerignore

# Development files
node_modules
npm-debug.log
.git
.gitignore
.vscode
*.md

# Testing
coverage
.nyc_output
test

# Environment and secrets
.env
.env.*
.npmrc
.aws

来源: sections/docker/docker-ignore.md

移除开发依赖项

开发依赖项会增加容器的攻击面和大小。在最终镜像中仅安装生产依赖项。

来源: sections/docker/install-for-production.md

资源管理

同时使用 Docker 和 V8 设置内存限制

在容器级别(Docker)和应用程序级别(Node.js V8)都设置显式的内存限制,以防止内存不足问题并确保正确的资源分配。

Docker 内存限制

Node.js 内存限制

来源: sections/docker/memory-limit.md

Docker 配置与优化

优先选择更小的基础镜像

使用 Alpine 等更小的基础镜像可以减少漏洞和资源消耗。标准的 Node.js 镜像大约为 345MB,而 Alpine 版本仅为 39MB。

Node.js 基础镜像对比

基础镜像大小安全面构建工具
node:14约 345MB较大包含
node:14-slim约 110MB中等最小
node:14-alpine约 39MB更小最小

来源: sections/docker/smaller_base_images.md sections/docker/smaller_base_images.basque.md

使用特定的镜像标签

避免在生产环境中使用 latest 标签。改用特定的版本标签,以确保一致性和可预测性。

示例

  • 错误: FROM node:latest
  • 正确: FROM node:14.17.0-alpine3.13
  • 更好: FROM node:14.17.0-alpine3.13@sha256:a1f935b3700c6.....

来源: sections/docker/image-tags.basque.md

清理 npm 缓存

安装后移除 npm 缓存以减小镜像大小。这在单阶段构建中尤为重要。

来源: sections/docker/clean-cache.md sections/docker/clean-cache.basque.md

检查 Dockerfile

使用 Hadolint 等 linting 工具来验证 Dockerfile 的最佳实践并及早发现问题。

来源: sections/docker/lint-dockerfile.basque.md

其他最佳实践

通用 Docker 实践

  1. 优先使用 COPY 而非 ADD:COPY 更透明,仅处理本地文件复制。
  2. 避免更新基础操作系统:使用定期更新的基础镜像,而不是运行包更新。
  3. 为镜像添加元数据标签:添加适当的标签来识别镜像的所有权和版本。
  4. 使用非特权容器:尽可能以非 root 用户运行容器。

来源: sections/docker/generic-tips.basque.md

让 Docker 处理进程管理

不要在容器内实现进程管理。让 Docker 编排平台(Kubernetes、Docker Swarm)来处理副本、正常运行时间和扩展。

使用 LTS Node.js 版本

在生产 Docker 镜像中始终使用 Node.js LTS(长期支持)版本,以提高稳定性和安全性。

来源: sections/production/LTSrelease.chinese.md

Docker 最佳实践总结

遵循这些 Docker 最佳实践,您可以确保您的 Node.js 应用程序部署在安全、高效且易于维护的容器中。