Docker Compose服务启停前执行代码及Tailscale优雅关闭咨询
Docker Compose 服务启停前后执行代码的通用方案
方法1:利用 Docker Compose 生命周期钩子(推荐,v2.20+)
Docker Compose 从v2.20版本开始支持服务生命周期钩子,可直接在服务启动前(pre_start)和停止前(pre_stop)执行命令,无需修改原有服务的核心配置。
全局复用配置(通过 YAML 锚点)
定义一套基础钩子配置,让所有服务继承,实现通用逻辑:
x-hooks: &default-hooks lifecycle: pre_start: exec: command: ["echo", "up"] pre_stop: exec: command: ["echo", "down"] services: service1: image: nginx <<: *default-hooks service2: image: redis <<: *default-hooks
方法2:通用 Entrypoint 脚本挂载
若你的环境不支持生命周期钩子,可通过挂载自定义脚本替换容器原有 entrypoint,实现启动前执行代码、停止时响应信号做清理的效果。
- 本地创建
entrypoint.sh脚本:
#!/bin/sh # 启动前执行逻辑 echo "up" # 停止信号处理函数 cleanup() { echo "down" exit 0 } # 捕获容器停止时的默认信号 trap cleanup SIGTERM SIGINT # 执行容器原有命令/entrypoint exec "$@" & # 等待子进程,确保信号能被捕获 wait $!
- 在 Docker Compose 中给所有服务挂载该脚本:
services: service1: image: nginx entrypoint: /entrypoint.sh volumes: - ./entrypoint.sh:/entrypoint.sh:ro service2: image: redis entrypoint: /entrypoint.sh volumes: - ./entrypoint.sh:/entrypoint.sh:ro
注意:部分镜像的 entrypoint 逻辑复杂,需先通过docker inspect <镜像名>确认原有 entrypoint 路径,再调整脚本逻辑适配。
针对 Tailscale 服务的停止清理方案
针对你提供的 Tailscale 服务配置,可直接修改command字段,添加信号捕获逻辑执行tailscale down,无需创建 Dockerfile:
修改后的docker-compose.yml:
services: tailscale: image: tailscale/tailscale hostname: tailscale environment: TS_AUTH_KEY: ${TS_AUTH_KEY} cap_add: - net_admin command: | /bin/sh -c ' # 停止清理函数 cleanup() { echo "Executing tailscale down..." tailscale down exit 0 } # 捕获容器停止信号 trap cleanup SIGTERM SIGINT # 原有 Tailscale 启动逻辑 tailscaled --tun=userspace-networking & until tailscale up --ssh --authkey="$TS_AUTH_KEY"; do sleep 0.1; done # 等待信号,替代 sleep infinity 确保能响应停止请求 wait '
逻辑说明:
- 用
trap捕获 Docker 停止容器时发送的SIGTERM和SIGINT信号 - 收到停止信号时,先执行
tailscale down完成清理,再退出容器 - 用
wait替代sleep infinity,保证容器能正确响应停止指令,而非忽略信号
内容的提问来源于stack exchange,提问作者Hnus
相关产品推荐
相关产品推荐

