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:
- 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.
- 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.
- 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: Bernilaitrue. 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 kefalse. 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-driverdanlog-opts: Kita wajib mengontrol ukuran file log. Tanpa pembatasan, file log container akan terus bertumbuh tanpa batas hingga ruang penyimpanan habis. Kita menggunakan driverjson-filedengan pembatasan ukuran maksimal per file dan jumlah file rotasi.storage-driver: Driver penyimpanan standar industri yang sangat efisien untuk Docker di Linux modern adalahoverlay2.
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:
overlay2tidak 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: truedi/etc/docker/daemon.jsonsangat krusial untuk menjaga kontainer tetap menyala saat Docker daemon di-restart.- Matikan userland-proxy — Menyetel
userland-proxy: falsememindahkan 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-driverdanlog-optsdi filedaemon.jsonagar penyimpanan server tidak terancam penuh oleh file log kontainer.- Garbage Collection Rutin — Terapkan otomatisasi pembersihan resource sampah dengan modul
docker_pruneatau script cron job terjadwal untuk menghapus image dangling dan volume tidak terpakai secara berkala.- Keamanan Privilege — Keanggotaan grup
dockersetara dengan hak akses root host. Batasi keanggotaan grup hanya untuk akun otomatisasi deployment tepercaya saja.