Docker Dockerfile
# Docker Dockerfile
## What is a Dockerfile?
A Dockerfile is a text file that contains all the instructions needed to build a Docker image.
A Dockerfile is a text file used to build an image. Its content consists of a series of instructions and explanations required for the image construction process.
By defining a series of commands and parameters, a Dockerfile guides Docker in building a custom image.
## Customizing Images with a Dockerfile
This section only explains how to run a Dockerfile to customize an image. Detailed explanations of the instructions within a Dockerfile will be covered in the next section. Here, you only need to understand the build process.
**1. Example: Customizing an nginx image (the built image will contain a `/usr/share/nginx/html/index.html` file)**
In an empty directory, create a new file named `Dockerfile` and add the following content:
```dockerfile
FROM nginx
RUN echo 'This is a locally built nginx image' > /usr/share/nginx/html/index.html
!(#)
**2. The Role of the FROM and RUN Instructions**
**FROM**: All custom images are based on a `FROM` image. Here, `nginx` is the base image required for customization. All subsequent operations are based on `nginx`.
**RUN**: Used to execute the command-line command that follows. There are two formats:
Shell format:
```dockerfile
RUN
# is equivalent to a shell command executed in the terminal.
Exec format:
```dockerfile
RUN ["executable", "param1", "param2"]
# Example:
# RUN ["./test.php", "dev", "offline"] is equivalent to RUN ./test.php dev offline
**Note**: Each instruction in a Dockerfile creates a new layer in Docker. Therefore, too many unnecessary layers will cause the image to become bloated. For example:
```dockerfile
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 execution will create 3 image layers. It can be simplified to the following format:
```dockerfile
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
As shown above, connecting commands with the `&&` symbol ensures that only 1 image layer is created after execution.
## Starting the Image Build
Execute the build command in the directory where the `Dockerfile` is located.
The following example builds an `nginx:v3` image (image name:image tag) using the `Dockerfile` in the current directory.
**Note**: The final `.` represents the context path for this execution, which will be explained in the next section.
```bash
$ docker build -t nginx:v3 .
!(#)
The output above indicates that the build was successful.
## Context Path
In the previous section, it was mentioned that the final `.` in the command is the context path. So, what is a context path?
```bash
$ docker build -t nginx:v3 .
The context path refers to the fact that when Docker builds an image, it sometimes needs to use files from the local machine (e.g., for copying). Once the `docker build` command knows this path, it will package all the contents within that path.
**Explanation**: Since Docker operates in a client-server (C/S) model, our local machine is the client (C), and the Docker engine is the server (S). The actual build process is completed by the Docker engine, so it cannot directly access files on our local machine. This requires packaging the files from the specified local directory and providing them to the Docker engine for use.
If the final parameter is not specified, the default context path is the location of the `Dockerfile`.
**Note**: Do not place unnecessary files in the context path, as they will be packaged and sent to the Docker engine. Too many files can slow down the process.
---
## Detailed Instructions
| Dockerfile Instruction | Description |
| --- | --- |
| FROM | Specifies the base image for subsequent instructions. |
| MAINTAINER | Specifies the author/maintainer of the Dockerfile. (Deprecated, use the LABEL instruction instead) |
| LABEL | Adds metadata to an image in key-value pair format. |
| RUN | Executes commands within the image during the build process. |
| CMD | Specifies the default command to run when a container is created. (Can be overridden) |
| ENTRYPOINT | Sets the main command for when a container is created. (Cannot be overridden) |
| EXPOSE | Declares specific network ports that the container listens on at runtime. |
| ENV | Sets environment variables inside the container. |
| ADD | Copies files, directories, or remote URLs into the image. |
| COPY | Copies files or directories into the image. |
| VOLUME | Creates mount points for a container or declares volumes. |
| WORKDIR | Sets the working directory for subsequent instructions. |
| USER | Specifies the user context for subsequent instructions. |
| ARG | Defines variables passed to the builder during the build process, which can be set using the `docker build` command. |
| ONBUILD | Adds a trigger when the image is used as the base for another build process. |
| STOPSIGNAL | Sets the system call signal sent to the container to exit. |
| HEALTHCHECK | Defines a command to periodically check the health status of the container. |
| SHELL | Overrides the default shell in Docker for the RUN, CMD, and ENTRYPOINT instructions. |
### COPY
The copy instruction copies files or directories from the context directory to a specified path inside the container.
Format:
```dockerfile
COPY [--chown=:] ...
COPY [--chown=:] ["",... ""]
**`[--chown=:]`**: An optional parameter to change the owner and group of the files copied into the container.
**``**: The source file or source directory. This can be a wildcard expression, and the wildcard rules must satisfy Go's `filepath.Match` rules. For example:
```dockerfile
COPY hom* /mydir/
COPY hom?.txt /mydir/
**``**: The specified path inside the container. This path does not need to be created in advance; if it does not exist, it will be created automatically.
### ADD
The `ADD` instruction has a similar usage format to `COPY` (for similar needs, the official recommendation is to use `COPY`). Its functionality is also similar, with the following differences:
* **Advantage of ADD**: When the `` is a tar archive file, if the compression format is gzip, bzip2, or xz, it will automatically copy and decompress it to the ``.
* **Disadvantage of ADD**: Without decompression, it cannot copy tar archive files. It can invalidate the image build cache, potentially making the image build slower. Whether to use it depends on whether automatic decompression is needed.
### CMD
Similar to the `RUN` instruction, it is used to run programs, but they run at different times:
* `CMD` runs when `docker run` is executed.
* `RUN` runs during `docker build`.
**Purpose**: Specifies the default program to run when the container starts. When the program finishes, the container stops. The program specified by the `CMD` instruction can be overridden by the program specified in the `docker run` command-line arguments.
**Note**: If there are multiple `CMD` instructions in a Dockerfile, only the last one takes effect.
Format:
```dockerfile
CMD
CMD ["","","",...]
CMD ["","",...] # This format is used to provide default parameters for the program specified by the ENTRYPOINT instruction.
The second format is recommended as the execution process is clearer. The first format is actually automatically converted to the second format during execution, and the default executable is `sh`.
### ENTRYPOINT
Similar to the `CMD` instruction, but it is not overridden by the command-line arguments specified in `docker run`. Instead, these command-line arguments are passed as parameters to the program specified by the `ENTRYPOINT` instruction.
However, if the `--entrypoint` option is used when running `docker run`, it will override the program specified by the `ENTRYPOINT` instruction.
**Advantage**: Allows specifying the parameters required for `ENTRYPOINT` to run when executing `docker run`.
**Note**: If there are multiple `ENTRYPOINT` instructions in a Dockerfile, only the last one takes effect.
Format:
```dockerfile
ENTRYPOINT ["","","",...]
It can be used in conjunction with the `CMD` command: Typically, `CMD` is used for variable parameters. Here, `CMD` is essentially passing parameters to `ENTRYPOINT`. The following example will illustrate this.
Example:
Assuming the `nginx:test` image has been built via a Dockerfile:
```dockerfile
FROM nginx
ENTRYPOINT ["nginx", "-c"] # Fixed parameters
CMD ["/etc/nginx/nginx.conf"] # Variable parameters
1. **Running without parameters**:
```bash
$ docker run nginx:test
```
The container will by default run the following command to start the main process:
```bash
nginx -c /etc/nginx/nginx.conf
```
2. **Running with parameters**:
```bash
$ docker run nginx:test -c /etc/nginx/new.conf
```
The container will by default run the following command to start the main process (assuming `/etc/nginx/new.conf` already exists inside the container):
```bash
nginx -c /etc/nginx/new.conf
```
### ENV
Sets environment variables. Once an environment variable is defined, it can be used in subsequent instructions.
Format:
```dockerfile
ENV
ENV = =...
The following example sets `NODE_VERSION = 7.2.0`, which can be referenced via `$NODE_VERSION` in subsequent instructions:
```dockerfile
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 in function to `ENV`. However, their scope is different. The environment variables set by `ARG` are only valid within the Dockerfile, meaning they are only effective during the `docker build` process and do not exist in the built image.
In the `docker build` command, you can use `--build-arg =` to override them.
Format:
```dockerfile
ARG
### VOLUME
Defines an anonymous data volume. If you forget to mount a data volume when starting a container, it will automatically be mounted to an anonymous volume.
Purpose:
* Prevents important data from being lost due to container restarts, which can be critical.
* Prevents the container from continuously growing in size.
Format:
```dockerfile
VOLUME ["", ""...]
VOLUME
When starting a container with `docker run`, we can modify the mount point using the `-v` parameter.
### EXPOSE
Only declares a port.
Purpose:
* Helps image users understand the daemon port of this image service, facilitating port mapping configuration.
* When using random port mapping at runtime (i.e., `docker run -P`), it will automatically randomly map the `EXPOSE` ports.
Format:
```dockerfile
EXPOSE [...]
### WORKDIR
Specifies the working directory. The working directory specified by `WORKDIR` exists in every layer of the image build. The current directory for all subsequent layers is changed to the specified directory. If the directory does not exist, `WORKDIR` will create it for you.
During the `docker build` process, each `RUN` command creates a new layer. Only directories created via `WORKDIR` will persist.
Format:
```dockerfile
WORKDIR
### USER
Used to specify the user and user group for executing subsequent commands. This only switches the user for subsequent command execution (the user and user group must already exist).
Format:
```dockerfile
USER [:]
### HEALTHCHECK
Used to specify a program or instruction to monitor the running status of a Docker container service.
Format:
```dockerfile
HEALTHCHECK CMD : Sets the command to check the container's health status.
HEALTHCHECK NONE: If the base image has a health check instruction, using this line disables its health check instruction.
HEALTHCHECK CMD : The command following CMD can be referenced in the CMD usage.
### ONBUILD
Used to delay the execution of build commands. Simply put, commands specified with `ONBUILD` in a Dockerfile will not be executed during the current image build (assuming the image is `test-build`). When a new Dockerfile uses the previously built image `FROM test-build`, and the new image's Dockerfile is built, the `ONBUILD` commands from `test-build`'s Dockerfile will be executed.
Format:
```dockerfile
ONBUILD
### LABEL
The `LABEL` instruction is used to add metadata to an image in key-value pair format. The syntax is as follows:
```dockerfile
LABEL = = = ...
For example, we can add the image's author:
```dockerfile
LABEL org.opencontainers.image.authors=""
YouTip