如何动态检测docker-compose是否启动/重启容器?是否有terraform plan类预览?
针对你提到的两个问题,我整理了几个实用且相对优雅的方案,分别对应预览操作和动态判断容器状态:
一、类似Terraform Plan的预览功能:提前知道Docker Compose将要执行的操作
Docker Compose(尤其是v2版本)提供了直接的方式来预览up命令会触发的变更,不需要实际执行容器操作:
使用
docker compose up --dry-run命令
这个参数会模拟执行up流程,输出所有将要进行的操作,比如哪些容器会被创建、启动、重启,哪些容器状态不会变化。示例输出类似:Container my-app-1 Creating Container my-db-1 Restarting Container redis-1 Running (unchanged)注意:这个功能在Docker Compose v2.10.0+版本中正式支持,如果你还在使用v1(
docker-compose命令),建议升级到v2;如果暂时无法升级,也可以用docker-compose config --dry-run结合配置差异分析,但前者体验要好得多。额外技巧:结合
--quiet减少冗余输出
如果你只关心有变更的容器,可以加上--quiet参数,这样只会输出需要变更的容器名称:docker compose up --dry-run --quiet
二、动态判断指定容器是否被本次up启动/重启
要区分容器是本来就运行的,还是本次up才启动/重启的,有几种相对优雅的实现方式:
方案1:提前记录容器状态,执行后对比
这是最直观且准确性高的方法,通过在up前后分别获取容器的状态和启动时间,进行对比:
执行
up前,记录目标容器的状态和启动时间
比如针对名为my-app的服务,执行:# 获取容器ID(如果服务有多个实例,需调整逻辑遍历所有实例) CONTAINER_ID=$(docker compose ps -q my-app) # 记录当前是否运行,以及启动时间 BEFORE_RUNNING=$(docker inspect --format '{{.State.Running}}' $CONTAINER_ID) BEFORE_STARTED_AT=$(docker inspect --format '{{.State.StartedAt}}' $CONTAINER_ID)执行
docker compose up命令docker compose up -d my-app执行后,再次获取状态和启动时间,对比判断
AFTER_RUNNING=$(docker inspect --format '{{.State.Running}}' $CONTAINER_ID) AFTER_STARTED_AT=$(docker inspect --format '{{.State.StartedAt}}' $CONTAINER_ID) # 判断逻辑 if [ "$BEFORE_RUNNING" = "false" ] && [ "$AFTER_RUNNING" = "true" ]; then echo "容器my-app是本次up启动的" elif [ "$BEFORE_RUNNING" = "true" ] && [ "$BEFORE_STARTED_AT" != "$AFTER_STARTED_AT" ]; then echo "容器my-app是本次up重启的" else echo "容器my-app原本就处于运行状态,未被本次up变更" fi
方案2:监听Docker事件流
Docker本身提供了事件监听功能,可以实时捕获容器的start、restart事件,结合up命令的执行时间,判断是否是本次操作触发的:
先记录
up命令的开始时间START_TIME=$(date -u +"%Y-%m-%dT%H:%M:%S.%NZ")后台启动事件监听,过滤目标容器的相关事件
比如监听my-app服务对应的容器的start和restart事件:docker events --filter "container=$(docker compose ps -q my-app)" --filter "event=start" --filter "event=restart" --since "$START_TIME" & EVENT_PID=$!执行
docker compose up命令docker compose up -d my-app停止事件监听,检查是否捕获到事件
kill $EVENT_PID # 如果有输出,说明容器被启动/重启了这个方案的优势是可以实时感知容器状态变化,不需要前后两次查询,适合脚本自动化场景。
方案3:解析Docker Compose的输出日志
虽然你提到解析日志不够优雅,但如果是简单场景,这个方法最快捷:
执行up命令时,直接过滤包含目标容器名和Starting/Restarting关键字的输出:
docker compose up -d my-app 2>&1 | grep -E "(Starting|Restarting) my-app"
如果有输出,说明容器被本次up启动或重启了;没有输出则说明容器原本就运行,未变更。
内容的提问来源于stack exchange,提问作者Dotan




