Provision Host

Provision Host #

Sebelum kita dapat menjalankan dan mengorkestrasi container di lingkungan production, hal mendasar yang harus kita lakukan adalah menyiapkan host yang akan bertindak sebagai container runtime. Proses ini sering disebut sebagai host provisioning. Jika kita melakukannya secara manual—mulai dari instalasi paket, konfigurasi daemon, pembuatan user, hingga pengelolaan keamanan—kita rentan terhadap masalah inkonsistensi konfigurasi (configuration drift). Satu server mungkin memiliki konfigurasi logging yang berbeda, sementara server lain menggunakan storage driver yang tidak optimal, yang pada akhirnya memicu kegagalan aplikasi yang sulit dilacak.

Dengan menggunakan Ansible, kita dapat mengotomasi seluruh alur provisioning host Docker ini. Mulai dari menambahkan repository resmi, menginstal Docker Engine versi spesifik, menyusun file konfigurasi /etc/docker/daemon.json secara dinamis, mengonfigurasi storage driver overlay2, membatasi ukuran log agar tidak memenuhi disk, hingga menyusun cron job untuk pembersihan sampah container (garbage collection). Pendekatan infrastruktur sebagai kode (Infrastructure as Code) ini memastikan bahwa setiap host Docker yang kita kelola berjalan dengan konfigurasi yang identik, aman, dan siap untuk menangani beban kerja production.

flowchart TD
    Start["Mulai Provisioning"] --> CheckOS{"Deteksi Keluarga OS"}
    CheckOS -->|"Debian / Ubuntu"| SetupAPT["Setup Repository APT"]
    CheckOS -->|"RedHat / CentOS"| SetupYUM["Setup Repository YUM/DNF"]
    SetupAPT --> InstallDocker["Instal Docker Engine & Plugins"]
    SetupYUM --> InstallDocker
    InstallDocker --> ConfigDaemon["Deploy daemon.json & Validasi JSON"]
    ConfigDaemon --> SetupUsers["Setup User & Group docker"]
    SetupUsers --> EnableService["Aktifkan & Jalankan Service Docker"]
    EnableService --> SetupGC["Setup Cron Garbage Collection"]
    SetupGC --> Verify["Verifikasi & Test Container"]
    Verify --> End["Selesai (Host Siap)"]

Tantangan Pengelolaan Docker Host Manual #

Mengelola host Docker secara manual dengan mengetikkan perintah satu per satu di terminal adalah pola yang sangat tidak direkomendasikan untuk skala production. Ketika jumlah server bertambah, tantangan pemeliharaan akan meningkat secara eksponensial.

Ada beberapa masalah utama yang sering kita hadapi akibat instalasi manual:

  1. Ketidakcocokan Versi Paket: Tanpa kontrol terpusat, satu server mungkin menjalankan Docker versi 24.x sedangkan server lainnya menjalankan versi 26.x. Perbedaan versi ini dapat menyebabkan inkonsistensi perilaku runtime API atau kegagalan modul integrasi.
  2. Konfigurasi Daemon yang Tersebar: Pengaturan vital seperti alamat registry mirror, opsi dns, live-restore, dan logging driver sering kali lupa dikonfigurasi secara seragam di setiap host.
  3. Risiko Disk Penuh: Secara default, Docker tidak membatasi ukuran log container dan tidak menghapus image yang tidak terpakai (dangling images). Tanpa otomatisasi sistem rotasi log dan pembersihan berkala, server kita akan cepat kehabisan ruang penyimpanan.

Untuk melihat perbandingan dampak antara pendekatan manual dengan otomatisasi menggunakan Ansible, kita dapat melihat tabel di bawah ini:

Dimensi Pengelolaan Pendekatan Manual (Terminal CLI) Otomasi dengan Ansible (Playbook)
Kecepatan Provisioning Lambat, membutuhkan waktu 15-30 menit per host. Sangat cepat, selesai dalam hitungan menit untuk puluhan host secara paralel.
Konsistensi Konfigurasi Rendah, sangat rentan terhadap kesalahan manusia (human error). Mutlak, seluruh host dijamin memiliki konfigurasi yang identik.
Audit & Version Control Sulit dilacak karena tidak ada dokumentasi perubahan sistem. Mudah, semua playbook dan variabel disimpan dalam Git repository.
Penanganan Log & Cleanup Sering kali diabaikan hingga server mengalami kendala disk penuh. Terotomasi sejak awal melalui task pembuatan file konfigurasi dan cron.
Keamanan Host Akses grup docker sering kali diberikan secara longgar tanpa batasan. Dikontrol secara ketat melalui manajemen user dan hak akses terbatas.

Instalasi Docker Engine di Ubuntu dan CentOS #

Langkah pertama dalam proses provisioning adalah menginstal Docker Engine. Untuk memastikan keandalan, kita harus menghindari instalasi paket bawaan distribusi OS yang versinya sering kali tertinggal jauh. Kita wajib menggunakan repository resmi dari Docker.

Dalam playbook Ansible, kita bisa menggunakan pendekatan multi-OS yang mendeteksi keluarga OS (ansible_os_family) menggunakan kondisional. Berikut adalah struktur role Docker yang mendukung Ubuntu (Debian) dan CentOS (RedHat):

1. Struktur Task Utama (tasks/main.yml) #

Kita membagi logika instalasi berdasarkan keluarga OS dan kemudian menjalankan konfigurasi bersama yang berlaku untuk semua sistem:

# roles/docker/tasks/main.yml
---
- name: Jalankan instalasi spesifik Ubuntu (Debian)
  include_tasks: install_debian.yml
  when: ansible_os_family == "Debian"

- name: Jalankan instalasi spesifik CentOS (RedHat)
  include_tasks: install_redhat.yml
  when: ansible_os_family == "RedHat"

- name: Jalankan konfigurasi bersama Docker Daemon
  include_tasks: configure.yml

- name: Jalankan pengaturan user dan grup
  include_tasks: users.yml

- name: Konfigurasi sistem logging dan garbage collection
  include_tasks: maintenance.yml

- name: Verifikasi instalasi Docker
  include_tasks: verify.yml

2. Jalur Instalasi Ubuntu/Debian (tasks/install_debian.yml) #

Untuk keluarga Debian, kita harus memastikan paket lama dibersihkan, dependensi APT diinstal, GPG key Docker ditambahkan secara aman ke direktori /etc/apt/keyrings, repository ditambahkan, dan akhirnya Docker Engine diinstal dengan versi yang telah dipin (dikunci).

# roles/docker/tasks/install_debian.yml
---
- name: Hapus versi Docker lama untuk mencegah konflik
  apt:
    name:
      - docker
      - docker-engine
      - docker.io
      - containerd
      - runc
    state: absent

- name: Install paket dependensi APT yang dibutuhkan
  apt:
    name:
      - ca-certificates
      - curl
      - gnupg
      - lsb-release
      - python3-pip
    state: present
    update_cache: true

- name: Buat direktori keyrings jika belum ada
  file:
    path: /etc/apt/keyrings
    state: directory
    mode: '0755'

- name: Unduh dan simpan GPG key resmi Docker
  apt_key:
    url: https://download.docker.com/linux/ubuntu/gpg
    keyring: /etc/apt/keyrings/docker.gpg
    state: present

- name: Tambahkan repository Docker resmi ke sistem APT
  apt_repository:
    repo: >
      deb [arch={{ ansible_architecture }}
      signed-by=/etc/apt/keyrings/docker.gpg]
      https://download.docker.com/linux/ubuntu
      {{ ansible_distribution_release }} stable      
    filename: docker
    state: present

- name: Instal Docker Engine versi spesifik (Ubuntu)
  apt:
    name:
      - "docker-ce={{ docker_apt_version }}"
      - "docker-ce-cli={{ docker_apt_version }}"
      - containerd.io
      - docker-buildx-plugin
      - docker-compose-plugin
    state: present
    update_cache: true

3. Jalur Instalasi CentOS/RedHat (tasks/install_redhat.yml) #

Untuk CentOS atau RedHat, prosesnya melibatkan penghapusan paket lama, penambahan repository YUM resmi menggunakan modul yum_repository atau get_url, instalasi dependensi YUM, dan instalasi Docker Engine dengan versi DNF/YUM yang sesuai.

# roles/docker/tasks/install_redhat.yml
---
- name: Hapus versi Docker lama (CentOS/RedHat)
  dnf:
    name:
      - docker
      - docker-client
      - docker-client-latest
      - docker-common
      - docker-latest
      - docker-latest-logrotate
      - docker-logrotate
      - docker-engine
    state: absent

- name: Install paket penunjang YUM
  dnf:
    name:
      - yum-utils
      - device-mapper-persistent-data
      - lvm2
      - python3-pip
    state: present

- name: Tambahkan repository Docker YUM resmi
  get_url:
    url: https://download.docker.com/linux/centos/docker-ce.repo
    dest: /etc/yum.repos.d/docker-ce.repo
    owner: root
    group: root
    mode: '0644'

- name: Instal Docker Engine versi spesifik (CentOS/RedHat)
  dnf:
    name:
      - "docker-ce-{{ docker_yum_version }}"
      - "docker-ce-cli-{{ docker_yum_version }}"
      - containerd.io
      - docker-buildx-plugin
      - docker-compose-plugin
    state: present
    update_cache: true

4. Definisi Variabel Versi (defaults/main.yml) #

Untuk menjaga stabilitas, kita wajib mengunci versi Docker. Jangan biarkan Ansible mengunduh versi terbaru secara acak yang berpotensi merusak kompatibilitas aplikasi kita.

# roles/docker/defaults/main.yml
---
# Menetapkan versi spesifik untuk Debian/Ubuntu
docker_apt_version: "5:24.0.7-1~ubuntu.22.04~jammy"

# Menetapkan versi spesifik untuk CentOS/RHEL
docker_yum_version: "3:24.0.7-1.el9"

# Konfigurasi default daemon
docker_daemon_log_driver: "json-file"
docker_daemon_log_max_size: "50m"
docker_daemon_log_max_file: "3"
docker_daemon_storage_driver: "overlay2"

# Mirror registry opsional
docker_registry_mirrors: []

# User yang akan dimasukkan ke grup docker
docker_users: []

Optimasi Docker Daemon via daemon.json #

File /etc/docker/daemon.json merupakan pusat kendali dari perilaku Docker Engine. Di sinilah kita mendefinisikan bagaimana container diisolasi, bagaimana log disimpan, mirror registry apa yang digunakan, dan bagaimana Docker memproses resource host.

Opsi Konfigurasi Vital daemon.json #

Berikut adalah opsi-opsi krusial yang wajib kita terapkan untuk kebutuhan production:

  • live-restore: Bernilai true. Fitur ini sangat krusial karena memungkinkan container kita tetap berjalan dengan lancar meskipun Docker daemon sedang di-restart atau di-update. Ini menjamin pemeliharaan server tanpa downtime aplikasi (zero-downtime maintenance).
  • userland-proxy: Setel ke false. Secara default, Docker menggunakan proxy userland untuk membelokkan lalu lintas jaringan ke port container. Menonaktifkan opsi ini membuat lalu lintas jaringan ditangani langsung oleh aturan iptables host, meningkatkan performa jaringan secara signifikan dan menghemat overhead memori host.
  • log-driver dan log-opts: Kita wajib mengontrol ukuran file log. Tanpa pembatasan, file log container akan terus bertumbuh tanpa batas hingga ruang penyimpanan habis. Kita menggunakan driver json-file dengan pembatasan ukuran maksimal per file dan jumlah file rotasi.
  • storage-driver: Driver penyimpanan standar industri yang sangat efisien untuk Docker di Linux modern adalah overlay2.

Task Deployment daemon.json dengan Validasi JSON #

Ketika mendeploy file JSON, kesalahan penulisan karakter seperti koma yang hilang atau tanda kurung kurawal yang salah letak akan membuat Docker daemon gagal berjalan saat di-restart. Untuk mencegah hal ini, kita menggunakan fitur validate di modul template Ansible. Kita memanfaatkan interpreter Python bawaan untuk memeriksa sintaksis JSON sebelum file ditulis ke tujuan.

# roles/docker/tasks/configure.yml
---
- name: Pastikan direktori konfigurasi Docker ada
  file:
    path: /etc/docker
    state: directory
    owner: root
    group: root
    mode: '0755'

- name: Deploy file konfigurasi daemon.json dari template Jinja2
  template:
    src: daemon.json.j2
    dest: /etc/docker/daemon.json
    owner: root
    group: root
    mode: '0644'
    # Validasi sintaksis JSON menggunakan interpreter Python sebelum menyimpannya
    validate: "python3 -c 'import json; json.load(open(\"%s\"))'"
  notify: Restart Docker Daemon

Template Jinja2 daemon.json (templates/daemon.json.j2) #

Template ini menyusun konfigurasi JSON secara dinamis berdasarkan variabel yang telah kita tetapkan di default role atau variabel group host:

{# roles/docker/templates/daemon.json.j2 #}
{
  "log-driver": "{{ docker_daemon_log_driver }}",
  "log-opts": {
    "max-size": "{{ docker_daemon_log_max_size }}",
    "max-file": "{{ docker_daemon_log_max_file }}"
  },
  "storage-driver": "{{ docker_daemon_storage_driver }}",
  "live-restore": true,
  "userland-proxy": false,
  "iptables": true,
  "exec-opts": ["native.cgroupdriver=systemd"]
{% if docker_registry_mirrors | length > 0 %}
  ,
  "registry-mirrors": {{ docker_registry_mirrors | to_json }}
{% endif %}
}

Kita juga menambahkan handler untuk me-restart Docker secara aman jika file konfigurasi berubah:

# roles/docker/handlers/main.yml
---
- name: Restart Docker Daemon
  systemd:
    name: docker
    state: restarted
    daemon_reload: true

Manajemen Storage Driver dan File System #

Docker membutuhkan cara yang efisien untuk mengelola image layers dan filesystem kontainer yang bersifat read-write. Pilihan storage driver berdampak besar pada kecepatan I/O operasi baca-tulis kontainer serta penggunaan memori host.

Mengapa overlay2? #

Di masa lalu, Docker menggunakan driver seperti aufs, devicemapper, atau overlay. Di lingkungan Linux modern saat ini, driver overlay2 adalah standar baku industri. Keunggulan utamanya meliputi:

  • Efisiensi Inode: overlay2 tidak menghabiskan inode dalam jumlah besar seperti pendahulunya.
  • Performa I/O: Menggunakan fitur kernel Linux secara native untuk menggabungkan direktori (union mount), yang meminimalkan overhead sistem.
  • Penggunaan Memori Rendah: Kontainer yang berbagi image layer yang sama dapat berbagi halaman cache memori halaman kernel (page cache), mengurangi beban RAM host.

Persyaratan File System Host (Backing File System) #

Agar driver overlay2 bekerja maksimal dan stabil, backing file system dari host (sistem berkas tempat direktori /var/lib/docker berada) disarankan berupa ext4 atau xfs dengan opsi ftype=1 aktif.

Kita dapat menggunakan Ansible untuk memeriksa jenis filesystem host dan memastikan direktori /var/lib/docker dipasang (mount) di disk dengan parameter yang tepat:

- name: Periksa backing filesystem dari direktori Docker
  command: stat -f -c %T /var/lib/docker
  register: docker_fs_check
  changed_when: false
  failed_when: false

- name: Peringatkan jika filesystem tidak didukung untuk overlay2
  debug:
    msg: "PERINGATAN: Filesystem {{ docker_fs_check.stdout }} terdeteksi. Disarankan menggunakan ext4 atau xfs untuk stabilitas overlay2."
  when: docker_fs_check.stdout not in ['ext4', 'xfs']

Sistem Logging dan Rotasi Log Container #

Setiap baris teks yang dikirimkan aplikasi kita ke stdout atau stderr akan ditangkap oleh Docker dan disimpan dalam file berformat JSON di host. Di lingkungan production yang sibuk, volume log yang dihasilkan kontainer bisa mencapai gigabytes per hari. Jika kita membiarkan konfigurasi bawaan tanpa batas, disk server akan penuh dan memicu crash seluruh sistem operasi.

Ada dua cara utama untuk mengelola ukuran log container: mengatur batas maksimal pada daemon Docker, atau menggunakan sistem logrotate bawaan Linux.

Perbandingan Strategi Logging #

Strategi 1: daemon.json Limits (Direkomendasikan)
  - Penanganan dilakukan langsung oleh daemon Docker.
  - Log langsung dipotong ketika menyentuh batas ukuran (misalnya 50MB).
  - Sangat rapi dan tidak memerlukan dependensi eksternal sistem operasi.

Strategi 2: Logrotate Host
  - Menggunakan utilitas cron logrotate milik sistem operasi Linux.
  - Bekerja di luar siklus hidup Docker daemon.
  - Membutuhkan penanganan khusus karena file log yang sedang ditulis bisa mengalami kendala deskriptor berkas (file descriptor) jika tidak dipotong dengan opsi copytruncate.

Implementasi Logrotate Menggunakan Ansible #

Sebagai langkah mitigasi tambahan di luar batasan daemon Docker, kita dapat mendeploy konfigurasi logrotate untuk file log kontainer Docker. Opsi copytruncate sangat penting agar logrotate menduplikasi isi berkas log asli lalu mengosongkannya, alih-alih memindahkan berkas secara langsung, karena Docker daemon terus-menerus membuka file descriptor log tersebut.

# roles/docker/tasks/maintenance.yml (Bagian Logrotate)
- name: Deploy konfigurasi logrotate untuk log container Docker
  template:
    src: docker-logrotate.j2
    dest: /etc/logrotate.d/docker-containers
    owner: root
    group: root
    mode: '0644'

Berikut adalah template Jinja2 untuk berkas logrotate:

{# roles/docker/templates/docker-logrotate.j2 #}
/var/lib/docker/containers/*/*.log {
    rotate 7
    daily
    compress
    size 50M
    missingok
    delaycompress
    copytruncate
    notifempty
}

Opsi-opsi di atas memiliki fungsi sebagai berikut:

  • rotate 7: Menyimpan maksimal 7 file arsip log lama sebelum mulai menghapusnya.
  • daily: Melakukan rotasi secara harian.
  • compress: Mengompresi file log lama menggunakan gzip untuk menghemat ruang disk.
  • size 50M: Melakukan rotasi seketika jika file log mencapai ukuran 50 Megabytes, tanpa menunggu jadwal harian.
  • copytruncate: Menyalin berkas log yang aktif lalu mengosongkannya di tempat, mencegah Docker kehilangan tujuan penulisan log.

Garbage Collection Otomatis untuk Container, Image, dan Volume #

Di server development atau production yang mengalami deployment berkala (misalnya melalui pipeline CI/CD), server kita akan menimbun banyak sekali “sampah” digital. Ini mencakup:

  • Kontainer yang sudah mati atau keluar (exited containers).
  • Volume yatim piatu (orphaned volumes) yang tidak terhubung ke kontainer manapun.
  • Jaringan Docker (networks) yang tidak lagi digunakan.
  • Image lama tanpa tag yang tertinggal setelah kita melakukan build atau pull image baru (dangling images).

Ansible memiliki modul khusus untuk menangani pembersihan ini secara efisien, yaitu community.docker.docker_prune. Kita dapat menyusun task untuk menjalankan pembersihan ini secara berkala, misalnya seminggu sekali atau sehari sekali, menggunakan sistem cron.

Task Pruning dengan community.docker.docker_prune #

Berikut adalah task Ansible untuk melakukan pembersihan resource Docker yang tidak terpakai:

# roles/docker/tasks/maintenance.yml (Bagian Garbage Collection)
---
- name: Hapus container yang sudah terhenti
  community.docker.docker_prune:
    containers: true
    containers_filters:
      until: "24h" # Hapus kontainer yang telah mati lebih dari 24 jam
  register: prune_containers_result

- name: Hapus image dangling (tanpa tag) untuk hemat disk
  community.docker.docker_prune:
    images: true
    images_filters:
      dangling: true
  register: prune_images_result

- name: Hapus volume yatim piatu yang tidak terhubung ke container
  community.docker.docker_prune:
    volumes: true
  register: prune_volumes_result

- name: Tampilkan statistik ruang disk yang berhasil dibebaskan
  debug:
    msg: 
      - "Container bersih: {{ prune_containers_result.space_reclaimed | default(0) | filesizeformat }}"
      - "Image bersih: {{ prune_images_result.space_reclaimed | default(0) | filesizeformat }}"
      - "Volume bersih: {{ prune_volumes_result.space_reclaimed | default(0) | filesizeformat }}"

Mengonfigurasi Otomatisasi GC dengan Cron Job #

Agar pembersihan ini berjalan secara otomatis tanpa intervensi manual di kemudian hari, kita membuat sebuah script shell pembersih dan mendaftarkannya sebagai cron job mingguan menggunakan modul cron di Ansible.

- name: Buat script pembersih Docker di host
  copy:
    dest: /usr/local/bin/docker-cleanup.sh
    owner: root
    group: root
    mode: '0755'
    content: |
      #!/bin/bash
      # Pembersihan otomatis untuk resource Docker
      docker system prune -af --volumes --filter "until=168h"      

- name: Buat cron job untuk menjalankan pembersihan setiap hari Minggu jam 03.00 WIB
  cron:
    name: "Docker Garbage Collection"
    minute: "0"
    hour: "3"
    weekday: "0"
    job: "/usr/local/bin/docker-cleanup.sh > /dev/null 2>&1"

Manajemen User dan Aspek Keamanan Rootless #

Menjalankan perintah Docker memerlukan hak akses administrative yang tinggi. Secara default, jika kita ingin berinteraksi dengan socket Docker daemon (/var/run/docker.sock), kita harus menjadi user root atau menggunakan perintah sudo.

Bahaya Keamanan Grup docker #

Pola yang sangat umum dilakukan developer adalah menambahkan user biasa ke dalam grup Unix bernama docker. Dengan cara ini, user tersebut dapat menjalankan perintah Docker tanpa mengetikkan sudo. Namun, pola ini membawa risiko keamanan yang sangat tinggi.

# ANTI-PATTERN: Menambahkan sembarang user ke grup docker tanpa menyadari konsekuensinya
- name: Tambahkan user developer ke grup docker
  user:
    name: developer_anak_magang
    groups: docker
    append: true

Mengapa ini berbahaya? User yang berada dalam grup docker secara efektif memiliki wewenang setara root pada host. Attacker yang berhasil mengambil alih akun user tersebut dapat dengan mudah melakukan eskalasi hak akses (privilege escalation) ke root host dengan cara menjalankan kontainer yang mem-mount filesystem root (/) dari host:

# Eksploitasi sederhana oleh user dalam grup docker untuk membaca file rahasia host
docker run -v /:/host-root -it alpine cat /host-root/etc/shadow

Solusi Praktis: Batasi Akses dan Audit Playbook #

Untuk mengamankan host, kita harus membatasi user yang masuk ke grup docker hanya untuk service account deployment yang terverifikasi (seperti user ansible-deploy atau agen CI/CD kita) dan menjaga socket Docker tetap aman.

Berikut adalah playbook untuk mengelola user yang memiliki otorisasi secara ketat:

# roles/docker/tasks/users.yml
---
- name: Pastikan grup docker ada di sistem
  group:
    name: docker
    state: present

- name: Tambahkan user deployment spesifik ke grup docker
  user:
    name: "{{ item }}"
    groups: docker
    append: true
  loop: "{{ docker_users }}"
  when: docker_users is defined and (docker_users | length > 0)

Untuk perlindungan ekstra tingkat production, kita disarankan untuk menerapkan sistem Rootless Docker. Konseptualisasinya adalah Docker daemon dan kontainer berjalan sepenuhnya di dalam ruang nama user (user namespace) tanpa membutuhkan hak akses root sama sekali. Ansible dapat kita gunakan untuk menyiapkan dependensi rootless Docker ini:

- name: Pasang paket penunjang untuk Docker Rootless
  apt:
    name:
      - uidmap
      - dbus-user-session
    state: present
  when: ansible_os_family == "Debian"

Verifikasi Instalasi #

Setelah seluruh konfigurasi dideploy dan service Docker diaktifkan, kita harus memastikan bahwa semuanya bekerja dengan benar sebelum menandai host tersebut siap digunakan. Proses verifikasi ini mencakup memastikan service berjalan aktif, memeriksa fungsionalitas dasar dengan menjalankan kontainer test ringan, dan memvalidasi bahwa versi Docker yang terpasang sesuai dengan konfigurasi yang kita harapkan.

# roles/docker/tasks/verify.yml
---
- name: Pastikan service docker telah diaktifkan dan berjalan
  systemd:
    name: docker
    state: started
    enabled: true

- name: Uji coba jalankan kontainer test hello-world
  community.docker.docker_container:
    name: test-hello-world
    image: hello-world:latest
    state: started
  register: test_run
  failed_when: test_run is failed

- name: Hapus kontainer uji coba hello-world
  community.docker.docker_container:
    name: test-hello-world
    state: absent

- name: Ambil informasi versi Docker yang terpasang
  command: docker version --format "{{ '{{' }}.Server.Version{{ '}}' }}"
  register: docker_installed_version
  changed_when: false

- name: Tampilkan laporan status verifikasi host
  debug:
    msg: 
      - "Sistem Operasi: {{ ansible_distribution }} {{ ansible_distribution_version }}"
      - "Docker Engine Aktif: {{ test_run.container is defined }}"
      - "Versi Docker Terpasang: {{ docker_installed_version.stdout }}"

Dengan menjalankan langkah verifikasi otomatis ini, kita dapat langsung mendeteksi jika ada anomali atau kegagalan instalasi sejak awal playbook dijalankan, menghindari kejutan yang tidak menyenangkan saat tim deployment mulai mendeploy aplikasi asli mereka ke host baru ini.


Ringkasan #

  • Gunakan Repository Resmi — Hindari menginstal Docker dari paket bawaan OS distro. Gunakan repository resmi Docker dan kunci (pin) versinya agar seluruh server seragam.
  • Gunakan live-restore — Mengaktifkan live-restore: true di /etc/docker/daemon.json sangat krusial untuk menjaga kontainer tetap menyala saat Docker daemon di-restart.
  • Matikan userland-proxy — Menyetel userland-proxy: false memindahkan beban forwarding jaringan langsung ke kernel iptables, menghemat RAM dan meningkatkan performa I/O network.
  • Rotasi Log Wajib — Selalu batasi kapasitas logging Docker menggunakan opsi log-driver dan log-opts di file daemon.json agar penyimpanan server tidak terancam penuh oleh file log kontainer.
  • Garbage Collection Rutin — Terapkan otomatisasi pembersihan resource sampah dengan modul docker_prune atau script cron job terjadwal untuk menghapus image dangling dan volume tidak terpakai secara berkala.
  • Keamanan Privilege — Keanggotaan grup docker setara dengan hak akses root host. Batasi keanggotaan grup hanya untuk akun otomatisasi deployment tepercaya saja.

← Sebelumnya: Common Mistake   Berikutnya: Deploy Container →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact