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

