Tidak suka iklan? Pergi Bebas Iklan Hari ini

Docker ENTRYPOINT vs CMD — Kontainer Pernah Menipu Anda

Diperbarui pada

Anda menggabungkan ENTRYPOINT dan CMD dalam Dockerfile, container memulai hal yang salah, dan sekarang Anda berada di sini. Berikut penjelasan lengkapnya — setiap kombinasi, penangkap trap antara shell dan bentuk exec, serta pola yang benar-benar berfungsi.

Anda menggabungkan ENTRYPOINT dan CMD dalam Dockerfile Anda, kontainer memulai hal yang salah, dan sekarang Anda di sini. Berikut penjelasan lengkap — setiap kombinasi, penangkapan sinyal bentuk shell vs exec, dan pola yang benar-benar bekerja.
IKLAN · HAPUS?

Kesalahan terjadi pukul 2 pagi. Anda memulai kontainer, dan bukannya server API Anda, Anda mendapatkan prompt shell. Atau tidak ada sama sekali. Atau proses Anda berjalan terkunci dalam sesuatu yang tidak nyata. sh yang memakan SIGTERM seperti permen — sehingga penutupan yang halus membutuhkan 10 detik dari Docker sebelum menyerah dan mengirimkan SIGKILL.

Penyebabnya, hampir setiap kali: Anda membingungkan ENTRYPOINT dan CMD. Atau menggabungkannya dalam cara-cara yang Docker terima secara diam-diam — hanya tidak seperti yang Anda harapkan.

CMD: Default yang Bisa Diganti

CMD menentukan apa yang berjalan saat Anda memulai kontainer — tetapi ini hanya saran, bukan aturan. Masukkan apa pun setelah nama gambar dan itu akan digantikan secara utuh:

FROM ubuntu
CMD ["echo", "hello from CMD"]
$ docker run myimage
hello from CMD

$ docker run myimage echo goodbye
goodbye

Itu echo goodbye tidak ditambahkan — itu digantikan. Seluruh CMD hilang. Ini adalah desain yang ditetapkan: CMD adalah perilaku default, bukan perilaku yang diperkuat. Setiap argumen runtime menang.

ENTRYPOINT: Bagian yang Selalu Berjalan

ENTRYPOINT menentukan eksekutable yang berjalan tanpa tergantung pada apa pun. Argumen runtime tidak menggantikannya — mereka hanya dikirimkan ke dalamnya:

FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["hello"]
$ docker run myimage
hello

$ docker run myimage goodbye
goodbye

$ docker run --entrypoint cat myimage /etc/hostname
mycontainer-abc123

Ketika keduanya diatur, ENTRYPOINT adalah eksekutable dan CMD menjadi argumen default. Anda dapat menggantinya secara bebas. Anda dapat menggantinya CMD hanya jika Anda secara eksplisit mengirimkan ENTRYPOINT Setiap kombinasi ENTRYPOINT + CMD, Dijelaskan --entrypoint.

Dokumen Docker mencantumkan tabel ini tetapi tidak memperhatikan baris-baris yang akan menghancurkan hari Anda:

Apa yang sebenarnya berjalan

ENTRYPOINTCMDKesalahan — kontainer membutuhkan perintah dari suatu tempat
Tidak diaturTidak diaturbentuk exec
Tidak diatur["cmd", "arg"] bentuk shellcmd arg
Tidak diaturcmd arg/bin/sh -c "cmd arg"
["entry"] bentuk shellTidak diaturentry
["entry"] bentuk shell["arg1", "arg2"] bentuk shellentry arg1 arg2 — hampir pasti salah
["entry"] bentuk shellcmd argentry /bin/sh -c "cmd arg" CMD diam-diam diabaikan
entry["arg1"] bentuk shell/bin/sh -c "entry"Dua baris yang ditandai "CMD diam-diam diabaikan" bertanggung jawab atas sebagian besar sesi perbaikan Docker. Bentuk shell
entrycmd arg/bin/sh -c "entry"Dua baris yang ditandai "CMD diam-diam diabaikan" bertanggung jawab atas sebagian besar sesi perbaikan Docker. Bentuk shell

tidak digabungkan dengan ENTRYPOINT — itu diabaikan secara utuh. Docker tidak memperingatkan Anda tentang ini. CMD Bentuk Shell vs Bentuk Exec: Penangkapan Sinyal

Kedua instruksi menerima dua bentuk, dan pilihan ini lebih penting daripada yang biasanya diakui dalam tutorial Dockerfile.

Bentuk exec

(sintaks array): Eksekutable Anda berjalan secara langsung. Ini menjadi PID 1. Ketika Docker mengirimkan

ENTRYPOINT ["nginx", "-g", "daemon off;"]

untuk menghentikan kontainer, proses Anda menerima sinyal tersebut. Penutupan yang halus bekerja. Log disimpan. Koneksi ditutup secara bersih. SIGTERM (string biasa):

Bentuk Shell Docker menjalankan ini sebagai

ENTRYPOINT nginx -g "daemon off;"

. Shell menjadi PID 1. Ketika /bin/sh -c "nginx -g daemon off;"datang, SIGTERM mendapatkannya — dan sh tidak menyalurkan sinyal ke proses anak. Kontainer terhambat selama 10 detik, menerima sh , dan mati tanpa pembersihan. Setiap kali. SIGKILLGunakan bentuk exec. Selalu. Untuk kedua

Tiga Pola yang Benar-Benar Bekerja ENTRYPOINT dan CMD.

Polanya 1: Eksekutable tetap, default yang dapat diubah

Polanya yang tepat untuk kebanyakan kontainer produksi. Eksekutable tetap; flag-nya dapat diganti saat runtime:

Polanya 2: Skrip wrapper dengan exec

ENTRYPOINT ["/app/server"]
CMD ["--port", "8080", "--env", "production"]
# Use defaults
docker run myimage

# Override at deploy time
docker run myimage --port 9090 --env staging

Ketika Anda membutuhkan logika awal sebelum proses utama (migrasi, injeksi rahasia, penangkapan sinyal), gunakan skrip wrapper. Baris kritis adalah

di akhir — ini menggantikan proses shell dengan CMD Anda, sehingga eksekutable Anda menjadi PID 1: exec "$@" Jika Anda melewatkan

#!/bin/sh
set -e

echo "Running migrations..."
/app/migrate

# Hand off to CMD — exec replaces shell, so /app/server becomes PID 1
exec "$@"
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/app/server", "--port", "8080"]

, shell tetap menjadi PID 1 dan Anda kembali ke masalah penanganan sinyal. exec "$@"Polanya 3: Hanya CMD, tanpa ENTRYPOINT

Cukup untuk gambar pengembangan atau kontainer alat di mana Anda ingin menjalankan perintah sembarang dalam lingkungan yang sama:

Untuk produksi, pola 1 atau 2 lebih aman — Anda tidak ingin skrip deplikasi yang salah dikonfigurasi secara tidak sengaja menjalankan

FROM python:3.12-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

dan menggantikan server Anda dengan sesi shell. docker run myimage bash Apa yang harus dilakukan oleh docker exec

Tidak apa-apa.

menjalankan perintah dalam kontainer yang sudah berjalan. Ini menghindari docker exec secara utuh. Anda tidak perlu memikirkan ENTRYPOINT saat Anda menjalankan ENTRYPOINT untuk menggali — Anda berbicara dengan lingkungan kontainer yang hidup, bukan konfigurasi startup. docker exec mycontainer bash Kesalahan biasanya muncul dari orang yang menggunakan

dan memastikan sesuatu berfungsi, lalu bertanya mengapa docker exec berperilaku berbeda. Keduanya adalah jalur kode yang berbeda. docker run Daftar Pemeriksaan Sebelum Penyimpanan

gunakan bentuk exec (sintaks array, bukan string biasa)

  • Kedua-duanya ENTRYPOINT dan CMD Jika Anda memiliki skrip wrapper, akhirnya berakhir dengan
  • Anda telah menguji exec "$@"
  • untuk memastikan kedua jalur berfungsi docker run myimage dan docker run myimage --your-flag selesai dalam kurang dari 2 detik (bukan 10 — jika 10, Anda mengalami masalah sinyal)
  • docker stop mycontainer Jika Anda ingin umpan balik otomatis sebelum Dockerfile pergi ke registry,

IO Tools’ Dockerfile Linter mendeteksi penggunaan bentuk shell, kehilangan dalam skrip entrypoint, dan pola lain yang menyebabkan perilaku yang tidak terlihat saat runtime. exec Docker ENTRYPOINT vs CMD — Kontainer Anda Menyia-nyiakan Anda 2

Ingin bebas iklan? Bebas Iklan Hari Ini

Instal Ekstensi Kami

Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat

Ke Ekstensi Chrome Ke Ekstensi Tepi Ke Ekstensi Firefox Ke Ekstensi Opera

Papan Skor Telah Tiba!

Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!

IKLAN · HAPUS?
IKLAN · HAPUS?
IKLAN · HAPUS?

Pojok Berita dengan Sorotan Teknologi

Terlibat

Bantu kami untuk terus menyediakan alat gratis yang berharga

Belikan aku kopi
IKLAN · HAPUS?