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

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,实现启动前执行代码、停止时响应信号做清理的效果。

  1. 本地创建entrypoint.sh脚本:
#!/bin/sh

# 启动前执行逻辑
echo "up"

# 停止信号处理函数
cleanup() {
    echo "down"
    exit 0
}

# 捕获容器停止时的默认信号
trap cleanup SIGTERM SIGINT

# 执行容器原有命令/entrypoint
exec "$@" &

# 等待子进程,确保信号能被捕获
wait $!
  1. 在 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:55:17