Skip to content
Konsultasi

Sudo yang Bertahan Setiap Container di-Recreate

Adityo Guni Waluyo

Image upstream nggak bawa sudo dan /etc ephemeral. Entrypoint override kecil di compose bikin passwordless sudo terpasang ulang tiap boot.

Container baru aja di-recreate dari image upstream, dan pas buka shell, sudo-nya ilang lagi. Padahal container user butuh sudo buat operasi host. Tiap image di-pull ulang, semua yang terpasang di /etc musnah; direktori itu ephemeral, apapun yang saya taruh di sana hilang saat container dibikin ulang.

Dulu mikirnya: ya udah, install sudo manual tiap kali container jalan. Kadang keinget, kadang nggak, dan pas nggak keinget, tool yang butuh sudo diam-diam gagal di tengah jalan. Ribet, tapi kayaknya cuma itu jalannya.

Salah. Solusinya bukan install sekali, tapi bikin setup yang ikut jalan setiap boot. Commit ini ngubah docker-compose.yml plus nambah script kecil bootstrap-root.sh di folder docker/ repo — compose file yang sama yang dulu bikin dua kontainer bentrok di port 8642.

Bentuknya di compose:

services:
  hermes:
    # Bootstrap root — lihat entrypoint override di bawah.
    volumes:
      - ./docker/bootstrap-root.sh:/opt/data/bin/bootstrap-root.sh
    # Jalan sebagai root sebelum entrypoint image drop privilege,
    # lalu serahkan kendali ke entrypoint asli lewat script ini.
    entrypoint: ["/opt/data/bin/bootstrap-root.sh"]

Script-nya pendek. Jalan sebagai root, pasang sudo kalau belum ada, tulis aturan NOPASSWD ke /etc/sudoers.d/, rapikan permission, terus exec entrypoint asli image:

printf 'hermes ALL=(ALL) NOPASSWD: ALL\n' > /etc/sudoers.d/hermes
chmod 0440 /etc/sudoers.d/hermes

Dua baris itu inti dari semua yang saya butuhkan. Sisanya di script cuma jaga-jaga: apt-get install sudo kalau image nggak bawa, lalu exec ke entrypoint-dispatch.sh bawaan image supaya s6 lanjut kerja kayak biasa dan privilege tetap di-drop ke user biasa.

Sudoers-nya picky soal permission

Urutan eksekusinya punya detail kecil yang gampang kelewat: script diakhiri exec, bukan sekadar nembak entrypoint asli di baris terakhir. Dengan exec, proses shell script digantikan oleh entrypoint image dalam PID yang sama, jadi sinyal lifecycle container sampai ke proses yang benar. Bedanya nggak kelihatan pas container sehat, tapi kerasa pas mau shutdown rapi.

Bagian yang paling gampang salah: file di /etc/sudoers.d/ harus punya root:root dan mode 0440. Kalau nggak, sudo diam-diam mengabaikannya: nggak error, cuma nggak jalan. Red Hat mendokumentasikan aturan ini di panduan manajemen sudo access mereka, termasuk detail kalau #includedir di sudoers itu sintaks, bukan komentar. Tulisan praktik sudoers.d plus visudo di dev.to nambahin detail lain yang bikin saya waspada: nama file yang mengandung titik diabaikan juga. Makanya chmod 0440 itu wajib, bukan opsional, dan nama filenya polos tanpa ekstensi.

Kabel yang menghubungkan semuanya satu aturan compose: entrypoint menimpa ENTRYPOINT dari image, dan kalau diisi non-null, default command image diabaikan referensi services compose. Jadi script kita pegang kendali pertama, beresin urusan root, baru serahkan ke entrypoint original.

Biar yakin bootstrap berhasil, ada dua cek murah yang saya jalankan setelah container naik. sudo -l dari user biasa nunjukkan aturan NOPASSWD yang efektif buat user itu, dan visudo punya mode check (-c) yang bisa mengarah ke file tertentu, enak dipanggil dari script sebelum file sudoers dipakai. Dua-duanya didokumentasikan di tulisan sudoers.d tadi.

Kenapa bukan commit sudo ke image

Bisa nggak image-nya di-fork terus sudo-nya di-bake? Bisa. Tapi tiap upstream rilis versi baru, saya harus rebase lagi. Dengan bootstrap di host yang di-mount tiap boot, upgrade image = docker compose pull polos, dan bootstrap jalan lagi otomatis di atas image baru. Bonus: file bootstrap ikut ke-review di git bareng compose-nya, jadi ada jejak kapan aturan sudo-nya berubah, bukan tersembunyi di layer image.

Saya pribadi pilih pola entrypoint override yang diakhiri exec ke entrypoint asli. Bootstrap-nya idempoten: jalan berkali-kali nggak merusak apa-apa. Dan soal passwordless sudo di container pribadi, itu keputusan sadar, bukan kelalaian — container ini emang extension dari host user, bukan multi-tenant server. Yang tetap saya jaga cuma satu: script bootstrap hidup di host, jadi /etc boleh ephemeral, tapi setup-nya nggak pernah ikut hilang.

Artikel terkait