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

如何在运行中的Docker容器内用Python脚本更新镜像并重启容器?

问题描述

我遇到了Docker容器更新的问题,具体场景和现象如下:

  • 现有基于1.0.1版本镜像的Python应用Docker容器,通过shell脚本以--restart=always选项启动,使用latest标签,运行正常。
  • 手动关闭(Alt-F4)容器后,容器能按预期自动重启。
  • 在运行的1.0.1容器内,通过Docker SDK for Python从DockerHub拉取1.0.2版本镜像,标记为latest后,调用client.containers.get("mycontainername").restart()尝试重启容器。

成功的操作:新镜像已拉取并本地标记为latest,容器能停止,本地可见1.0.2镜像且与latest镜像ID一致。
未达预期的结果:容器停止后无法自动重启;调用stop()停止容器也无法触发自动重启。
额外观察:

  1. 重新执行启动shell脚本后,运行的仍是基于旧1.0.1镜像的容器(尽管脚本用了latest标签)。
  2. 当前运行的容器始终基于1.0.1版本镜像。
  3. 系统重启后,会基于正确的1.0.2版本镜像创建新容器。

我的问题:如何在运行中的容器内通过Python脚本更新镜像,并重启基于新镜像的容器?

解决方案

问题核心在于:Docker的restart()操作只是重启现有容器的进程,不会重新拉取latest镜像或创建新容器;而--restart=always规则仅触发现有容器的重启,不会自动基于新镜像重建容器。要实现基于新镜像启动容器,需要删除旧容器并重新创建。

步骤说明

  1. 拉取新版本镜像并标记为latest(你已完成这一步)。
  2. 停止目标容器。
  3. 删除已停止的旧容器。
  4. 使用与原容器相同的配置(端口映射、卷挂载、环境变量、--restart=always等),基于latest镜像重新创建并启动容器。

代码示例

import docker

def update_and_restart_container(client, container_name, image_name, container_config):
    # 1. 拉取新镜像并标记为latest(若未完成可取消注释以下代码)
    # client.images.pull(f"{image_name}:1.0.2")
    # client.images.get(f"{image_name}:1.0.2").tag(image_name, tag="latest")

    # 2. 停止目标容器
    container = client.containers.get(container_name)
    container.stop()

    # 3. 删除旧容器
    container.remove()

    # 4. 基于latest镜像重新创建并启动容器,复用原配置
    new_container = client.containers.run(
        image=f"{image_name}:latest",
        name=container_name,
        restart_policy={"Name": "always"},  # 对应--restart=always
        ports=container_config["ports"],    # 原容器的端口映射
        volumes=container_config["volumes"],# 原容器的卷挂载
        environment=container_config["env"],# 原容器的环境变量
        detach=True  # 后台运行
    )
    return new_container

# 初始化Docker客户端
client = docker.from_env()

# 动态获取原容器的配置信息
original_container = client.containers.get("mycontainername")
container_config = {
    "ports": original_container.attrs["HostConfig"]["PortBindings"],
    "volumes": original_container.attrs["HostConfig"]["Binds"],
    "env": original_container.attrs["Config"]["Env"]
}

# 执行更新重启
update_and_restart_container(client, "mycontainername", "your-image-name", container_config)

关键注意事项

  • 必须确保重新创建容器时复用原容器的所有必要配置(端口、卷、环境变量等),否则新容器可能无法正常工作。
  • 命名卷默认不会随容器删除而消失,绑定挂载的本地文件也会保留,无需担心数据丢失;若使用临时卷,需提前做好数据备份。
  • 若启动脚本包含--network、--user等自定义参数,需在containers.run()中对应添加这些参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:52:30