Keywords: Dockerfile | RUN instruction | CMD instruction
Abstract: This article explores the core differences between RUN and CMD instructions in Dockerfile. RUN executes commands during image build phase and persists results, while CMD defines the default command when a container starts. Through detailed code examples and scenario analysis, it explains their applicable scenarios, execution timing, and best practices, helping developers correctly use these key instructions to optimize Docker image building and container operation.
Introduction
In Docker containerization technology, Dockerfile is the core file defining the image build process, and the correct use of its instructions is crucial for image efficiency and functionality. Among them, RUN and CMD are two commonly used but easily confused instructions. Based on official documentation and community practices, this article systematically analyzes their differences, application scenarios, and best practices.
RUN Instruction: Command Execution During Image Build
The RUN instruction executes during the Docker image build process. Each RUN command creates a new layer on top of the current image layer and commits the execution result to that layer. This means RUN is used at build time to install software, configure environments, or perform other preparation tasks, with results permanently saved in the image.
For example, installing Python and dependencies in an Ubuntu-based image:
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y python3 python3-pip
RUN pip3 install flask requestsIn this example, the first RUN updates the package list and installs Python3, and the second RUN installs Python libraries. These commands execute during image build, and the resulting image includes these changes.
CMD Instruction: Default Command at Container Startup
The CMD instruction specifies the default command to execute when a container starts. It only takes effect at container runtime, and each Dockerfile can have only one CMD (if multiple, only the last one is effective). The primary use of CMD is to define the application or service to run after container startup, and it can be overridden via the docker run command.
For example, defining a default command to start a Python Flask application:
CMD ["python3", "app.py"]When running docker run my-image, the container executes python3 app.py. If the user specifies another command, such as docker run my-image /bin/bash, the CMD is overridden, and the container starts a bash shell.
Core Differences Between RUN and CMD
From an execution timing perspective, RUN runs at build time (docker build), affecting image layers; CMD executes at runtime (docker run), defining container behavior. Functionally, RUN is for preparing the image environment, such as installing software; CMD is for starting applications, such as running services.
Illustrative example: Suppose building a web server image. Use RUN to install Nginx:
RUN apt-get install -y nginxThen use CMD to start the Nginx service:
CMD ["nginx", "-g", "daemon off;"]Here, RUN ensures Nginx is installed in the image, while CMD sets the container to automatically run Nginx at startup. If the user wants to run other commands, such as checking configuration, they can override CMD.
Association with ENTRYPOINT
ENTRYPOINT is another related instruction, often used in combination with CMD. ENTRYPOINT defines the command that always executes when the container starts, while CMD provides default parameters. For example:
ENTRYPOINT ["python3"]
CMD ["app.py"]In this case, running docker run my-image executes python3 app.py, but the user can override parameters, e.g., docker run my-image test.py executes python3 test.py. This enhances container flexibility.
Best Practices and Common Pitfalls
In practice, avoid confusing RUN and CMD. Use RUN for build-time tasks like installing packages and creating files; use CMD to define runtime behavior. A common mistake is performing build tasks in CMD, leading to repeated execution each time the container starts, increasing overhead.
For example, incorrect usage:
CMD apt-get install -y nginx # Incorrect: should be in RUNCorrect approach:
RUN apt-get install -y nginx
CMD ["nginx", "-g", "daemon off;"]Additionally, optimize RUN commands by combining multiple operations into one layer to reduce image size. For instance, use && to chain commands.
Conclusion
RUN and CMD are key instructions in Dockerfile, serving the image build and container runtime phases, respectively. Understanding their differences helps in writing efficient and maintainable Dockerfiles, improving the quality of containerized applications. Developers should choose the appropriate instruction based on task nature, follow best practices, and achieve fast image builds and flexible container deployments.