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

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

问题咨询

  1. 不调整现有目录结构、不修改现有DockerFile的前提下,如何解决该问题?
  2. 如何配置Ansible docker模块实现自定义构建上下文?
  3. 为什么本次构建实际失败但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模块的已知问题:

  1. 原有配置中,构建上下文是../../build/postgres,Dockerfile里的COPY ../deploy-scripts/...会尝试访问上下文之外的路径,Docker本身会抛出COPY failed: Forbidden path outside the build context错误
  2. 旧版的Ansible docker模块没有正确捕获Docker daemon返回的构建错误,错误判断构建状态为成功,同时返回image: null的异常结果(正常构建成功的话image字段会返回镜像的详细元数据,不会为null)
  3. 可以通过升级Ansible的community.docker集合到最新版本解决这个问题,新版已经修复了错误捕获的逻辑,构建失败时会正确抛出异常信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:45:03