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
相关产品推荐
相关产品推荐

