Deploy Container #
Setelah host Docker siap, saatnya menjalankan container. Ansible menyediakan module community.docker yang memungkinkan kamu mendeploy, mengkonfigurasi, dan mengelola container dengan cara yang sama persis seperti kamu mengelola konfigurasi sistem — deklaratif dan idempoten. Artikel ini membahas pola deployment container yang umum digunakan dan bagaimana Ansible mengelolanya.
Persiapan: Instal Collection #
Module Docker tidak termasuk dalam Ansible Core dan perlu diinstal terlebih dahulu:
ansible-galaxy collection install community.docker
pip install docker # Library Python yang diperlukan oleh module
Menjalankan Container Sederhana #
Module community.docker.docker_container adalah module utama untuk mengelola lifecycle container:
- name: Jalankan container nginx
community.docker.docker_container:
name: nginx-web
image: nginx:1.24-alpine
state: started
restart_policy: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- /opt/nginx/conf:/etc/nginx/conf.d:ro
- /opt/nginx/ssl:/etc/ssl/nginx:ro
- nginx-logs:/var/log/nginx
env:
TZ: "Asia/Jakarta"
State yang tersedia:
state: started → Jalankan container jika belum berjalan
state: stopped → Hentikan container
state: absent → Hentikan dan hapus container
state: present → Buat container tapi tidak langsung jalankan
Mengelola Image #
Sebelum menjalankan container, pastikan image yang diperlukan sudah ada di host:
- name: Pull image terbaru sebelum deployment
community.docker.docker_image:
name: "{{ app_image }}"
tag: "{{ app_version }}"
source: pull
force_source: true # Pull meski tag sudah ada (untuk :latest atau tag mutable)
- name: Pull image dari private registry
community.docker.docker_image:
name: registry.company.com/myapp
tag: "{{ app_version }}"
source: pull
force_source: false # Jangan pull ulang jika sudah ada (untuk tag immutable)
# Login ke private registry terlebih dahulu
- name: Login ke private Docker registry
community.docker.docker_login:
registry_url: registry.company.com
username: "{{ registry_username }}"
password: "{{ registry_password }}"
no_log: true
Pola Deployment: Stop, Deploy, Start #
Untuk deployment aplikasi yang sudah berjalan, ikuti pola yang aman:
- name: Deploy aplikasi v{{ app_version }}
hosts: appservers
vars:
app_image: registry.company.com/myapp
app_container_name: myapp
tasks:
- name: Pull image versi baru
community.docker.docker_image:
name: "{{ app_image }}"
tag: "{{ app_version }}"
source: pull
- name: Stop container lama
community.docker.docker_container:
name: "{{ app_container_name }}"
state: stopped
ignore_errors: true # Tidak apa-apa jika container belum ada
- name: Hapus container lama
community.docker.docker_container:
name: "{{ app_container_name }}"
state: absent
- name: Jalankan container baru
community.docker.docker_container:
name: "{{ app_container_name }}"
image: "{{ app_image }}:{{ app_version }}"
state: started
restart_policy: unless-stopped
ports:
- "{{ app_port }}:8080"
env:
DATABASE_URL: "{{ db_url }}"
REDIS_URL: "{{ redis_url }}"
APP_ENV: "{{ env }}"
volumes:
- "{{ app_data_dir }}:/app/data"
networks:
- name: app-network
- name: Tunggu container siap
uri:
url: "http://localhost:{{ app_port }}/health"
status_code: 200
register: health_check
until: health_check.status == 200
retries: 12
delay: 5
Mengelola Docker Network #
- name: Buat network untuk aplikasi
community.docker.docker_network:
name: app-network
driver: bridge
ipam_config:
- subnet: "172.20.0.0/16"
gateway: "172.20.0.1"
state: present
- name: Buat network untuk database (isolated)
community.docker.docker_network:
name: db-network
driver: bridge
internal: true # Network internal, tidak bisa akses internet
state: present
Mengelola Docker Volume #
- name: Buat volume untuk data persistent
community.docker.docker_volume:
name: "{{ item }}"
state: present
loop:
- app-data
- db-data
- redis-data
- name: Jalankan database dengan volume persistent
community.docker.docker_container:
name: postgres
image: postgres:15-alpine
state: started
restart_policy: unless-stopped
volumes:
- db-data:/var/lib/postgresql/data
env:
POSTGRES_DB: "{{ db_name }}"
POSTGRES_USER: "{{ db_user }}"
POSTGRES_PASSWORD: "{{ db_password }}"
networks:
- name: db-network
no_log: true
Cek Status Container #
- name: Kumpulkan informasi semua container yang berjalan
community.docker.docker_container_info:
name: myapp
register: container_info
- name: Tampilkan status container
debug:
msg:
- "Container: {{ container_info.container.Name }}"
- "Status: {{ container_info.container.State.Status }}"
- "Image: {{ container_info.container.Config.Image }}"
- "Started: {{ container_info.container.State.StartedAt }}"
when: container_info.exists
Ringkasan #
- Instal
community.dockercollection dan librarydockerPython sebelum menggunakan module Docker.docker_containeradalah module utama — deklaratif dan idempoten, sama seperti module Ansible lainnya.- Selalu pull image sebelum deployment dan gunakan tag yang immutable (bukan
latest) untuk reproducibility.- Pola deployment yang aman: pull → stop → remove → run — memastikan container baru berjalan dengan image yang benar.
restart_policy: unless-stoppeduntuk container production — container otomatis restart setelah reboot host atau crash.- Gunakan
networksuntuk isolasi — container yang tidak perlu berkomunikasi sebaiknya tidak berada di network yang sama.no_log: trueuntuk task yang melibatkan environment variable sensitif seperti password database.
← Sebelumnya: Provision Host Berikutnya: Ansible vs Docker Compose →