Search code examples
dockerdocker-composeansibledockerfileansible-galaxy

Running local ansible to create local docker Image


Directory Structure

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

I'm trying to create docker image using ansible. Here is my playbook yml

- 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 }}"

My Postgres DockerFile

FROM postgres:10.17-buster
COPY ../deploy-scripts/db-schema/global /docker-entrypoint-initdb.d/

When i execute ansible-playbook from the project root directory, this is result of the execution.

[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

Based on the output I expected the docker image to be built and ready to push to local registry. But when I execute, docker images I'm not seeing that image at all.

docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
registry     2         b2cb11db9d3d   3 days ago   26.2MB

My analysis until now:

My DockerFile has to copy some scripts from the root path of the project that is the reason it has "../scripts/db-schema". I cannot change this path because the same DockerFile is being used by my docker-compose.dev.yml file inside the build directly for creating dev containers.

I am guessing docker image creation is failing, but ansible module does not throw an error and provides output as success.

Second, ansible docker module does not have config to customize the build context like docker-compose allows in the yml.

Here is my docker-compose.dev.yml for reference

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

My Questions:

  1. How can i solve this problem ? Without rearranging possible and not changing the existing DockerFile
  2. How to configure ansible docker module to the custom context ?
  3. Why is ansible docker module is not throwing error ?

Repro Repo: https://github.com/sathishsoundharajan/ansible-repro

It has files required to reproduce the issue in anyone local


Solution

  • Fixed by doing following changes

    postgres/Dockerfile

    FROM postgres:10.17-buster
    COPY deploy-scripts/db-schema/global /docker-entrypoint-initdb.d/
    

    Ansible Playbook

    - hosts: localhost
      vars:
        registry_host: "localhost"
        registry_port: 5000
        i_postgres_image: "order-postgres"
      tasks:
        - name: "Pull & Initialize Postgres Image"
          docker_image:
            name: "{{ i_postgres_image  }}"
            build:
              path: ../../
              dockerfile: build/postgres/Dockerfile
            source: build
            state: present
    
        - name: "Tag & Push to registry"
          register: "out"
          docker_image:
            name: "{{ i_postgres_image }}"
            repository: "{{ registry_host }}:{{ registry_port }}/{{ i_postgres_image }}"
            push: yes
            source: local
    
        - name: Show test output
          debug:
            msg: "{{ out }}"