ENTRYPOINT και CMD καθορίζουν και τα δύο τι εκτελείται όταν ξεκινά ένα container, αλλά εξυπηρετούν διαφορετικούς ρόλους και αλληλεπιδρούν με συγκεκριμένους τρόπους. Η κατανόηση της διαφοράς (και των δύο μορφών — exec vs shell) είναι σημαντική για τη σύνταξη Dockerfiles που συμπεριφέρονται σωστά.
CMD — η προεπιλεγμένη εντολή (εναλλάξιμη)
CMD ["node", "server.js"]
# → the DEFAULT command when the container starts
# → but it's REPLACED if you pass a command at run time:
# docker run myapp echo hello → runs "echo hello" INSTEAD of node server.js
CMD παρέχει την προεπιλεγμένη εντολή, η οποία αντικαθίσταται πλήρως από οποιαδήποτε εντολή δίνεται στο docker run.
ENTRYPOINT — το σταθερό εκτελέσιμο
ENTRYPOINT ["node", "server.js"]
# → ALWAYS runs; run-time arguments are APPENDED (not replacing it):
# docker run myapp --port 8080 → runs "node server.js --port 8080"
# → makes the container behave like a specific executable
ENTRYPOINT ορίζει ένα σταθερό εκτελέσιμο που εκτελείται πάντα· τα ορίσματα χρόνου εκτέλεσης προστίθενται ως τα ορίσματά του αντί να το αντικαθιστούν.
Χρήση τους μαζί (το κοινό pattern)
ENTRYPOINT ["node", "server.js"] # the fixed command
CMD ["--port", "3000"] # DEFAULT arguments (overridable)
# docker run myapp → node server.js --port 3000 (defaults)
# docker run myapp --port 8080 → node server.js --port 8080 (CMD overridden)
→ ENTRYPOINT = the command; CMD = default arguments you can override. A clean pattern.
Exec form vs shell form
EXEC form → CMD ["node", "server.js"] (JSON array) — PREFERRED:
runs the executable DIRECTLY (PID 1) → receives signals (SIGTERM) → graceful shutdown
SHELL form → CMD node server.js → runs via /bin/sh -c → the shell is PID 1,
the app may NOT receive signals properly (shutdown issues) → avoid for the main process
Γιατί έχει σημασία
Η κατανόηση της διαφοράς μεταξύ ENTRYPOINT και CMD είναι σημαντική για τη σύνταξη Dockerfiles που συμπεριφέρονται σωστά, επομένως είναι πολύτιμη πρακτική γνώση και ένα συνήθως συγχεόμενο θέμα.
Η διάκριση στη συμπεριφορά έχει σημασία: CMD παρέχει μια προεπιλεγμένη εντολή που αντικαθίσταται πλήρως από οποιαδήποτε εντολή περνάται στο docker run, ενώ ENTRYPOINT ορίζει ένα σταθερό εκτελέσιμο που εκτελείται πάντα με ορίσματα χρόνου εκτέλεσης προστιθέμενα σε αυτό — διαφορετικές συμπεριφορές που επηρεάζουν πώς το container ανταποκρίνεται στα ορίσματα χρόνου εκτέλεσης.
Η κατανόηση του κοινού pattern χρήσης τους μαζί (ENTRYPOINT ως εντολή και CMD ως εναλλάξιμα προεπιλεγμένα ορίσματα) είναι μια καθαρή, idiomatική προσέγγιση που κάνει τα containers να συμπεριφέρονται όπως ρυθμιζόμενα εκτελέσιμα — μια ευρέως χρησιμοποιούμενη τεχνική που αξίζει να γνωρίζετε.
Καθοριστικά, η κατανόηση του exec form vs shell form είναι σημαντική για την ορθότητα: το exec form (JSON array, π.χ. CMD ["node", "server.js"]) είναι προτιμώμενο επειδή εκτελεί το εκτελέσιμο απευθείας ως PID 1, επομένως λαμβάνει σήματα όπως SIGTERM σωστά, ενεργοποιώντας graceful shutdown — ενώ το shell form (CMD node server.js) εκτελείται μέσω ενός shell που γίνεται PID 1, συχνά προκαλώντας την εφαρμογή να μην λαμβάνει σήματα shutdown σωστά (οδηγώντας σε ungraceful termination, χαμένη in-flight work ή αργή διακοπή).
Αυτό το πρόβλημα χειρισμού σημάτων/graceful shutdown είναι πραγματικό, λεπτό πρόβλημα που το exec form αποφεύγει.
Επειδή ο ορισμός του τι εκτελείται όταν ξεκινά ένα container είναι θεμελιώδης για κάθε Dockerfile, και επειδή η διάκριση ENTRYPOINT/CMD (και το exec-vs-shell-form signal-handling concern) επηρεάζει άμεσα τη συμπεριφορά και την ορθότητα του container (handling ορισμάτων, graceful shutdown), η κατανόηση του ENTRYPOINT vs CMD — τα ρόλια τους, πώς συνδυάζονται και η σημαντική πρακτική exec-form-for-signals — είναι πολύτιμη, πρακτικά σχετική Docker γνώση, ένα συνήθως παρεξηγημένο θέμα όπου η κατανόηση των διαφορών προλαμβάνει πραγματικά προβλήματα συμπεριφοράς και shutdown.
