logoPushwant Rai
Home
Experience
Education
Projects
Achievements
Blogs

Elsewhere

GitHub
LinkedIn
hi@pushwantrai.com.np

Theme

Understanding Docker RUN, CMD, and ENTRYPOINT

Sep 02, 2023

#docker#dockerfile

Table of Contents

  • Introduction
  • The RUN Command: Your Image Builder
  • The CMD Command: Your Default Instructions
  • The ENTRYPOINT: Your Container's Primary Purpose
  • How They Work Together
  • Common Use Cases
  • Best Practices
  • Quick Reference Table
  • Example: Putting It All Together
  • Conclusion

Introduction

When working with Docker, understanding the difference between RUN, CMD, and ENTRYPOINT is key to effectively managing how containers are executed. These commands serve different purposes in controlling the behavior of a container when it's started.

The RUN Command: Your Image Builder

Think of RUN as your container's construction worker. It executes during the image build process, setting up your environment.

Here's what RUN does:

  • Installs packages
  • Creates directories
  • Copies files
  • Sets up your environment

Example:

FROM python:3.9 RUN apt-get update RUN pip install flask RUN mkdir /app

Each RUN command creates a new layer in your image. It's like adding a new floor to a building - permanent and part of the structure.

The CMD Command: Your Default Instructions

CMD is like leaving a note saying "here's what to do if no one says otherwise." It provides default commands or parameters that can be easily overridden.

Key points about CMD:

  • You can only have one CMD instruction in a Dockerfile
  • It can be overridden from the command line
  • It specifies the default program that should run in your container

There are three forms of CMD:

# Shell form CMD python app.py # Exec form (preferred) CMD ["python", "app.py"] # Parameters for ENTRYPOINT CMD ["--port", "8080"]

The ENTRYPOINT: Your Container's Primary Purpose

ENTRYPOINT defines your container's main executable. Think of it as your container's mission in life - it's what the container is designed to do.

Two forms of ENTRYPOINT:

# Shell form ENTRYPOINT python app.py # Exec form (preferred) ENTRYPOINT ["python", "app.py"]

How They Work Together

The real magic happens when you combine these commands. Here's how they interact:

  1. RUN sets up your environment
  2. ENTRYPOINT sets the main executable
  3. CMD provides default arguments

Example:

FROM python:3.9 # Setup phase RUN pip install flask RUN mkdir /app WORKDIR /app COPY . . # Runtime configuration ENTRYPOINT ["python"] CMD ["app.py", "--port", "8080"]

In this case:

  • If you run the container normally: It executes python app.py --port 8080
  • If you run with arguments: docker run myimage script.py, it runs python script.py

Common Use Cases

Web Server Example

FROM nginx:alpine RUN mkdir -p /usr/share/nginx/html COPY ./website /usr/share/nginx/html ENTRYPOINT ["nginx"] CMD ["-g", "daemon off;"]

Application Server Example

FROM node:14 RUN mkdir /app WORKDIR /app COPY package*.json ./ RUN npm install COPY . . ENTRYPOINT ["node"] CMD ["server.js"]

Best Practices

  1. For RUN:

    • Use for installation and setup
    • Combine related commands with && to reduce layers
    • Clean up after installations
  2. For CMD:

    • Always use the exec form ["executable", "param1", "param2"]
    • Use for default parameters that might need to change
    • Remember it can be overridden at runtime
  3. For ENTRYPOINT:

    • Use for commands that shouldn't change
    • Combine with CMD for flexible defaults
    • Always use exec form for predictable behavior

Quick Reference Table

CommandPurposeCan Override?Multiple Allowed?
RUNBuild-time setupNoYes
CMDDefault runtime command/argsYesNo (last one wins)
ENTRYPOINTContainer's main executableYes (--entrypoint)No (last one wins)

Example: Putting It All Together

Here's a complete example showing all three commands working together:

FROM python:3.9 # RUN commands for setup RUN apt-get update && \ apt-get install -y --no-install-recommends \ postgresql-client && \ rm -rf /var/lib/apt/lists/* RUN pip install flask psycopg2-binary # Setup application WORKDIR /app COPY . . # Set the main executable ENTRYPOINT ["python"] # Set default arguments CMD ["app.py", "--host", "0.0.0.0", "--port", "8080"]

In this example:

  • RUN installs dependencies and sets up the environment
  • ENTRYPOINT specifies that Python is our main executable
  • CMD provides default arguments that can be overridden

Conclusion

Understanding the differences between RUN, CMD, and ENTRYPOINT is crucial for Docker mastery:

  • Use RUN for building your image and setting up the environment
  • Use CMD for default commands and arguments that might change
  • Use ENTRYPOINT for the main executable that defines your container's purpose

Remember: RUN executes during build, while CMD and ENTRYPOINT determine what happens when your container starts. Happy Dockerizing!