You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于docker-compose实现React/Node.js应用的零停机部署?

嘿,我来帮你搞定React应用的零停机部署问题!你当前用docker down/up的方式确实会导致2-3分钟的服务中断,咱们可以利用docker-compose的滚动更新和扩缩容能力来实现无缝部署,下面是具体的方案:

一、先调整部署基础:把React打包成独立Docker镜像

你现在直接替换本地dist目录再重启容器的方式,没法做到逐个容器更新(如果是挂载本地目录的话,所有容器共享同一个目录)。所以第一步要把React应用打包成包含构建产物的Docker镜像,这样每个容器都是独立的版本实例。

  1. 给React项目写个Dockerfile(用多阶段构建,既精简镜像又避免冗余依赖):
# 第一阶段:构建静态文件
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci # 用ci代替install,保证依赖版本一致
COPY . .
RUN npm run build # 执行webpack构建

# 第二阶段:用nginx作为生产服务器
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html # 把构建好的dist复制到nginx目录
COPY nginx.conf /etc/nginx/conf.d/default.conf # 可以自定义nginx配置,比如gzip、路由重写
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
  1. 每次更新代码后,构建新镜像并打上唯一标签(比如版本号、commit hash或者时间戳,千万别用latest,否则docker-compose可能识别不到更新):
docker build -t my-react-app:v20240520 .

二、配置docker-compose支持滚动更新

修改你的docker-compose.yml,给React服务添加滚动更新的规则,确保更新时先启动新容器再停旧容器:

version: '3.8'
services:
  react-app:
    image: my-react-app:v20240520 # 替换成你刚构建的镜像标签
    ports:
      - "80:80"
    deploy:
      replicas: 2 # 先启动2个实例,保证更新时总有一个容器在运行
      update_config:
        parallelism: 1 # 每次只更新1个容器
        delay: 10s # 等待10秒再更下一个,给新容器足够的启动时间
        order: start-first # 核心!先启动新容器,确认正常后再停旧容器
        failure_action: rollback # 如果更新失败,自动回滚到旧版本
      restart_policy:
        condition: on-failure
    healthcheck:
      # 配置健康检查,确保新容器真的能正常提供服务
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 10s
      timeout: 5s
      retries: 3
  # 你的Node.js服务配置...

三、零停机部署的具体流程

现在部署新代码就不用docker down了,流程变成:

  1. 拉取最新代码,构建新的React镜像(比如标签换成v20240521):
docker build -t my-react-app:v20240521 .
  1. 更新docker-compose里的镜像标签,然后执行滚动更新:
docker-compose up -d --no-deps react-app
  • -d:后台运行服务
  • --no-deps:不重启依赖的其他服务(比如你的Node.js服务)
  • react-app:指定只更新这个服务

docker-compose会自动按照你配置的update_config规则来:先启动一个新的v20240521容器,等健康检查通过后,停掉一个旧的v20240520容器,再启动第二个新容器,停掉第二个旧容器,全程服务不会中断。

  1. 你可以用docker-compose logs -f react-app实时查看日志,确认所有新容器都正常启动。
  2. 最后可以清理掉旧版本的镜像(可选):
docker image prune -f

如果你暂时不想改镜像构建方式(不推荐)

要是你还想继续用本地构建dist再部署的方式,也可以用临时容器过渡:

  1. 先启动一个临时的React容器,挂载新的dist目录,映射到另一个端口测试:
docker-compose run --name react-temp -p 8080:80 react-app
  1. 访问http://localhost:8080确认临时容器正常运行。
  2. 停掉旧的React容器:
docker-compose stop react-app
  1. 启动新的React容器(此时挂载的是更新后的dist):
docker-compose up -d react-app
  1. 确认新容器正常后,删除临时容器:
docker rm react-temp

不过这种方式还是会有短暂的停机间隙(旧容器停到新容器启动的时间),不如镜像滚动更新可靠,所以优先推荐第一种方案。

内容的提问来源于stack exchange,提问作者Hirad Roshandel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:19:40