CMD
dan ENTRYPOINT
instruksi adalah dua Dockerfile
yang sering membingungkan arahan. Keduanya memiliki peran dalam menentukan perintah yang akan dijalankan saat container dimulai.
CMD
dan ENTRYPOINT
dapat diganti secara individual dalam setiap gambar. Penggunaan arahan ini secara efektif membuat container Anda lebih mudah digunakan dengan mempersingkat panjang perintah yang Anda berikan.
Apa Itu Entrypoint?
Kita akan melihat ENTRYPOINT
terlebih dahulu diproses sebelum CMD
saat memulai wadah baru. Titik masuk gambar menentukan proses yang akan dijalankan saat penampung dimulai.
Docker menetapkan titik masuk secara default ke /bin/sh -c
. Ini berarti Anda akan berakhir di sesi shell saat Anda memulai container. Untuk banyak kontainer, lebih diinginkan untuk memiliki peluncuran proses yang berbeda secara default. Anda ingin layanan tanpa kepala segera memulai beban kerjanya.
Menyetel ENTRYPOINT
direktif dalam Dockerfile
menginstruksikan Docker untuk menjalankan perintah tertentu saat container dimulai. Ini akan menjadi proses latar depan, bukan sesi shell default.
ENTRYPOINT ["date"]
Wadah yang dibuat dengan Dockerfile
. ini akan menjalankan date
memerintah. Sebagai date
bukan proses latar depan yang berumur panjang, wadah akan segera keluar setelahnya.
Entrypoints harus berupa binari atau skrip yang dapat dieksekusi. Penampung Anda tidak akan dimulai jika Anda menentukan titik masuk yang tidak valid. Jika Anda menggunakan skrip khusus, pastikan skrip tersebut memiliki bit yang dapat dieksekusi. Anda dapat menambahkan izin eksekusi menggunakan chmod +x my-script.sh
.
Menambahkan Perintah (CMD)
CMD
instruksi adalah sesuatu yang keliru. Ini memberikan argumen default untuk perintah yang didefinisikan oleh ENTRYPOINT
.
ENTRYPOINT ["date"] CMD ["+%A"]
Contoh ini menghasilkan penampung yang menjalankan date +%A
. +%A
argumen untuk date
menampilkan hari saat ini dalam seminggu (mis. Monday
).
CMD
dirancang untuk diganti. docker run
memungkinkan Anda menentukan perintah yang berbeda untuk instance container individual:
docker run my-image +%B
CMD
default akan diganti dengan +%B
, menyebabkan penampung menampilkan nama bulan saat ini. Ini berfungsi karena titik masuk gambar tetap utuh. CMD
selalu ditambahkan ke ENTRYPOINT
, sehingga perintah terakhir menjadi date +%B
.
Anda harus menggunakan ENTRYPOINT
untuk menentukan executable utama container Anda. Gunakan CMD
untuk mendefinisikan argumen default untuk executable itu. Ini akan ditimpa jika penampung dijalankan dengan argumen yang berbeda.
Penggantian Titik Masuk
Anda dapat memaksa Docker untuk memulai gambar menggunakan titik masuk khusus. Lewati --entrypoint
tandai ke docker run
:
docker run --entrypoint /bin/sh my-image
Titik masuk yang ditentukan dalam gambar penampung akan diabaikan demi perintah yang Anda tentukan. Dalam contoh kita, sesi shell akan dimulai, bukan date
perintah.
Mengganti titik masuk harus jarang terjadi. Itu bisa bertentangan dengan niat pembuat gambar. Menyetel titik masuk khusus dapat berguna, terutama saat debugging. Jika penampung berperilaku tidak semestinya, mengganti titik masuknya dapat memberi Anda akses shell yang tidak dapat diperoleh dengan cara lain.
Yang Mana Untuk Digunakan?
Jika Anda seorang pembuat gambar, Anda harus menggunakan ENTRYPOINT
saat menentukan apa yang akan dijalankan oleh wadah Anda. Jika Anda ingin memberikan argumen default, tetapi mengharapkan pengguna untuk menimpanya, sertakan CMD
juga.
Sebagai pengguna gambar, Anda biasanya dapat tetap menggunakan CMD
. docker run
memiliki dukungan transparan untuk penggantian perintah. Argumen apa pun yang diberikan setelah nama gambar akan ditafsirkan sebagai CMD
string untuk wadah.
Mode Titik Masuk:Shell atau Exec
Docker sebenarnya mendukung dua bentuk berbeda dari ENTRYPOINT
:mode exec dan mode shell. Mode Exec dicirikan oleh penggunaan konstruksi array untuk menentukan parameter. Dalam mode shell, perintah ditetapkan sebagai satu string.
# exec mode ENTRYPOINT ["binary", "--param", "--another-param"] # shell mode ENTRYPOINT binary --param --another-param
Menggunakan mode shell menyebabkan biner Anda dieksekusi sebagai subproses dari /bin/sh -c
. Ini memberikan akses titik masuk Anda ke variabel lingkungan yang ditentukan oleh shell.
Mode Shell memiliki pengorbanan. Anda tidak dapat menggunakan CMD
sehingga pengguna tidak akan dapat mengeluarkan penggantian. Argumen yang diberikan ke docker run
akan diabaikan; penampung Anda akan selalu menggunakan titik masuk apa adanya.
Karena biner Anda berjalan di dalam shell, perintah siklus hidup Docker seperti docker stop
dapat bekerja tidak menentu atau tidak sama sekali. Docker akan memberi sinyal pada shell untuk berhenti, bukan proses di dalam. Anda dapat meluncurkan proses Anda dengan exec
untuk menghindari ini.
ENTRYPOINT exec binary --param --another-param
Manfaat Pendekatan Entrypoint Docker
Memisahkan titik masuk dari argumennya membantu Anda menyembunyikan kerumitan dalam wadah Anda. Ini paling bermanfaat saat Anda membuat wadah utilitas untuk merangkum program CLI.
Tetapkan biner CLI Anda sebagai titik masuk gambar. Ini memungkinkan pengguna berinteraksi tanpa mengulang nama biner di setiap perintah.
Pertimbangkan jika kita mengemas Dockerfile
di atas sebagai date:latest
:
# default entrypoint (/bin/sh -c) docker run date:latest date +%A # with `date` as the entrypoint docker run date:latest +%A`
Menyetel titik masuk khusus mempersingkat perintah dan mengurangi pengulangan. Wadah menjadi lebih terspesialisasi dengan memanggil date
secara otomatis. Ini menciptakan antarmuka yang lebih ramah bagi pengguna Anda.
Ringkasan
ENTRYPOINT
Docker dan CMD
instruksi sering menjadi sumber kebingungan. Penamaan mereka menutupi tujuan yang dimaksudkan.
Gunakan ENTRYPOINT
untuk mengatur "perintah" yang akan dijalankan ketika kontainer baru dimulai. Anda dapat menentukan argumen default menggunakan CMD
. ENTRYPOINT
dan CMD
digabungkan bersama untuk menghasilkan string perintah terakhir container.
Saat Anda menggunakan docker run
, Docker menggantikan CMD
default gambar dengan argumen yang Anda tentukan. Jika Anda perlu mengganti titik masuk gambar, gunakan --entrypoint
bendera.