Ansible docker_compose模块执行与主机SSH手动执行结果不一致问题
问题根因
报错的核心原因是Ansible的docker_compose模块与手动SSH执行docker-compose命令时,对项目目录下文件的权限、上下文处理逻辑存在差异,最终导致容器无法读取/my_entrypoint.sh入口脚本的执行权限。
两种执行方式的核心差异
- 文件处理逻辑不同
手动执行docker-compose -f <path> up -d时,直接读取目标服务器上已存在的本地文件,脚本的可执行权限、SELinux上下文均为之前已配置好的可用状态。而Ansible的docker_compose模块执行时,会先将控制节点的compose配置、关联文件传输到目标节点的临时工作目录,如果传输过程中没有显式保留可执行权限,就会导致脚本权限丢失。 - 运行环境配置差异
Ansible使用非交互式SSH会话执行任务,默认继承的环境变量和手动登录的交互式SSH会话不同。最常见的是umask配置差异:如果手动会话的umask为0022(新文件默认权限为755),而Ansible非交互式会话的umask为0077(新文件默认权限为700),当容器内的运行用户非root时,就无法读取仅有root权限的入口脚本。 - 额外操作逻辑差异
Ansible的docker_compose模块内置了项目校验、临时文件清理等额外操作,部分场景下会重置目标目录下已有的文件权限属性,而原生docker-compose命令不会修改本地已存在的文件属性。
修复方案
- 所有传输入口脚本的Ansible任务(
copy/template模块)显式设置可执行权限:
- name: Copy bitbucket nginx entrypoint copy: src: my_entrypoint.sh dest: "{{ bitbucket__install_path }}/my_entrypoint.sh" mode: '0755' # 必须显式指定执行权限
- 若目标服务器开启了SELinux,可在compose文件的挂载规则后添加
:z标签,自动适配SELinux上下文:
services: nginx: volumes: - ./my_entrypoint.sh:/my_entrypoint.sh:z
- 可在docker_compose任务中显式指定umask,保证文件权限符合预期:
- name: docker compose up docker_compose: project_src: "{{ bitbucket__install_path }}" files: "{{ bitbucket__compose_files }}" state: present register: output environment: umask: '0022'
内容的提问来源于stack exchange,提问作者Oskar Granlund
相关产品推荐
相关产品推荐

