This article is the 24th day article of MicroAd Advent Calendar 2020 --Qiita.
At MicroAd, we have prepared a Docker container with the production schema of MySQL and used it for testing by the development team. As for this, the one that was synchronized with the latest schema by daily execution was prepared, but since multiple development projects proceed in parallel, there is a request that "I want to test with the schema before the update comes in". I did. Until now, the MySQL administrator manually executed the build and push of the container every time there was a request, but so that the developer can also do this, build a build push mechanism using Ansible and AWX. I tried to.
Playbook
---
- name:Build and push Docker image
hosts: "{{ docker_operation_host }}"
gather_facts: no
vars:
github_repository_name: docker-images-mysqldb
tasks:
- name:Get the GitHub repository
git:
repo: git@{{ github_domain }}/{{ github_organization }}/{{ github_repository_name }}
dest: /opt/{{ github_repository_name }}
accept_hostkey: true
no_log: true
- name:Log in to the Docker registry
docker_login:
registry_url: "{{ docker_registry_domain }}"
username: "{{ docker_registry_user }}"
password: "{{ docker_registry_token }}"
no_log: true
- name:Pull the image of the latest tag as a build cache
docker_image:
name: "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_hostname }}"
tag: latest
source: pull
- name:Build the image and push it to the Docker registry
docker_image:
build:
path: /opt/{{ github_repository_name }}/images/{{ mysql_hostname }}
cache_from:
- "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_hostname }}:latest"
args:
MYSQL_HOSTNAME: "{{ mysql_hostname }}"
MYSQL_USER: "{{ mysql_docker_user }}"
MYSQL_PASSWORD: "{{ mysql_docker_password }}"
name: "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_hostname }}"
tag: "{{ lookup('pipe','date +%Y%m%d') }}"
push: yes
source: build
no_log: true
- name:Delete pushed image from local
docker_image:
state: absent
name: "{{ docker_registry_domain }}/{{ github_organization }}/{{ mysql_db_name }}"
tag: "{{ lookup('pipe','date +%Y%m%d') }}"
Since the Dockerfile of MySQL is managed on the GitHub repository, we first clone the repository to the host where the Docker image is built, build it on the host, and then push it to the Docker registry.
Build with the execution date in YYYYMMDD format as a tag by setting tag:" {{lookup ('pipe','date +% Y% m% d')}} "
in the docker_image
task. Will be pushed.
github_domain
: GitHub domain name to get the repository
github_organization
: The organization name of GitHub to get the repository
github_repository_name
: Get the GitHub repository
docker_registry_domain
: Domain name of the Docker registry to push
docker_registry_user
: Username to log in to the Docker registry
docker_registry_token
: Token of the user logging in to the Docker registry
mysql_hostname
: MySQL hostname to create the image
mysql_docker_user
: User to get the MySQL schema (requires SELECT privilege)
mysql_docker_password
: MySQL user password
Of these variables, those that are not given in the playbook are given values with group_vars (confidential information is encrypted with ansible-vault) or additional variables of Ansible AWX.
Dockerfile
FROM mysql:8.0
ARG MYSQL_HOSTNAME=unknown
ARG MYSQL_USER=unknown
ARG MYSQL_PASSWORD=unknown
RUN apt-get update && apt-get install -y --no-install-recommends wget && rm -rf /var/lib/apt/lists/* && \
#Import MySQL schema
mysqldump -h${MYSQL_HOSTNAME} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -B xxxx_db --no-data --lock-tables=false --set-gtid-purged=OFF > /docker-entrypoint-initdb.d/dump.sql
#Arguments passed from the outside(Passed during docker build)
ARG GIT_REVISION=unknown
ARG GIT_ORIGIN=unknown
ARG IMAGE_NAME=unknown
LABEL git-revision=$GIT_REVISION \
git-origin=$GIT_ORIGIN \
image-name=$IMAGE_NAME
Since the MySQL image provided by the Oracle official has the function to execute the SQL file under /docker-entrypoint-initdb.d/
at build time, the schema information is provided by the --no-data
option of mysqldump. Create a dump file with only the fetched environment and generate a Docker image with the same schema as the fetched environment.
The above file is cloned to the environment where Docker is built, and mysqldump can be executed by passing arguments such as MYSQL_HOSTNAME
from Ansible in the docker_image
task.
By creating a job template using the above playbook on Ansible AWX and granting job execution authority to users of the development team, pushing the Docker image can be completed with one click job execution. ..
Recommended Posts