Image Build #
Ansible bukan hanya untuk menjalankan container — ia juga bisa mengotomasi proses membangun image. Mengintegrasikan build image ke dalam playbook memungkinkan kamu mengontrol seluruh lifecycle: dari persiapan kode, build image, push ke registry, hingga deployment ke server production, semuanya dalam satu alur yang terdokumentasi. Artikel ini membahas bagaimana mengotomasi proses build Docker image menggunakan Ansible.
Build Image dengan docker_image #
Module community.docker.docker_image mendukung build image dari Dockerfile:
- name: Build Docker image aplikasi
community.docker.docker_image:
name: registry.company.com/myapp
tag: "{{ app_version }}"
source: build
build:
path: /opt/app/src # Direktori yang berisi Dockerfile
dockerfile: Dockerfile # Default, bisa dikustomisasi
args:
APP_VERSION: "{{ app_version }}"
BUILD_DATE: "{{ ansible_date_time.iso8601 }}"
pull: true # Pull base image terbaru sebelum build
nocache: false # Gunakan build cache jika tersedia
state: present
register: build_result
- name: Tampilkan image ID yang dihasilkan
debug:
msg: "Image berhasil dibangun: {{ build_result.image.Id }}"
Push Image ke Registry #
Setelah build, push image ke registry agar bisa digunakan di server lain:
- name: Login ke private registry
community.docker.docker_login:
registry_url: registry.company.com
username: "{{ registry_username }}"
password: "{{ registry_password }}"
no_log: true
- name: Push image ke registry
community.docker.docker_image:
name: registry.company.com/myapp
tag: "{{ app_version }}"
push: true
source: local # Gunakan image yang sudah ada di local
- name: Tag image sebagai latest
community.docker.docker_image:
name: registry.company.com/myapp
repository: registry.company.com/myapp
tag: latest
source: local
force_tag: true
- name: Push tag latest
community.docker.docker_image:
name: registry.company.com/myapp
tag: latest
push: true
source: local
- name: Logout dari registry
community.docker.docker_login:
registry_url: registry.company.com
state: absent
Strategi Tagging yang Baik #
Tag yang baik mengidentifikasi image secara unik dan tidak ambigu:
# vars untuk build
app_version: "2.1.0"
git_commit: "{{ lookup('pipe', 'git rev-parse --short HEAD') }}"
build_date: "{{ ansible_date_time.date }}"
# Tag yang dihasilkan:
image_tags:
- "{{ app_version }}" # 2.1.0
- "{{ app_version }}-{{ git_commit }}" # 2.1.0-a3f5c1d
- "{{ app_version }}-{{ build_date }}" # 2.1.0-2024-03-15
- latest # Hanya untuk branch main
- name: Build dan tag image dengan semua tag
community.docker.docker_image:
name: registry.company.com/myapp
tag: "{{ item }}"
source: "{{ 'build' if loop.index == 1 else 'local' }}"
build:
path: /opt/app/src
push: true
loop: "{{ image_tags }}"
loop_control:
label: "registry.company.com/myapp:{{ item }}"
Taglatestsering disalahgunakan. Di production, selalu deploy dengan tag versi yang spesifik (2.1.0atau2.1.0-a3f5c1d) — bukanlatest. Taglatesttidak menjamin kamu tahu persis versi apa yang berjalan, dan tidak bisa di-rollback dengan mudah.
Build Pipeline Lengkap #
Menggabungkan semua langkah menjadi satu playbook pipeline:
# playbooks/build-and-push.yml
---
- name: Build dan push Docker image
hosts: localhost # Build di control node atau build server
vars:
registry: registry.company.com
image_name: myapp
app_version: "{{ version | mandatory }}" # Harus dipass via -e version=x.y.z
tasks:
- name: Validasi versi yang diberikan
assert:
that:
- app_version is defined
- app_version is match('^[0-9]+\.[0-9]+\.[0-9]+$')
fail_msg: "Gunakan -e version=x.y.z (contoh: -e version=2.1.0)"
- name: Checkout kode versi {{ app_version }}
git:
repo: https://github.com/company/myapp.git
dest: /tmp/myapp-build
version: "v{{ app_version }}"
force: true
- name: Build image
community.docker.docker_image:
name: "{{ registry }}/{{ image_name }}"
tag: "{{ app_version }}"
source: build
build:
path: /tmp/myapp-build
pull: true
state: present
- name: Login ke registry
community.docker.docker_login:
registry_url: "{{ registry }}"
username: "{{ registry_username }}"
password: "{{ registry_password }}"
no_log: true
- name: Push image
community.docker.docker_image:
name: "{{ registry }}/{{ image_name }}"
tag: "{{ app_version }}"
push: true
source: local
- name: Logout dari registry
community.docker.docker_login:
registry_url: "{{ registry }}"
state: absent
- name: Cleanup direktori build
file:
path: /tmp/myapp-build
state: absent
# Jalankan pipeline build
ansible-playbook playbooks/build-and-push.yml -e version=2.1.0
Membersihkan Image Lama #
Image yang tidak lagi digunakan akan memenuhi disk. Bersihkan secara berkala:
- name: Hapus image lama yang tidak digunakan
community.docker.docker_prune:
images: true
images_filters:
dangling: true # Hapus hanya dangling images (untagged)
timeout: 300
- name: Hapus semua image yang tidak digunakan (lebih agresif)
community.docker.docker_prune:
images: true
images_filters:
until: "168h" # Hapus image yang tidak digunakan lebih dari 7 hari
Ringkasan #
- Module
docker_imagedengansource: builduntuk membangun image dari Dockerfile — mendukung build args, cache control, dan pull base image.- Selalu login ke registry sebelum push dan logout setelah selesai — gunakan
no_log: trueuntuk menyembunyikan credential.- Strategi tag yang baik menggunakan versi + git commit untuk traceability penuh — selalu tahu kode mana yang ada di image mana.
- Jangan deploy dengan tag
latestdi production — gunakan tag versi spesifik untuk reproducibility dan kemampuan rollback.- Buat playbook build pipeline yang menerima versi via
-e version=x.y.z— proses build yang konsisten dan dapat diulang.- Bersihkan image lama secara berkala dengan
docker_prune— image yang menumpuk bisa menghabiskan disk dalam waktu singkat.
← Sebelumnya: Ansible vs Docker Compose Berikutnya: Apa itu Kubernetes? →