Ansible本地构建Docker镜像未生成问题排查及配置咨询
问题背景
目录结构
build ├── docker-compose.dev.yml ├── playbooks │ ├── deploy-deps.yml │ └── setup-local-registry.yml ├── postgres │ └── DockerFile └── rabbitmq ├── DockerFile └── init.sh deploy-scripts ├── db-schema │ └── global │ ├── 01-init.sql │ ├── 02-tables.sql │ ├── 03-grant.sql │ └── 04-index.sql ├── rabbitmq │ └── global │ └── prepare-queues.sh
现有配置
Ansible Playbook
- hosts: localhost vars: registry_host: "localhost" registry_port: 5000 i_postgres_image: "orderpostgres" tasks: - name: "Create & Push Postgres Image" docker_image: name: "{{ i_postgres_image }}" build: path: "../../build/postgres" source: build state: present register: "out" - name: Show test output debug: msg: "{{ out }}"
Postgres DockerFile
FROM postgres:10.17-buster COPY ../deploy-scripts/db-schema/global /docker-entrypoint-initdb.d/
docker-compose.dev.yml 参考配置
version: '3' services: redis: image: redis:5.0 container_name: 'cache' ports: - 6379:6379 volumes: - ~/.docker-volume/redis/data/:/var/lib/redis postgres: build: context: ../ dockerfile: ./build/postgres/DockerFile container_name: 'database' restart: always environment: - POSTGRES_USER=haha - POSTGRES_PASSWORD=haha - POSTGRES_DB=haha logging: options: max-size: 10m max-file: '3' ports: - 5432:5432 volumes: - ~/.docker-volume/postgres/data/:/var/lib/postgresql/data
现象描述
从项目根目录执行ansible-playbook,返回运行成功:
[WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [localhost] *********************************************************************************************************************************************************************************************** TASK [Gathering Facts] ***************************************************************************************************************************************************************************************** ok: [localhost] TASK [Create & Push Postgres Image] **************************************************************************************************************************************************************************** changed: [localhost] TASK [Show test output] **************************************************************************************************************************************************************************************** ok: [localhost] => { "msg": { "actions": [ "Built image orderpostgres:latest from ../../build/postgres" ], "changed": true, "failed": false, "image": null, "stdout": "", "stdout_lines": [] } } PLAY RECAP ***************************************************************************************************************************************************************************************************** localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
但执行docker images查看本地镜像,找不到构建的orderpostgres镜像:
docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry 2 b2cb11db9d3d 3 days ago 26.2MB
问题咨询
- 不调整现有目录结构、不修改现有DockerFile的前提下,如何解决该问题?
- 如何配置Ansible docker模块实现自定义构建上下文?
- 为什么本次构建实际失败但Ansible docker模块未抛出错误,反而返回成功结果?
解答
问题1:不调整目录结构、不修改DockerFile的解决方案
仅需调整Ansible playbook中docker_image模块的构建参数,和docker-compose的逻辑对齐即可:将构建上下文设为项目根目录,同时显式指定Dockerfile的路径。调整后的playbook任务配置如下:
- name: "Create & Push Postgres Image" docker_image: name: "{{ i_postgres_image }}" build: # 构建上下文指定为项目根目录(从playbook所在的build/playbooks目录出发向上跳两级就是根目录) path: "../../" # 显式指定Dockerfile的相对路径,相对于上面的构建上下文 dockerfile: "./build/postgres/DockerFile" source: build state: present register: "out"
该配置和现有docker-compose的build逻辑完全一致,不需要修改任何原有文件和目录结构即可正常构建镜像。
问题2:Ansible docker模块自定义构建上下文的配置方法
Ansible的docker_image模块完全支持自定义构建上下文,对应参数就是build下的path字段:
build.path:就是Docker构建的上下文路径,等价于docker build命令最后跟的路径参数,也等价于docker-compose里的build.context配置- 如果需要指定上下文之外的Dockerfile,额外加
build.dockerfile字段即可,值为Dockerfile相对于build.path的路径,等价于docker build的-f参数,也等价于docker-compose里的build.dockerfile配置
之前的配置错误核心是误以为build.path是Dockerfile的存放路径,实际上它是构建上下文的路径。
问题3:构建失败但Ansible返回成功的原因
这个是旧版Ansible docker_image模块的已知问题:
- 原有配置中,构建上下文是
../../build/postgres,Dockerfile里的COPY ../deploy-scripts/...会尝试访问上下文之外的路径,Docker本身会抛出COPY failed: Forbidden path outside the build context错误 - 旧版的Ansible docker模块没有正确捕获Docker daemon返回的构建错误,错误判断构建状态为成功,同时返回
image: null的异常结果(正常构建成功的话image字段会返回镜像的详细元数据,不会为null) - 可以通过升级Ansible的
community.docker集合到最新版本解决这个问题,新版已经修复了错误捕获的逻辑,构建失败时会正确抛出异常信息。
内容的提问来源于stack exchange,提问作者Sathish
相关产品推荐
相关产品推荐

