首页 > 解决方案 > 如果图像已更改,用于构建 Docker 映像和重新创建 Docker 容器的 Ansible 工作流程?

问题描述

我一直在努力找出正确的 Ansible 工作流程来部署 Docker 映像并在映像发生更改时重新创建 Docker 容器。

这是我最初认为可行的角色的任务列表:

- name: Deploy Source
  synchronize:
    archive: yes
    checksum: yes
    compress: yes
    dest: '/tmp/{{ app_name }}'
    src: ./

- name: Build Docker Image
  docker_image:
    name: '{{ docker_image_name }}'
    path: '/tmp/{{ app_name }}'
    rm: yes
    state: present
  register: build_docker_image

- name: Create Docker Container
  docker_container:
    image: '{{ docker_image_name }}'
    keep_volumes: yes
    name: '{{ docker_container_name }}'
    recreate: '{{ true if build_docker_image.changed else omit }}'
    state: started

这不起作用,因为 Ansibledocker_image模块不提供state: latest选项。state: present只检查图像是否存在,而不检查它是否是最新的。这意味着即使Dockerfile已更改,也不会重建映像。docker_image确实提供了一个force: yes选项,但是无论Dockerfile. 使用时force: yes,我觉得最好总是重新创建运行镜像的容器,以防止它们指向悬空的 Docker 镜像。

我错过了什么?有更好的选择吗?

标签: dockeransible

解决方案


用户 viggeh 在 Ansible GitHub 上提供了一种解决方法,我已经根据我的需要进行了调整,如下所示:

- name: Deploy Source
  synchronize:
    archive: yes
    checksum: yes
    compress: yes
    dest: '/tmp/{{ app_name }}'
    src: ./

- name: Get Existing Image ID
  command: 'docker images --format {% raw %}"{{.ID}}"{% endraw %} --no-trunc {{ docker_image_name }}:{{ docker_image_tag }}'
  register: image_id
  changed_when: image_id.rc != 0

- name: Build Docker Image
  docker_image:
    force: yes
    name: '{{ docker_image_name }}'
    path: '/tmp/{{ app_name }}'
    rm: yes
    state: present
    tag: '{{ docker_image_tag }}'
  register: image_build
  changed_when: image_id.stdout != image_build.image.Id

- name: Create Docker Container
  docker_container:
    image: '{{ docker_image_name }}'
    keep_volumes: yes
    name: '{{ docker_container_name }}'
    recreate: '{{ True if image_build.changed else omit }}'
    state: started

推荐阅读