What is the Difference Between CMD vs ENTRYPOINT in Docker?
CMD and ENTRYPOINT are Dockerfile instructions used to define what command should run when a Docker container starts.
Both are important in Docker container startup behavior, but they work differently and are used for different production use cases in DevOps, Kubernetes, CI/CD, microservices, and cloud-native applications.
Why CMD and ENTRYPOINT Matter
When a Docker container starts, Docker needs to know:
- Which process should start?
- Which application should run?
- What should happen if users pass additional commands?
CMD and ENTRYPOINT control this startup behavior.
Real-Time Analogy
ENTRYPOINT:
Main application
CMD:
Default parameters/options for application
Think of ENTRYPOINT like a fixed executable and CMD like default arguments.
High-Level Container Startup Flow
Docker Container Starts
|
v
ENTRYPOINT Executes
|
v
CMD Arguments Passed
|
v
Application Runs
What is CMD?
CMD defines the default command or arguments that run when the container starts.
CMD can be overridden easily at runtime.
Basic CMD Example
FROM ubuntu
CMD ["echo", "Hello Docker"]
Run Container
docker run my-image
Output
Hello Docker
CMD Override Example
docker run my-image echo "Overridden Command"
Docker replaces CMD with the new command.
Output
Overridden Command
What is ENTRYPOINT?
ENTRYPOINT defines the main executable process of the container.
Unlike CMD, ENTRYPOINT is not replaced automatically when arguments are passed.
Basic ENTRYPOINT Example
FROM ubuntu
ENTRYPOINT ["echo", "Hello Docker"]
Run Container
docker run my-image
Output
Hello Docker
ENTRYPOINT with Additional Arguments
docker run my-image "Additional Text"
Actual Execution
echo "Hello Docker" "Additional Text"
Output
Hello Docker Additional Text
Docker appends runtime arguments to ENTRYPOINT instead of replacing it.
CMD vs ENTRYPOINT Core Difference
| Feature | CMD | ENTRYPOINT |
|---|---|---|
| Purpose | Default command/arguments | Main executable |
| Can be overridden? | Yes | Not easily |
| Runtime behavior | Replaced by runtime command | Runtime args appended |
| Production usage | Default arguments | Main application process |
Shell Form vs Exec Form
CMD and ENTRYPOINT support two formats:
- Shell Form
- Exec Form
Shell Form
CMD java -jar app.jar
OR
ENTRYPOINT java -jar app.jar
Problems with Shell Form
- Runs through shell
- Poor signal handling
- Harder graceful shutdown
- Issues in Kubernetes
Exec Form (Recommended)
CMD ["java", "-jar", "app.jar"]
OR
ENTRYPOINT ["java", "-jar", "app.jar"]
Benefits
- Proper signal handling
- Better process management
- Works well in Kubernetes
- Graceful shutdown support
Why ENTRYPOINT is Preferred in Production
In production systems, containers usually represent a single application.
Payment Service Container
|
v
Always runs Payment Application
ENTRYPOINT guarantees that the application always starts.
Production Spring Boot Example
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
COPY app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
This ensures the Spring Boot application always starts correctly.
CMD for Default Arguments
CMD is commonly used with ENTRYPOINT to provide default parameters.
Example
FROM ubuntu
ENTRYPOINT ["ping"]
CMD ["google.com"]
Run Container
docker run my-image
Actual Execution
ping google.com
Override CMD Example
docker run my-image yahoo.com
Actual Execution
ping yahoo.com
CMD value changes while ENTRYPOINT remains fixed.
Production Architecture Example
Consider a global learning platform serving users from USA, UK, and India.
Microservices:
API Gateway
Course Service
Interview Service
Payment Service
Notification Service
Each container should always start its application process.
ENTRYPOINT ["java", "-jar", "app.jar"]
This ensures consistent container behavior across:
- Docker Compose
- Kubernetes
- AWS ECS
- CI/CD pipelines
How Docker Handles CMD and ENTRYPOINT Internally
Only CMD
CMD ["java", "-jar", "app.jar"]
Runtime
docker run image
Execution
java -jar app.jar
Only ENTRYPOINT
ENTRYPOINT ["java", "-jar", "app.jar"]
Runtime
docker run image
Execution
java -jar app.jar
ENTRYPOINT + CMD Together
ENTRYPOINT ["java"]
CMD ["-jar", "app.jar"]
Execution
java -jar app.jar
Override CMD Runtime
docker run image -version
Execution
java -version
CMD changes, ENTRYPOINT remains.
How to Override ENTRYPOINT
ENTRYPOINT can still be overridden explicitly.
docker run --entrypoint bash image
This is useful for debugging production containers.
Common Production Use Cases
| Use Case | Recommended |
|---|---|
| Fixed application container | ENTRYPOINT |
| Default runtime arguments | CMD |
| Debug container | CMD |
| Production microservice | ENTRYPOINT |
| Flexible utility container | CMD |
Production Dockerfile Example
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
RUN groupadd -r appuser && useradd -r -g appuser appuser
COPY app.jar app.jar
RUN chown -R appuser:appuser /app
USER appuser
EXPOSE 8080
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar", "app.jar"]
Why ENTRYPOINT is Better for Kubernetes
Kubernetes manages containers as long-running application processes.
ENTRYPOINT works better because:
- Main process remains fixed
- Signal handling works correctly
- Graceful shutdown works
- Readiness/liveness probes behave correctly
Signal Handling Importance
In Kubernetes, containers receive signals like:
SIGTERM
SIGKILL
Exec-form ENTRYPOINT properly forwards signals to the application.
Bad Production Example
ENTRYPOINT java -jar app.jar
Problems
- Shell process becomes PID 1
- Signals may not reach Java process
- Graceful shutdown problems
Good Production Example
ENTRYPOINT ["java", "-jar", "app.jar"]
Benefits
- Java process becomes PID 1
- Proper signal handling
- Better Kubernetes integration
Container Startup Diagram
Docker Container Starts
|
v
ENTRYPOINT Executes
|
v
CMD Arguments Applied
|
v
Application Process Starts
|
v
Container Running
Common CMD vs ENTRYPOINT Mistakes
- Using shell form instead of exec form
- Using CMD when application must always run
- Hardcoding parameters in CMD unnecessarily
- Improper signal handling
- Confusing CMD override behavior
Best Practices
- Use ENTRYPOINT for production applications
- Use CMD for default arguments
- Use exec form always
- Keep containers focused on one process
- Test signal handling in Kubernetes
Production Example with ENTRYPOINT + CMD
FROM python:3.11-slim
WORKDIR /app
COPY app.py .
ENTRYPOINT ["python"]
CMD ["app.py"]
Default Execution
python app.py
Override CMD
docker run image test.py
Execution
python test.py
Interview Answer
CMD and ENTRYPOINT are Dockerfile instructions used to define container startup behavior. CMD provides default commands or arguments that can be overridden at runtime, while ENTRYPOINT defines the main executable that always runs when the container starts.
In production systems, ENTRYPOINT is commonly used for the main application process, while CMD is used for default arguments. Exec-form syntax is recommended because it provides proper signal handling and better Kubernetes compatibility.
Quick Summary Table
| Scenario | Best Choice |
|---|---|
| Always run application | ENTRYPOINT |
| Provide default arguments | CMD |
| Production microservice | ENTRYPOINT |
| Debug/testing container | CMD |
Useful Internal Links
- Docker Interview Questions
- DevOps Interview Questions
- Kubernetes Interview Questions
- Microservices Interview Questions
- AWS Interview Questions
- Spring Boot Interview Questions
Final Conclusion
CMD and ENTRYPOINT are essential Dockerfile instructions that define container startup behavior. ENTRYPOINT is best suited for production applications because it guarantees the main process always runs, while CMD provides flexible default arguments.
In modern Kubernetes and microservices environments, production containers should generally use exec-form ENTRYPOINT for proper signal handling, graceful shutdown, and stable container lifecycle management.