在容器化技术日益普及的今天,Docker 已成为部署 Node.js 服务的常用选择。
同时,PM2 作为一个进程管理工具,也常被用于管理 Node.js 进程。
两者都提供了进程崩溃时的自动重启功能。
docker 重启
写个 dockerfile:
dockerfile
FROM node:18-alpine
WORKDIR /app
COPY ./index.js .
CMD ["node", "/app/index.js"]
写如下代码:
打包镜像:
dockerfile
docker build -t restart-test:v1.0 .
运行镜像:
dockerfile
docker run -d --name=restart-test-container restart-test:v1.0
1s 之后,容器就停掉了。
我们可以在 docker run 的时候通过 --restart 指定重启策略:
bash
docker run -d --restart=always --name=restart-test-container2 restart-test:v1.0
always 总是尝试重启容器。
打印了很多次错误日志:
你可以点击停止,就不会再重启了。
--restart 还有一些参数:
no
:这是默认的重启策略。当容器退出时,不会尝试重启它。on-failure
::仅在容器非正常退出时自动重启。可以指定重启次数,如on-failure:3
表示最多重启三次。unless-stopped
:除非手动停止,否则容器总是自动重启。与always
类似,但区别在于当 Docker 守护进程重启时,unless-stopped
策略的容器不会自动重启。
pm2 重启
新建 pm2.Dockerfile:
dockerfile
FROM node:18-alpine
WORKDIR /app
COPY ./index.js .
RUN npm install -g pm2
CMD ["pm2-runtime", "/app/index.js"]
然后 build 一下,生成镜像:
bash
docker build -t restart-test:v2.0 -f pm2.Dockerfile .
然后跑一下:
bash
docker run -d --name=restart-test-container3 restart-test:v2.0
这时候会发现容器一直是运行状态,但是内部的进程一直在重启:
也就是说,Docker 的自动重启功能和 PM2 的自动重启功能是重合的。
选择哪个重启
在大多数情况下,使用 Docker 的自动重启功能已经足够满足需求,无需再使用 PM2。特别是当使用容器编排工具(如Kubernetes)时,更倾向于让容器编排工具来管理容器的重启和调度。
如果只是 Docker 部署,可以考虑结合 pm2 来做进程的重启,可能会更快点。
docker compose 配置 restart
Docker Compose 是用于同时跑多个 Docker 容器的,它自然也支持 restart 的配置: