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

如何实现ReactJS应用Docker镜像更新触发拉取与容器重启

React应用容器化一键升级方案落地步骤

前置配置修正

你现有配置存在端口冲突隐患:Nginx配置监听7001端口,同时环境变量REACT_APP_API_ADDRESS也指向http://localhost:7001,如果后续后端接口使用7001端口会直接冲突。建议将前端Nginx默认监听端口改为80,容器启动时再做7001:80的端口映射即可。

前端版本检测逻辑实现

不需要引入额外依赖,按以下步骤实现即可:

  • 调整前端项目构建脚本,每次执行yarn build时自动在构建产物根目录生成version.json,写入当前版本标识(可取package.json的version字段、Git提交Hash或构建时间戳)。修改package.json的build脚本:
"scripts": {
  "build": "react-scripts build && node -e \"const fs = require('fs'); const pkg = require('./package.json'); fs.writeFileSync('./build/version.json', JSON.stringify({version: pkg.version, buildTime: Date.now()}))\""
}
  • 前端加定时轮询逻辑(建议间隔3-5分钟),请求/version.json?t=${Date.now()}(拼接时间戳是为了跳过浏览器缓存),将拿到的版本号和应用初始化时本地存储的版本号对比,不一致就触发你已经实现的更新提示弹窗。
  • 用户点击弹窗确认更新按钮时,向升级服务发送POST请求触发升级流程即可。

注意:必须给version.json的请求加随机参数,同时在Nginx配置中给该文件设置不缓存规则,否则缓存会导致版本检测完全失效。

升级服务(hook_upgrade_server)实现

选择轻量方案实现即可,核心要求是容器必须挂载宿主机docker.sock才能操作宿主机Docker实例,以下是可直接复用的实现:

  1. 新建服务入口文件app.py,核心逻辑包含镜像拉取、旧容器销毁、新容器启动三个步骤:
from flask import Flask, request
import subprocess

app = Flask(__name__)

# 可通过环境变量自定义配置
CONTAINER_NAME = "reactjs_app"
IMAGE_NAME = "替换为你的DockerHub镜像地址/reactjs:latest"
PORT_BIND = "7001:80"
AUTH_TOKEN = "替换为自定义的校验token,防止接口被恶意调用"

@app.post("/trigger-upgrade")
def run_upgrade():
    # 简单token校验
    req_token = request.headers.get("X-Upgrade-Token", "")
    if req_token != AUTH_TOKEN:
        return {"code": 403, "msg": "无操作权限"}, 403
    try:
        # 拉取最新镜像
        subprocess.run(
            ["docker", "pull", IMAGE_NAME],
            check=True,
            capture_output=True,
            text=True
        )
        # 强制删除旧容器
        subprocess.run(["docker", "rm", "-f", CONTAINER_NAME], capture_output=True)
        # 启动新容器
        subprocess.run(
            [
                "docker", "run", "-d",
                "--name", CONTAINER_NAME,
                "-p", PORT_BIND,
                "--restart", "always",
                IMAGE_NAME
            ],
            check=True,
            capture_output=True,
            text=True
        )
        return {"code": 0, "msg": "升级触发成功,服务即将重启"}
    except subprocess.CalledProcessError as e:
        return {"code": 500, "msg": f"升级执行失败: {e.stderr}"}, 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=9000)
  1. 给升级服务编写Dockerfile:
FROM python:alpine
WORKDIR /app
# 安装依赖和Docker CLI
RUN pip install flask && apk add --no-cache docker-cli
COPY app.py .
EXPOSE 9000
CMD ["python", "app.py"]

配置调整与部署步骤

  1. 修改前端Nginx配置,调整监听端口并给version.json设置不缓存规则,修改后配置如下:
server {
  listen 80;
  server_name _;

  index index.html;
  root /usr/share/nginx/html;

  error_log /var/log/nginx/error.log;
  access_log /var/log/nginx/access.log;

  # version.json不缓存,保证版本检测实时生效
  location /version.json {
    add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate";
    add_header Pragma "no-cache";
    add_header Expires "0";
    try_files $uri =404;
  }

  location / {
    try_files $uri /index.html =404;
  }
}
  1. 重新构建前端镜像,推送到Docker Hub。
  2. 构建升级服务镜像,启动时必须挂载宿主机docker.sock,启动命令参考:
docker run -d \
  --name hook_upgrade_server \
  -p 9000:9000 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --restart always \
  替换为你的升级服务镜像地址:latest
  1. 启动前端业务容器:
docker run -d \
  --name reactjs_app \
  -p 7001:80 \
  --restart always \
  替换为你的前端镜像地址:latest

可选优化项

  • 升级逻辑中可增加镜像ID对比步骤,拉取最新镜像后对比当前运行容器的镜像ID,若ID一致则跳过重启,避免无意义的服务中断。
  • 前端触发升级后可增加3-5秒倒计时,待容器重启完成后自动刷新页面加载新版本。
  • 升级服务可增加操作日志记录,方便排查升级失败问题。

内容的提问来源于stack exchange,提问作者Frank AK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 00:16:03