Topik ini membahas penyuntikan konfigurasi ke container pada saat dijalankan, baik melalui opsi -e maupun berkas env. Pembahasan mencakup alasan konfigurasi tidak disimpan di dalam image, format -e dan --env-file, demo program Python yang perilakunya berubah mengikuti variabel yang diberikan, serta konvensi variabel pada image populer seperti postgres. Setelah membacanya, satu image yang sama dapat digunakan pada berbagai lingkungan hanya dengan mengganti konfigurasinya.
Konfigurasi pada saat berjalan#
Image bersifat tetap, sedangkan konfigurasi berubah menurut lingkungan pemakaiannya. Aplikasi catatan yang sama membutuhkan mode debug pada lingkungan pengembangan dan mode production pada lingkungan produksi, dengan port yang boleh berbeda pula. Membangun ulang image setiap kali konfigurasi berubah berarti menaruh konfigurasi di tempat yang salah, yaitu di dalam image yang sifatnya tetap.
Konfigurasi diberikan melalui variabel lingkungan (environment variable), yaitu pasangan kunci dan nilai yang disediakan sistem operasi kepada proses pada saat proses dimulai. Opsi -e pada docker run menambahkan pasangan tersebut ke lingkungan proses utama di dalam container, sehingga aplikasi membacanya seperti variabel lingkungan biasa. Nilainya hanya melekat pada container yang dibuat saat itu, dan mengganti konfigurasi berarti menjalankan container lagi dengan nilai yang baru.
Menyuntikkan nilai dengan -e#
Opsi -e KUNCI=nilai dituliskan setelah docker run dan sebelum nama image. Satu perintah boleh membawa beberapa -e sekaligus, dan nilai yang memuat spasi diberi tanda kutip agar tidak terpotong. Contoh berikut menjalankan image aplikasi catatan dengan dua variabel sekaligus.
# tidak-dijalankan: daemon Docker tidak tersedia di sandbox
# dua variabel sekaligus pada satu container
docker run --rm -e APP_MODE=debug -e APP_PORT=8080 catatan
# nilai dengan spasi diberi tanda kutip
docker run --rm -e CATATAN_JUDUL="Catatan Mingguan" catatanSetiap -e mengatur satu pasangan kunci dan nilai untuk container tersebut, tanpa menyentuh image dan tanpa menyentuh container lain. Aplikasi di dalam container tidak perlu tahu dari mana nilainya berasal, sehingga mekanisme ini bekerja untuk aplikasi apa pun yang sudah membaca variabel lingkungan. Perubahan konfigurasi pun berlangsung pada tingkat perintah, bukan pada tingkat program.
Berkas env dan –env-file#
Daftar variabel yang panjang membuat perintah docker run sulit dibaca, sehingga pasangan kunci dan nilai dapat dipindahkan ke sebuah berkas env, yaitu berkas teks yang memuat satu baris KUNCI=nilai untuk setiap variabel. Baris yang diawali # diperlakukan sebagai komentar. Berkas berikut adalah konfigurasi aplikasi catatan untuk lingkungan produksi.
# konfigurasi aplikasi catatan
APP_PORT=8000
APP_MODE=productionBerkas ini berada di host, yaitu mesin tempat Docker berjalan, bukan di dalam image, sehingga nilainya dapat disunting tanpa membangun ulang apa pun. Opsi --env-file mengarahkan Docker membaca berkas tersebut saat container dibuat, dan opsi ini boleh dicampur dengan -e pada satu perintah yang sama.
# tidak-dijalankan: daemon Docker tidak tersedia di sandbox
docker run --rm --env-file konfig.env catatanMembuat satu berkas env untuk setiap lingkungan menjaga perintah docker run tetap pendek, sedangkan riwayat konfigurasinya tetap terbaca dari isi berkasnya. Berkas untuk lingkungan pengembangan dapat memuat APP_MODE=debug, sementara berkas produksi memuat APP_MODE=production, tanpa satu pun perubahan pada image.
Demo aplikasi catatan#
Program Python berikut membaca dua variabel dari os.environ dengan nilai bawaan, lalu melaporkan konfigurasi efektifnya. Berkas inilah yang dijalankan dua kali pada demo berikut.
import os
port = int(os.environ.get("APP_PORT", "8000"))
mode = os.environ.get("APP_MODE", "production")
print(f"Aplikasi catatan berjalan pada port {port} dengan mode {mode}")Aplikasi catatan berjalan pada port 8000 dengan mode productionTanpa variabel apa pun, kedua nilai bawaan terpakai dan program melaporkan port 8000 dengan mode production. Perilakunya dapat diubah tanpa menyentuh berkasnya, cukup dengan memberi variabel lingkungan pada saat program dipanggil. Jalankan berkas yang sama dua kali, pertama tanpa variabel lalu dengan dua variabel tersuntik, dan bandingkan kedua baris keluarannya.
# jalankan tanpa variabel lingkungan, nilai bawaan terpakai
python3 app.py
# jalankan dengan dua variabel lingkungan tersuntik
APP_MODE=debug APP_PORT=8080 python3 app.pyAplikasi catatan berjalan pada port 8000 dengan mode production
Aplikasi catatan berjalan pada port 8080 dengan mode debugBerkas app.py tidak diubah sama sekali, tetapi keluarannya berbeda pada kedua eksekusi. Opsi -e pada docker run melakukan hal yang sama terhadap proses utama di dalam container, sehingga pola pada demo ini persis seperti yang diterapkan Docker.
Konvensi image populer#
Nama variabel dan maknanya adalah konvensi milik masing-masing image, bukan milik Docker. Dokumentasi image itulah satu-satunya sumber yang dapat diandalkan, karena Docker sendiri hanya meneruskan pasangan kunci dan nilai tanpa memahami maknanya. Tabel berikut memuat konvensi yang sering dijumpai.
| Variabel | Image | Fungsi |
|---|---|---|
POSTGRES_PASSWORD | postgres | Kata sandi akun superuser basis data, wajib diisi, image menolak berjalan tanpanya |
POSTGRES_DB | postgres | Nama basis data awal yang dibuat saat container pertama berjalan |
PYTHONDONTWRITEBYTECODE | python | Menonaktifkan penulisan berkas .pyc saat program dijalankan |
PYTHONUNBUFFERED | python | Membuat keluaran stdout tidak ditahan buffer sehingga langsung tampil pada log |
Variabel PYTHONUNBUFFERED mempermudah banyak diagnosis. Tanpa variabel itu, keluaran Python ditahan dalam buffer, yaitu penampung sementara di memori, sehingga docker logs tampak hening seolah aplikasi tidak berjalan, padahal aplikasi hanya belum membuang isi buffernya.
Kesalahan umum#
Salah ketik nama variabel. Aplikasi membaca
APP_PORT, tetapi perintah memberiAPP_PROT. Program tidak menampilkan error apa pun dan diam-diam memakai nilai bawaan, sehingga kesalahannya baru ketahuan dari perilaku yang tidak sesuai. Perbaikannya dengan membuat program melaporkan konfigurasi efektifnya saat mulai, sebagaimanaapp.pypada demo di atas.Menganggap nilai
-emenetap untuk selamanya. Nilai tersebut hanya melekat pada container yang dibuat saat itu, sehingga container baru tanpa-ekembali ke nilai bawaan. Perbaikannya dengan menuliskan perintahdocker runlengkap dalam sebuah skrip atau dengan memindahkan daftar variabel ke berkas env agar tidak ada yang terlewat.
Ringkasan#
- Konfigurasi diberikan pada saat berjalan melalui
-e KUNCI=nilaiatau--env-file, tanpa membangun ulang image. - Berkas env memuat satu pasangan
KUNCI=nilaiper baris dan baris yang diawali#diperlakukan sebagai komentar. - Nama variabel adalah konvensi masing-masing image, misalnya
POSTGRES_PASSWORDpada image postgres danPYTHONUNBUFFEREDpada image python. - Program yang melaporkan konfigurasi efektifnya mempermudah diagnosis penyuntikan yang meleset.
Referensi#
- Overriding container defaults — Docker Docs
— Konsep mengatur ulang default container dengan opsi
docker run. - docker container run — Docker Docs
— Rujukan opsi
-edan--env-file.