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

Ansible执行成功但无法启动带flock的后台Docker Compose服务求助

问题概述

  • 预期行为:Ansible通过Bash脚本立即启动带flock的Docker Compose,并将日志写入文件。
  • 实际行为:Ansible无法启动服务;Monit通过该Bash脚本可正确启动服务,但存在延迟。
  • 核心需求:通过Ansible调用Bash脚本,无延迟地重启/重建Docker Compose服务。

相关代码与输出

Bash启动脚本(/etc/monit/scripts/start_captain_hook.sh)

#! /bin/bash

lockfile="/var/run/lock/captain-hook"
export ENVIRONMENT=production

cd /home/captain-hook/captain-hook
flock -n "$lockfile" -c "docker-compose up --build --force-recreate >> /var/log/captain-hook/log 2>&1 &"
exit 0

Ansible任务文件

- name: stop container
  command: docker stop captain_hook

- name: Sleep for 10 seconds
  wait_for:
   timeout: 10

- name: start docker-compose
  shell: |
    /etc/monit/scripts/start_captain_hook.sh
  args:
    chdir: /home/captain-hook/captain-hook

Ansible调试关键输出

changed: [trade-cloud] => {
    "changed": true,
    "cmd": "/etc/monit/scripts/start_captain_hook.sh\n",
    "delta": "0:00:00.009671",
    "end": "2022-09-16 10:52:37.669701",
    "rc": 0,
    "start": "2022-09-16 10:52:37.660030",
    "stderr": "",
    "stdout": ""
}

Monit配置文件

# {{ ansible_managed }}

#==================== check start-captain-hook is running =======================
CHECK PROGRAM captainHook WITH PATH /etc/monit/scripts/check_captain_hook.sh
    START PROGRAM = "/etc/monit/scripts/start_captain_hook.sh"
    IF status != 0 FOR 1 CYCLES THEN START

解决方案

1. 修复flock非阻塞导致的执行跳过

脚本中使用flock -n(非阻塞模式),若锁定文件已存在(如之前进程未释放锁),flock会直接跳过执行。可修改为:

  • 去掉-n参数,改为阻塞等待锁:
flock "$lockfile" -c "docker-compose up --build --force-recreate >> /var/log/captain-hook/log 2>&1 &"
  • 或清理无效锁定文件后再执行:
if [ -f "$lockfile" ]; then
  # 检查持有锁的进程是否存活
  if ! ps -p $(cat "$lockfile") > /dev/null 2>&1; then
    rm -f "$lockfile"
  fi
fi
flock -n "$lockfile" -c "docker-compose up --build --force-recreate >> /var/log/captain-hook/log 2>&1 &"

2. 解决Ansible会话关闭导致后台进程终止

Ansible执行完任务后会关闭SSH会话,后台运行的docker-compose可能被终止。修改脚本,用nohup或setsid隔离进程:

flock -n "$lockfile" -c "nohup docker-compose up --build --force-recreate >> /var/log/captain-hook/log 2>&1 &"

或

flock -n "$lockfile" -c "setsid docker-compose up --build --force-recreate >> /var/log/captain-hook/log 2>&1 &"

3. 检查权限问题

  • 确保/var/run/lock/目录权限为drwxrwxrwt,否则flock无法创建锁定文件:
chmod 1777 /var/run/lock/
  • 确保/var/log/captain-hook/目录存在且可写:
mkdir -p /var/log/captain-hook
chmod 755 /var/log/captain-hook

4. 替换为Ansible官方docker-compose模块

避免Shell脚本的兼容性问题,直接使用community.docker.docker_compose模块:

- name: start docker-compose service
  community.docker.docker_compose:
    project_src: /home/captain-hook/captain-hook
    state: present
    build: yes
    recreate: always
  environment:
    ENVIRONMENT: production

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:15:32