本文档概述了使用 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 命令,而不是 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 的秘密挂载功能或多阶段构建。
安全方法
Docker 构建秘密(推荐)
多阶段构建
来源: sections/docker/avoid-build-time-secrets.md
通过使用全面的 .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)和应用程序级别(Node.js V8)都设置显式的内存限制,以防止内存不足问题并确保正确的资源分配。
Docker 内存限制
Node.js 内存限制
来源: sections/docker/memory-limit.md
使用 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:latestFROM node:14.17.0-alpine3.13FROM node:14.17.0-alpine3.13@sha256:a1f935b3700c6.....来源: sections/docker/image-tags.basque.md
安装后移除 npm 缓存以减小镜像大小。这在单阶段构建中尤为重要。
来源: sections/docker/clean-cache.md sections/docker/clean-cache.basque.md
使用 Hadolint 等 linting 工具来验证 Dockerfile 的最佳实践并及早发现问题。
来源: sections/docker/lint-dockerfile.basque.md
来源: sections/docker/generic-tips.basque.md
不要在容器内实现进程管理。让 Docker 编排平台(Kubernetes、Docker Swarm)来处理副本、正常运行时间和扩展。
在生产 Docker 镜像中始终使用 Node.js LTS(长期支持)版本,以提高稳定性和安全性。
来源: sections/production/LTSrelease.chinese.md
遵循这些 Docker 最佳实践,您可以确保您的 Node.js 应用程序部署在安全、高效且易于维护的容器中。