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

docker-compose down后清理动态创建的Docker子容器问题求助

问题描述

使用docker-compose启动generator容器,该容器会动态创建子容器。期望执行docker-compose down时,generator容器先清理所有以test_开头的子容器,再自行关闭。但当前执行docker-compose down后,generator容器直接终止,子容器仍在运行;仅重启generator后再次执行docker-compose down,才会清理上一次创建的子容器。

现有配置

cleanup.sh

#!/bin/bash

#Define cleanup procedure
cleanup() {
    echo "Container stopped, performing cleanup..."
}

#Trap SIGTERM
trap 'cleanup' SIGTERM

#Execute a command
"${@}" &
echo "Stopping docker containers"
docker stop $(sudo docker ps -a -q  -f "name=test_")
docker rm $(sudo docker ps -a -q  -f "name=test_")

#Wait
wait $!

Dockerfile

FROM python:3.10
ENTRYPOINT [ "docker/docker-files/generator/cleanup.sh" ]
ENV PYTHONDONTWRITEBYTECODE=1

ENV PYTHONUNBUFFERED=1

# Install pip requirements
COPY requirements.txt .


RUN python -m pip install -r requirements.txt


RUN apt-get update && \
    apt-get install -yq tzdata ca-certificates curl gnupg sudo && \
    ln -fs /usr/share/zoneinfo/Poland /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata && \
    curl -fsSL https://get.docker.com | sh
        
WORKDIR /opt/app/
COPY . /opt/app/

CMD ["python", "scripts/generator.py"]

docker-compose.yml

version: '3'
services:
  generator:
    image: generator
    build:
      context: .
      dockerfile: ./docker/docker-files/generator/Dockerfile
    tty: true
    working_dir: /opt/app/
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    env_file:
      - ./.env
    environment:
      SERVICE_NAME: generator
      LOG_LINES: 9999:-9999
    restart: always
    networks:
      in-network:
        aliases:
          - generator
解决方案

当前问题核心是cleanup.sh逻辑错误:

  • 启动主进程后立刻执行子容器清理,此时子容器尚未创建,完全无效;
  • 捕获SIGTERM信号的cleanup函数为空,未执行实际清理操作;
  • 容器内挂载docker.sock后,执行docker命令无需sudo,多余的sudo反而可能引发权限问题。

修改后的cleanup.sh如下:

#!/bin/bash

# 定义子容器清理逻辑
cleanup() {
    echo "收到终止信号,开始清理子容器..."
    # 停止所有test_开头的运行中容器,忽略无匹配的错误输出
    docker stop $(docker ps -q -f "name=test_") 2>/dev/null
    # 删除所有test_开头的容器,忽略无匹配的错误输出
    docker rm $(docker ps -a -q -f "name=test_") 2>/dev/null
    echo "子容器清理完成"
    exit 0
}

# 捕获docker-compose down发送的SIGTERM,以及手动终止的SIGINT信号
trap 'cleanup' SIGTERM SIGINT

# 启动主进程并记录PID
"${@}" &
main_pid=$!

# 等待主进程结束
wait $main_pid

同时调整Dockerfile,移除不必要的sudo安装:

FROM python:3.10
ENTRYPOINT [ "docker/docker-files/generator/cleanup.sh" ]
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

# Install pip requirements
COPY requirements.txt .
RUN python -m pip install -r requirements.txt

RUN apt-get update && \
    apt-get install -yq tzdata ca-certificates curl gnupg && \
    ln -fs /usr/share/zoneinfo/Poland /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata && \
    curl -fsSL https://get.docker.com | sh
        
WORKDIR /opt/app/
COPY . /opt/app/

CMD ["python", "scripts/generator.py"]

逻辑说明

  • 脚本启动主进程后进入等待状态,当docker-compose down发送SIGTERM信号时,trap触发cleanup函数执行子容器清理;
  • 添加2>/dev/null避免无匹配容器时输出错误信息,保证日志整洁;
  • 同时捕获SIGINT信号(如Ctrl+C),确保手动终止容器时也能完成子容器清理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:33:30