Docker yang baru terpasang langsung bisa dipakai, tetapi konfigurasi bawaannya dirancang untuk kondisi umum, bukan untuk server produksi kita. Log container tumbuh tanpa batas sampai partisi penuh, seluruh image dan volume menumpuk di /var/lib/docker pada partisi yang mungkin kecil, dan setiap pull image menempuh perjalanan ke Docker Hub walau kantor memiliki mirror internal. Semua penyesuaian ini memiliki satu pintu masuk resmi: berkas daemon.json di folder /etc/docker. Chapter ini membuka berkas tersebut, menyusun contoh konfigurasi multi-kunci yang valid, membedah arti tiap kuncinya, lalu menuntaskan dengan satu kejutan kecil bernama bentrok hosts dengan systemd — beserta jalan keluarnya.

Berkas daemon.json #

daemon.json adalah berkas JSON biasa yang dibaca dockerd setiap kali daemon dinyalakan; setiap kunci di dalamnya menimpa nilai bawaan untuk perilaku daemon. Pemasangan baru belum memiliki berkas ini — absennya berkas berarti seluruh pengaturan memakai nilai bawaan. Membuatnya cukup dengan editor teks dan hak akses root; validitas isinya bisa diperiksa tanpa memulai ulang daemon, sehingga kesalahan tik tidak serta-merta mematikan server:

bash
$ sudo dockerd --validate --config-file /etc/docker/daemon.json

Output yang Dihasilkan:

text
configuration OK

Keluaran configuration OK berarti JSON tersebut dapat diurai dan seluruh kuncinya dikenali daemon. Jadikan perintah ini kebiasaan setiap kali selesai menyunting konfigurasi — bab terakhir section ini akan memperlihatkan apa yang terjadi bila langkah pemeriksaan ini dilewati.

Contoh Konfigurasi Lengkap #

Berikut contoh daemon.json yang menyatukan keenam penyesuaian yang paling sering dibutuhkan di server nyata. Simpan isi ini ke /etc/docker/daemon.json lalu sesuaikan nilainya dengan kondisi mesin kita:

json
{
  "data-root": "/data/docker",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "registry-mirrors": ["<alamat-mirror-anda>"],
  "hosts": ["unix:///var/run/docker.sock"],
  "features": {
    "containerd-snapshotter": true
  }
}

Blok JSON di atas sengaja ditulis dengan indentasi dua spasi dan setiap kunci di barisnya sendiri agar mudah dibedah. Mari kita telaah peran setiap kuncinya:

  1. data-root — memindahkan rumah penyimpanan Docker dari bawaan /var/lib/docker ke path yang kita tentukan; seluruh image, container, volume, dan build cache hidup di bawah folder ini. Di server yang partisi sistemnya kecil, memindahkannya ke disk data terpisah adalah langkah paling berdampak.
  2. log-driver — memilih driver log bawaan untuk semua container; json-file menyimpan log sebagai berkas JSON per container dan merupakan satu dari dua driver — bersama local — yang masih bisa dibaca lewat docker logs.
  3. log-opts — wadah opsi untuk driver log terpilih; pasangan max-size dan max-file di dalamnya mengaktifkan rotasi log, yang kita bedah khusus pada bagian berikutnya.
  4. registry-mirrors — daftar mirror yang dikunjungi daemon lebih dulu setiap kali menarik image publik dari Docker Hub. Ganti penanda <alamat-mirror-anda> dengan alamat mirror lengkap milik jaringan kita, misalnya mirror internal pada mirror.example.com:5000, ditulis dengan prefiks skema https sesuai format dokumentasi.
  5. hosts — menentukan alamat yang didengarkan daemon; nilai unix:///var/run/docker.sock mempertahankan socket lokal sebagai satu-satunya pintu masuk. Kunci ini punya sejarah bentrok khusus dengan systemd yang kita bahas pada bagian tersendiri di bawah.
  6. features — saklar fitur engine; containerd-snapshotter mengaktifkan penyimpanan image berbasis containerd. Instalasi Engine 29 ke atas sudah memakainya secara bawaan, tetapi instalasi lama yang di-upgrade tetap pada overlay2 sampai saklar ini dinyalakan.

Kenapa Rotasi Log Wajib Dipikirkan #

Di antara semua kunci di atas, pasangan max-size dan max-file adalah penyesuaian yang paling layak disebut wajib. Driver json-file tanpa pengaturan menulis log container ke satu berkas yang tumbuh selamanya — container yang rajin mencetak log akan mengisi disk pelan-pelan sampai suatu pagi seluruh server berhenti menulis apa pun karena no space left on device. Dengan rotasi aktif, daemon memotong berkas log ketika ukurannya menyentuh max-size — 10 megabyte pada contoh kita — dan menjaga maksimal max-file buah berkas lama — 3 buah pada contoh kita — sebelum yang paling tua dihapus. Anggaran log tertinggi per container dengan contoh ini sekitar 40 megabyte: satu berkas aktif 10 megabyte di tiga berkas riwayat, terukur dan bisa direncanakan. Nilai ini menjadi bawaan untuk container apa pun yang tidak menimpanya lewat flag saat dijalankan, jadi satu baris konfigurasi melindungi seluruh armada container di mesin tersebut.

Opsi Umum daemon.json #

Selain enam kunci pada contoh di atas, tabel berikut merangkum opsi-opsi lain yang sering dibutuhkan. Nilai setiap kunci mengikuti bentuk yang sama seperti pada contoh: string, angka, objek, atau larik nilai:

KunciBentuk nilaiKegunaan
data-rootstringMemindahkan lokasi penyimpanan image, container, dan volume
log-driverstringMemilih driver log bawaan untuk semua container
log-optsobjekOpsi driver log, terutama rotasi max-size dan max-file
registry-mirrorslarikDaftar mirror untuk menarik image dari Docker Hub
hostslarikAlamat socket atau TCP yang didengarkan daemon
featuresobjekSaklar fitur engine seperti containerd-snapshotter
dnslarikDNS server yang dipakai container secara bawaan
insecure-registrieslarikRegistry internal tanpa verifikasi TLS — hanya untuk uji coba

Kunci hosts dan Bentrokan dengan systemd #

Kunci hosts menyimpan satu jebakan klasik di mesin dengan systemd. Unit layanan docker.service di Ubuntu menjalankan dockerd dengan argumen -H fd://, yang memerintahkan daemon mewarisi socket dari systemd lewat aktivasi socket. Argumen baris perintah dan kunci hosts di daemon.json tidak boleh mendefinisikan pendengar yang sama dua kali — bila keduanya hadir bersamaan, daemon menolak menyala dengan galat bentrok socket. Solusi resminya bukan membuang kunci hosts, melainkan membersihkan argumen bawaan dari unit layanan lewat berkas drop-in:

bash
$ sudo systemctl edit docker.service

Perintah tersebut membuka editor untuk berkas drop-in milik unit; isikan dua baris berikut lalu simpan:

ini
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd

Mari kita telaah isi drop-in di atas:

  1. ExecStart= yang kosong — baris tanpa nilai ini menghapus seluruh definisi ExecStart warisan unit asli, termasuk argumen -H fd:// yang menjadi sumber bentrok.
  2. ExecStart=/usr/bin/dockerd — baris kedua memasang definisi pengganti tanpa argumen pendengar apa pun, sehingga kunci hosts di daemon.json menjadi satu-satunya penguji alamat.
  3. Drop-in, bukan suntingan unit — berkas drop-in disimpan terpisah di folder docker.service.d dan tidak tertimpa saat paket Docker diperbarui; mengedit berkas unit asli justru berakhir hilang ditimpa upgrade.

Dengan drop-in ini, konflik hilang dan pendengar daemon sepenuhnya dikendalikan daemon.json — pola yang juga kita perlukan nanti saat membuka pendengar TCP untuk koneksi jauh pada Chapter Mengatur Akses Docker.

Menerapkan dan Memverifikasi #

Konfigurasi tidak bereaksi sampai daemon membacanya kembali. Mulai ulang layanan, lalu minta docker info merangkum keadaan daemon — dua baris di dalamnya menjadi bukti bahwa konfigurasi kita benar-benar aktif:

bash
$ sudo systemctl restart docker
$ docker info

Output yang Dihasilkan:

text
Client:
 Context:    default
 Debug Mode: false
...
Server:
 Containers: 0
 Images: 0
 Server Version: 29.9.0
 Storage Driver: overlayfs
  driver-type: containerd
 Logging Driver: json-file
...
 Docker Root Dir: /data/docker
...
 Registry Mirrors:
  <alamat-mirror-anda>/

Sebagian besar keluaran panjang docker info dipotong; yang tersisa sengaja dipilih karena menjadi sasaran konfigurasi kita. Mari kita telaah baris-baris kuncinya:

  1. Docker Root Dir: /data/docker — bukti kunci data-root aktif; nilai bawaan /var/lib/docker sudah tertimpa.
  2. Registry Mirrors: — daemon mencetak setiap mirror persis seperti yang tertulis di daemon.json; penanda pada contoh kita diganti alamat mirror sungguhan di mesin produksi.
  3. Storage Driver: overlayfs dengan driver-type: containerd — tanda penyimpanan image berbasis containerd; pada instalasi Engine 29 baru seperti ini, tampilan sama muncul walau tanpa kunci features, dan saklar tersebut tetap berguna bagi instalasi lama yang di-upgrade.
  4. Logging Driver: json-file — driver log aktif saat ini; rotasi dari log-opts tidak tercetak di sini, tetapi berkas log yang terpotong di folder container akan membuktikannya setelah container berjalan cukup lama.

Daemon kini tunduk pada konfigurasi kita, dan sisi server sudah beres. Namun setiap perintah yang kita ketik masih melewati satu pihak yang punya preferensi sendiri: docker CLI di sisi klien. Format tampilan docker ps yang ruwet, pilihan context yang tersimpan diam-diam, dan kredensial registry — semuanya dikendalikan berkas kecil bernama config.json di folder .docker milik kita. Chapter Konfigurasi Docker CLI membedah berkas tersebut dan menjadikan terminal kita lebih rapi.

Referensi #