All Newbie, Semua Tentang Ilmu

Recent

Docker Compose yang Tidak Berantakan Setelah 20 Container

Compose file yang dimulai dengan dua belas baris sering berakhir dengan tiga ratus baris, dan tidak ada yang ingat kenapa baris ke-147 ada di sana. Saya sudah membedah puluhan file seperti ini di server orang lain, dan polanya selalu sama: ditambah sedikit-sedikit, tidak pernah dirapikan.

Tumpukan kontainer peti kemas di Pelabuhan Rotterdam
Foto: AgainErick, CC BY-SA 4.0, via Wikimedia Commons

Docker Compose sendiri bukan masalahnya. Masalahnya adalah Compose tidak memaksa Anda membuat keputusan. Semua field opsional, semua default terlihat aman, dan baru enam bulan kemudian Anda tahu bahwa container tanpa batas log bisa menghabiskan disk 40 GB dalam satu akhir pekan.

Satu stack, satu folder

Kesalahan struktural paling awal: menaruh semua layanan dalam satu file besar. Ketika satu layanan bermasalah, Anda harus menyalakan ulang semuanya. Struktur yang saya pakai sejak lama:

/opt/stacks/
  nextcloud/
    compose.yaml
    .env
    data/
  vaultwarden/
    compose.yaml
    .env
    data/

Setiap folder bisa berdiri sendiri. Backup cukup menyalin folder, dan pemulihan tidak bergantung pada file raksasa yang harus dibaca ulang dari awal. Kalau satu stack rusak, yang lain tetap jalan.

Tujuh baris yang seharusnya ada di setiap service

Bukan konfigurasi ajaib, hanya pengaman yang murah dipasang sekarang dan mahal dipasang setelah insiden.

  • restart: unless-stopped — tanpa ini, container yang crash karena OOM akan tetap mati sampai Anda sadar.
  • healthcheck — status "running" tidak berarti aplikasinya sehat. Container bisa hidup sambil mengembalikan 500 untuk semua permintaan.
  • logging dengan max-size dan max-file — ini yang paling sering dilupakan. Log tanpa batas adalah cara paling umum menghabiskan disk tanpa disadari.
  • mem_limit dan cpus — satu container bocor memori bisa membuat seluruh host tidak responsif, termasuk SSH yang Anda butuhkan untuk memperbaikinya.
  • env_file — jangan menulis password di compose.yaml. File .env dengan izin 600, dan jangan pernah masuk Git.
  • security_opt: no-new-privileges:true — murah, dan menutup salah satu jalur eskalasi yang paling sering dipakai.
  • versi image yang dipatok — nextcloud:29.0.7, bukan nextcloud:latest. Ini yang membuat rollback mungkin dilakukan.

Contoh potongan yang menerapkan semuanya:

services:
  app:
    image: nextcloud:29.0.7
    restart: unless-stopped
    env_file: .env
    mem_limit: 1g
    security_opt:
      - no-new-privileges:true
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost/status.php"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 60s

start_period penting untuk aplikasi yang butuh waktu inisialisasi. Tanpa itu, healthcheck akan menandai container gagal sebelum ia sempat selesai migrasi database.

depends_on bukan penanda bahwa layanan siap

Ini kesalahpahaman yang paling mahal. depends_on hanya mengatur urutan start, bukan kesiapan. Database yang sudah "started" belum tentu menerima koneksi.

depends_on:
  db:
    condition: service_healthy

Dengan condition: service_healthy, Compose menunggu healthcheck database lulus. Tapi bahkan itu belum cukup: aplikasi tetap harus punya logika retry, karena koneksi bisa putus kapan saja setelah start. Aplikasi yang tidak bisa menangani database yang restart sebentar bukan aplikasi yang siap dipakai.

Bind mount atau named volume

Aturan praktis yang saya pakai: kalau data itu ingin Anda lihat dan cadangkan dengan mudah, bind mount. Kalau data itu milik aplikasi dan strukturnya tidak Anda pahami, named volume.

Yang wajib dipahami: named volume hidup di /var/lib/docker/volumes. Banyak orang mencadangkan folder project, merasa aman, lalu kehilangan seluruh database saat menjalankan docker compose down -v. Perintah itu menghapus volume tanpa konfirmasi, dan tidak ada tombol undo.

Untuk database, jangan menyalin file datanya saat container berjalan. Hasilnya sering tampak baik-baik saja sampai Anda mencoba restore. Dump dulu:

docker compose exec -T db pg_dump -U app appdb > backup/appdb-$(date +%F).sql

Alur update yang bisa dibatalkan

Urutan yang saya pakai untuk setiap pembaruan, tanpa kecuali:

  • Catat tag image yang sedang berjalan. Ini satu-satunya jalan pulang.
  • Dump database atau ambil snapshot volume.
  • Ubah tag di compose.yaml, lalu docker compose pull.
  • docker compose up -d, lalu periksa healthcheck dan log selama beberapa menit.
  • Kalau gagal, kembalikan tag lama dan jalankan ulang. Prosesnya harus di bawah dua menit.

Kalau langkah terakhir terasa sulit, berarti ada yang salah dengan cara Anda memakai tag. latest membuat rollback tidak mungkin karena Anda tidak tahu versi apa yang tadi berjalan.

Yang tidak perlu dimasukkan ke Compose

Tidak semua hal layak jadi container. VPN tingkat kernel, driver storage, dan tool yang butuh akses perangkat keras sering lebih baik dipasang langsung di host. Memaksakan semuanya masuk Docker hanya menambah lapisan yang harus di-debug saat bermasalah.

Compose yang baik terasa membosankan: pendek, eksplisit, dan setiap barisnya bisa dijelaskan. Kalau Anda tidak bisa menjelaskan satu baris, hapus baris itu — atau tulis alasannya sebagai komentar. Enam bulan lagi, orang yang membaca file itu adalah Anda sendiri.

Baca juga:





0 comments:

Post a Comment