Docker Dockerfile
What is a Dockerfile?
A Dockerfile is a text file used to build images, containing a series of instructions and directives required to create the image.
Customizing Images Using Dockerfile
This section only explains how to run a Dockerfile to customize an image. Detailed explanations of instructions within the Dockerfile will be covered in the next section. For now, understanding the build process is sufficient.
1. Customizing an Nginx Image (The built image will include a /usr/share/nginx/html/index.html file)
Create a new directory, initialize a Dockerfile within it, and add the following content:
FROM nginx
RUN echo 'This is a locally built Nginx image' > /usr/share/nginx/html/index.html
2. Functions of FROM and RUN Instructions
FROM: Custom images are based on an existing image. Here, Nginx is the base image required for customization. Subsequent operations are based on Nginx.
RUN: Executes the command that follows. There are two formats:
shell format:
RUN <command>
# <command> is equivalent to a shell command executed in the terminal.
exec format:
RUN ["executable", "param1", "param2"]
# For example:
# RUN ["./test.php", "dev", "offline"] is equivalent to RUN ./test.php dev offline
Note: Each Dockerfile instruction executed creates a new layer in Docker. Therefore, unnecessary layers can lead to image bloat. For example:
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
The above creates 3 layers. It can be simplified to:
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
By connecting commands with &&
, only 1 layer is created.
Starting the Image Build
Execute the build action in the directory containing the Dockerfile.
The following example builds an image named nginx:v3 using the Dockerfile in the directory.
Note: The final .
denotes the context path, which will be explained in the next section.
$ docker build -t nginx:v3 .
The above indicates a successful build.
Context Path
In the previous section, the last .
mentioned is the context path. What is the context path?
$ docker build -t nginx:v3 .
The context path refers to the directory Docker uses to build the image, especially when it needs to access local files (like copying). The docker build
command will package all contents of this path.
Explanation: Docker operates in a C/S mode. The local machine is C, and the Docker engine is S. The actual build process occurs within the Docker engine, so local files cannot be used directly. This requires packaging the specified local directory to be provided to the Docker engine.
If the last parameter is not specified, the default context path is the location of the Dockerfile.
Note: Do not include unnecessary files in the context path as they will be packaged and sent to the Docker engine, potentially slowing down the process.
Detailed Instructions
COPY
Copy instructions, copying files or directories from the context directory to the specified path in the container.
Format:
COPY [--chown=<user>:<group>] <source path>... <destination path>
COPY [--chown=<user>:<group>] ["<source path>",... "<destination path>"]
[--chown=<user>:<group>]: Optional parameter, changes the owner and group of the copied files in the container.
<source path>: Source file or directory, can include wildcard expressions, matching rules follow Go's filepath.Match. For example:
COPY hom* /mydir/
COPY hom?.txt /mydir/
<destination path>: Specified path in the container. The path does not need to exist beforehand; it will be created if it does not exist.
ADD
The ADD instruction is similar to COPY but with additional features (COPY is recommended for simple copying). Differences include:
ADD's advantage: Automatically copies and decompresses tar files (gzip, bzip2, xz) to the destination path.
ADD's disadvantage: Cannot copy tar files without decompression, which can invalidate image build caching, potentially making image builds slower. Use based on whether automatic decompression is needed.
CMD
Similar to the RUN instruction, used for program execution, but at different times:
CMD runs when docker run is executed.
RUN runs during docker build.
Function: Specifies the default program to run in the container, which ends the container when the program finishes. CMD can be overridden by specifying a program in the docker run command.
Note: If multiple CMD instructions exist in the Dockerfile, only the last one takes effect.
Format:
CMD <shell command>
CMD ["<executable or command>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # This format provides default parameters for the ENTRYPOINT instruction
The second format is recommended for clearer execution. The first format is automatically converted to the second format during execution, with the default executable being sh.
ENTRYPOINT
Similar to CMD, but is not overridden by the docker run command-line parameters. These parameters are passed as arguments to the program specified by ENTRYPOINT.
However, if the --entrypoint option is used in docker run, it overrides the ENTRYPOINT-specified program.
Advantage: Allows specifying parameters for ENTRYPOINT during docker run.
Note: If multiple ENTRYPOINT instructions exist in the Dockerfile, only the last one takes effect.
Format:
ENTRYPOINT ["<executable>","<param1>","<param2>",...]
CMD can be used with ENTRYPOINT: CMD is typically used for variable parameters, passing them to ENTRYPOINT. An example is provided below.
Example:
Assuming an nginx:test image has been built from a Dockerfile:
FROM nginx
ENTRYPOINT ["nginx", "-c"] # Fixed parameters
CMD ["/etc/nginx/nginx.conf"] # Variable parameters
- Running without parameters
$ docker run nginx:test
The default command executed in the container is:
nginx -c /etc/nginx/nginx.conf
- Running with parameters
$ docker run nginx:test -c /etc/nginx/new.conf
The default command executed in the container is (assuming /etc/nginx/new.conf exists in the container):
nginx -c /etc/nginx/new.conf
ENV
Sets environment variables, which can be used in subsequent instructions.
Format:
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
Example setting NODE_VERSION = 7.2.0, which can be referenced as $NODE_VERSION in subsequent instructions:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
ARG
Build arguments, similar to ENV but with different scopes. ARG environment variables are only valid within the Dockerfile, not in the built image.
The build command docker build can override these variables with --build-arg <parameter name>=<value>.
Format:
ARG <parameter name>[=<default value>]
VOLUME
Defines anonymous volumes. If the container is started without mounting a volume, it automatically mounts to an anonymous volume.
Purpose:
Prevents data loss due to container restarts.
Prevents container bloat.
Format:
VOLUME ["<path1>", "<path2>"...]
VOLUME <path>
The mount point can be modified during docker run using the -v parameter.
EXPOSE
Only declares ports.
Purpose:
Helps image users understand the service's守护端口, facilitating port mapping configuration.
Automatically maps EXPOSE ports when using random port mapping with docker run -P.
Format:
EXPOSE <port1> [<port2>...]
WORKDIR
Specifies the working directory. The directory specified by WORKDIR will exist in every layer of the built image. The current directory for each subsequent layer is set to the specified directory, which is created if it does not exist.
Format:
WORKDIR <working directory path>
USER
Specifies the user and group for executing subsequent commands. This only switches the user for subsequent command execution (the user and group must already exist).
Format:
USER <username>[:<group>]
HEALTHCHECK
Specifies a program or instruction to monitor the running status of the Docker container service.
Format:
HEALTHCHECK [options] CMD <command>: Sets the command to check the health of the container
HEALTHCHECK NONE: Disables the health check instruction if the base image has one
HEALTHCHECK [options] CMD <command>: CMD usage here can refer to the CMD instruction.
ONBUILD
Delays the execution of build commands. Essentially, ONBUILD commands specified in a Dockerfile will not execute during the current image build (assume the image is test-build). When a new Dockerfile uses the previously built image FROM test-build, the ONBUILD commands from the test-build Dockerfile will execute during the new image's build.
Format:
ONBUILD <other instructions>
LABEL
Adds metadata to the image in key-value pairs.
Format:
LABEL <key>=<value> <key>=<value>...
LABEL <key>=<value> <key>=<value> <key>=<value> ...
For example, we can add the image author:
LABEL org.opencontainers.image.authors="tutorialpro"