资讯详情

资讯详情

pm2 容器化部署实战:基于 pm2-runtime 与官方 Docker 镜像运行 Node.js 应用

运维CLI可观测性【免费下载链接】pm2Node.js/Typescript/Bun Production Process Manager with a built-in Load Balancer.项目地址https://gitcode.com/gh_mirrors/pm/pm2点击查看免费下载本篇技术指南以仓库 examples/docker-pm2 示例为骨架完整讲解如何在 Docker 容器中使用 pm2 官方镜像keymetrics/pm2:latest-alpine与pm2-runtime命令管理 Node.js 应用进程包括镜像构建、应用配置文件编写、日志流转发与 Keymetrics 监控接入。读完本文你将掌握一套可直接复制的容器内进程托管方案并理解pm2-runtime作为容器专用 PM2 运行时的底层实现原理。示例目录结构总览examples/docker-pm2目录展示了一个最小可运行的容器化 PM2 示例其完整结构如下examples/docker-pm2/ ├── README.md # 使用说明本文即基于它展开 ├── Dockerfile # 镜像构建定义 └── app/ ├── app.js # Express 示例应用 ├── package.json # 应用依赖清单 └── process.config.js # PM2 进程配置文件ecosystem 文件示例的技术要点一句话概括把整个 PM2含守护进程与监控 Agent封进镜像容器启动时直接执行pm2-runtime让容器的主进程就是 PM2 本身从而天然获得进程守护、自动重启、日志聚合等能力同时避免容器即进程模型下 PID 1 信号转发问题的复杂性。镜像构建Dockerfile 逐行拆解示例仓库根目录下的 Dockerfile 内容如下FROM keymetrics/pm2:latest-alpine # Bundle APP files COPY ./app /app WORKDIR /app # Install app dependencies ENV NPM_CONFIG_LOGLEVEL warn RUN npm install --production ENV KEYMETRICS_SECRET xxxx ENV KEYMETRICS_PUBLIC yyyy CMD [ pm2-runtime, process.config.js ]各指令的职责与注意事项指令作用实操建议FROM keymetrics/pm2:latest-alpine使用 PM2 官方 Alpine 基础镜像镜像内已内置pm2、pm2-runtime二进制及 Node.js 运行时生产环境建议固定到具体版本 tag如latest-alpine的某个发行版避免latest漂移COPY ./app /app将本地app/目录含应用代码、package.json、process.config.js复制进镜像/app配合.dockerignore排除node_modules等无关文件缩小镜像上下文WORKDIR /app设置工作目录后续npm install与pm2-runtime均在此目录执行保证process.config.js中相对路径./app.js能正确解析ENV NPM_CONFIG_LOGLEVEL warn降低 npm 安装日志噪音可移除如需离线构建可改用npm ci --productionRUN npm install --production仅安装生产依赖本示例为express不装devDependencies显著缩小镜像体积若应用使用 ES Modules 或需编译原生模块需在此安装对应构建工具链ENV KEYMETRICS_SECRET xxxx/ENV KEYMETRICS_PUBLIC yyyy注入 KeymetricsPM2 Plus监控密钥生产环境应通过--build-arg或容器编排系统的 secret 机制注入不要写死明文CMD [ pm2-runtime, process.config.js ]容器启动后由pm2-runtime加载并托管process.config.js中声明的应用也可直接写CMD [ pm2-runtime, app.js ]托管单个脚本注意CMD使用exec 形式JSON 数组而非 shell 形式这样容器 PID 1 进程就是pm2-runtime可正确接收 Docker/K8s 下发的SIGTERM等信号并完成优雅退出。应用代码与 PM2 进程配置示例应用是一个标准的 Express HTTP 服务examples/docker-pm2/app/app.jsconst express require(express) const app express() app.get(/, (req, res) res.send(Hello World!)) app.listen(3000, () console.log(Example app listening on port 3000!))依赖清单声明在 examples/docker-pm2/app/package.json{ name: app, version: 1.0.0, main: index.js, scripts: { test: echo \Error: no test specified\ exit 1 }, license: ISC, dependencies: { express: ^4.16.2 } }真正决定 PM2 如何托管应用的是进程配置文件 examples/docker-pm2/app/process.config.jsmodule.exports { apps : [{ name : express-app, script : ./app.js }] }这是一个标准的 PM2 ecosystem 配置文件CommonJS 导出apps数组内每个对象代表一个被托管的进程。name用于在pm2 list/pm2 logs中标识应用script为相对WORKDIR的入口脚本。在此基础上可继续扩展大量生产级配置项例如module.exports { apps : [{ name : express-app, script : ./app.js, instances : 2, // 多实例配合内置负载均衡cluster 模式 exec_mode : cluster, // fork | cluster max_memory_restart : 100M, // 内存超限自动重启 watch : false, env : { NODE_ENV: production }, error_file : /dev/null, // 错误日志重定向 out_file : /dev/null, // 输出日志重定向 time : true // 日志行附加时间戳 }] }这些字段会由 PM2 的启动逻辑解析并作用于进程生命周期管理具体行为可对照 lib/binaries/Runtime4Docker.js 中透传给pm2.start(cmd, commander, ...)的选项处理。构建与运行三条核心命令原文档给出了完整的三步操作流程直接可执行# 1. 构建镜像 $ docker build -t docker-pm2-test . # 2. 查看本机镜像列表确认构建成功 $ docker images # 3. 运行容器 $ docker run docker-pm2-test运行后观察容器日志应依次出现 PM2 启动信息与应用自身的输出Example app listening on port 3000!容器内pm2-runtime会把 PM2 的日志流stdout/stderr直接打到容器标准输出因此使用docker logs docker-pm2-test即可实时查看被托管应用的日志这正是pm2-runtime相对常规pm2命令在容器场景下的关键差异详见下文原理小节。如需验证应用可用性可追加端口映射后访问$ docker run -p 3000:3000 docker-pm2-test $ curl http://localhost:3000/ # Hello World!深入原理pm2-runtime 为什么适合容器pm2-runtime是 PM2 为容器场景Docker、Kubernetes 等提供的专用二进制其完整 CLI 实现位于 lib/binaries/Runtime4Docker.js代码注释将其明确定义为Specialized PM2 CLI for Containers容器专用 PM2 命令行与常规 pm2 命令的本质区别常规pm2采用守护进程daemon架构CLI 进程与长期驻留的 God 守护进程分离命令执行后 CLI 即退出守护进程在后台持续托管应用。这在宿主机场景没问题但在容器中会产生容器主进程退出、后台守护进程孤儿化等管理难题。pm2-runtime则运行在no-daemon 模拟模式下Runtime4Docker.js内部通过new PM2.custom({ daemon_mode: false, ... })创建内嵌 PM2 实例容器主进程即 PM2 本身被托管应用的生命周期与容器完全绑定——容器停止进程随之回收进程崩溃PM2 按配置自动拉起。关键实现细节源码证据从 lib/binaries/Runtime4Docker.js 可以观察到以下几点信号处理实例启动后立即注册SIGINT/SIGTERM处理器收到信号即调用Runtime.exit()先执行pm2.kill()清理全部托管进程再process.exit实现优雅退出Runtime.exit定义于Runtime.js对应逻辑的对称实现中见 lib/binaries/Runtime.js 的exitPM2日志流直通容器 stdoutstartLogStreaming()依据 CLI 选项在Log.jsonStream/Log.formatStream/Log.stream之间选择默认把 PM2 全部应用日志透传到标准输出天然适配docker logs内嵌 PM2 实例pm2_home、secret_key、public_key、machine_name均通过环境变量或 CLI 选项注入其中密钥优先级为constants.js中的环境变量优先、命令行参数兜底。pm2-runtime 常用选项Runtime4Docker.js中通过commander注册的选项即为容器场景下的完整能力面常用项整理如下选项含义-i, --instances number启动 N 个实例并自动负载均衡cluster 模式--no-autorestart启动应用但禁止自动重启--stop-exit-codes codes...指定一组退出码命中时跳过自动重启--max-memory-restart memory超过内存阈值如100M自动重启-c, --cron pattern按 cron 表达式定时重启应用--interpreter interpreter指定解释器bash、python 等--delay seconds延迟 N 秒后再加载配置文件启动--web [port]在指定端口默认 9615启动 Web API--env name注入配置文件中的env_name环境变量块--watch监听文件变化并自动重启--json/--format以 JSON 或keyval格式输出日志--no-auto-exit全部进程出错/停止时也不自动退出其中--no-autorestart、--stop-exit-codes、--delay、--only app-name等选项在Runtime4Docker.js的commander.option(...)注册列表中均有对应声明说明容器运行时对重启策略的控制粒度比常规命令行更细适配 K8s 下由编排层决定重启而非 PM2 自行无限重试的场景。无应用存活时的自动退出容器场景一个值得注意的细节Runtime4Docker.js内置了autoExitWorker配合--auto-exit默认失败容忍次数DEFAULT_FAIL_COUNT 3每 2 秒轮询一次pm2.list若检测到0 个应用处于online/launching状态则连续重试 3 次后调用Runtime.exit(2)使容器退出——避免容器空转占资源。这一点在 test/e2e/binaries/pm2-runtime.sh 中有对应测试pm2_runtime exited_app.js启动注定崩溃的应用后断言 PM2 进程最终被回收。测试验证pm2-runtime 的自动化用例仓库 test/e2e/binaries/pm2-runtime.sh 给出了pm2-runtime的端到端验证方式可作为理解其行为契约的补充# 启动 4 个实例断言有 4 个进程处于 online 状态 $pm2_runtime app.js -i 4 should should have started 4 apps online 4 # 通过 JSON 配置文件启动并验证 watch / ignore_watch 透传生效 $pm2_runtime app.json $pm2 prettylist | grep watch: \[ server, client \] $pm2 prettylist | grep ignore_watch: \[ node_modules, client/img \]可见pm2-runtime与常规pm2共享同一套应用配置解析与进程管理内核instances、watch、ignore_watch等配置均完整生效容器内外行为保持一致。集成 KeymetricsPM2 Plus监控原文档明确提及示例内含 Keymetrics 集成能力实现方式即 Dockerfile 中的两个环境变量ENV KEYMETRICS_SECRET xxxx ENV KEYMETRICS_PUBLIC yyyy这两个变量在 constants.js 中被正式消费MACHINE_NAME : process.env.INSTANCE_NAME || process.env.MACHINE_NAME || process.env.PM2_MACHINE_NAME, SECRET_KEY : process.env.KEYMETRICS_SECRET || process.env.PM2_SECRET_KEY || process.env.SECRET_KEY, PUBLIC_KEY : process.env.KEYMETRICS_PUBLIC || process.env.PM2_PUBLIC_KEY || process.env.PUBLIC_KEY,也就是说只要在镜像或容器运行时注入合法的KEYMETRICS_SECRET/KEYMETRICS_PUBLIC分别对应密钥对中的 secret 与 publicpm2-runtime在 Runtime4Docker.js 中创建内嵌 PM2 实例时就会自动带上这对密钥从而把应用指标事件循环延迟、内存、HTTP 请求等推送至 Keymetrics 平台INSTANCE_NAME或MACHINE_NAME则用于标识该容器在监控面板中的机器名。与之等效的运行时方式是在docker run时用-e覆盖$ docker run -e KEYMETRICS_SECRET你的secret \ -e KEYMETRICS_PUBLIC你的public \ -e INSTANCE_NAMEmy-container \ docker-pm2-test若暂不使用监控把KEYMETRICS_SECRET/KEYMETRICS_PUBLIC置空或删除即可不影响进程托管主流程。此外constants.js还支持PM2_SECRET_KEY/PM2_PUBLIC_KEY与PM2_MACHINE_NAME等别名变量便于在既有 CI/CD 环境中统一注入。生产化改造建议基于本示例可以继续演进以下是贴合容器/编排场景的实用方向固定镜像 tag将latest-alpine替换为具体版本号如keymetrics/pm2:12-alpine或对应 Node 版本的 tag保证可复现构建多实例负载均衡在process.config.js中设置instances与exec_mode: cluster由 PM2 内置负载均衡器分发请求对应Runtime4Docker.js中-i选项的官方说明健康检查为应用增加/healthz端点并在 Dockerfile 中配置HEALTHCHECK或依赖 K8s liveness/readiness probe与pm2-runtime的退出码语义配合密钥安全KEYMETRICS_SECRET/KEYMETRICS_PUBLIC应通过docker --build-arg、Docker secret 或 K8s ConfigMap/Secret 注入绝不硬编码进镜像日志标准化按需使用--json或--format输出结构化日志便于采集到 ELK/Loki 等日志平台冷启动优化对于频繁启停的短生命周期容器可评估--fast-boot见 lib/binaries/Runtime.js 的--fast-boot选项以复用后台 PM2 实例、缩短二次启动耗时。小结本示例演示的官方镜像 pm2-runtime ecosystem 配置文件三件套是 PM2 官方推荐的容器内进程管理范式pm2-runtime以 no-daemon 模式将 PM2 变为容器主进程统一了进程守护、自动重启、日志聚合与 Keymetrics 监控同时通过 exec 形式CMD与信号处理器保证容器优雅退出。无论是单一服务容器还是需要多实例负载均衡与监控接入的生产集群都可以从 examples/docker-pm2 这套最小示例出发快速落地。赞分享运维CLI可观测性【免费下载链接】pm2Node.js/Typescript/Bun Production Process Manager with a built-in Load Balancer.项目地址https://gitcode.com/gh_mirrors/pm/pm2点击查看免费下载相关推荐FastAPI 容器化部署实战基于官方 Python 镜像从零构建 Docker 镜像FastAPI 容器化部署实战基于官方 Python 镜像从零构建 Docker 镜像 导读 本指南以 docs/hi/docs/deployment/doc后端Web框架API设计Fiora 安装部署完全指南Node.js MongoDB Redis 环境搭建、PM2 守护与 Docker 容器化运行Fiora 安装部署完全指南Node.js MongoDB Redis 环境搭建、PM2 守护与 Docker 容器化运行 本文面向希望从零搭建并运行即时通讯后端前端移动开发Sanic 应用 Docker 化部署实战镜像构建、容器运行与 docker-compose 编排Sanic 应用 Docker 化部署实战镜像构建、容器运行与 docker compose 编排 导读 本文基于 Sanic 官方部署文档完整讲解如何将一后端Web框架上一篇XUnity.AutoTranslator打破语言障碍的Unity游戏翻译神器终极指南下一篇AO3镜像站完全指南3分钟解锁全球同人创作自由创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →