Docker 简明教程

Docker – Building Files

Dockerfile 本质上是一组以简单文本格式编写的指令,Docker 基于此构建 Docker 映像的构建过程。例如,它有必须开始的基本映像、安装软件、库、依赖项、复制文件和在应用程序环境中运行命令的指令。

A Dockerfile is essentially a set of instructions, written in simple text format, upon which Docker bases the building process of Docker images. For example, it has the base image that one must start with, instructions for installation of software, libraries, dependencies, copying files, and running commands necessary in an application environment.

把它看作是容器的食谱,列出要执行的食材和烹饪步骤,最终生成一个即用即食的 Docker 映像,就像美味佳肴一样。

Think of it as a recipe for your container about listing ingredients and cooking steps to execute, and it ends up producing a ready-to-run Docker image, quite like a delicious dish.

阅读本章,了解 Dockerfile 以及如何构建它们以创建和运行 Docker 映像。

Read this chapter to learn Dockerfiles and how to build them to create and run Docker Images.

Dockerfile Instructions

Dockerfile 指令是 Docker 映像构建过程中使用的一组命令。添加给 Dockerfile 的每条指令都概述了一个环境和行为,该环境和行为为一个最终将运行应用程序的容器。

Dockerfile instructions are a set of commands used in the building process of a Docker image. Every instruction added to the Dockerfile outlines an environment and behavior for a container that will run the application eventually.

此处列示了 @{s12} 以及示例,展示如何使用它们 −

Listed here are 10 essential Dockerfile instructions along with examples, showing how to use them −

Instruction

Description

FROM

Specifying the base image you’re building from

RUN

Run a command on a new layer of the current image and commit

COPY

Copy files or directories from the host filesystem into the image filesystem

WORKDIR

Set the working directory for any subsequent instructions.

ENV

It sets the environment variables

EXPOSE

Inform Docker that the container has interests in specific network ports at runtime

CMD

Provides the default command and/or parameters for the Container

ENTRYPOINT

This configures a container to run as an executable

VOLUME

Creates a mount point with the specified path and marks it as holding externally mounted volumes

USER

Sets the username or UID to use when running the image

Example

我们来为一个简单的 Node.js 应用程序创建一个 Dockerfile −

Let’s create a Dockerfile for a simple Node.js application −

# Use the official Node.js image as a base
FROM node:14

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose port 3000 to the outside world
EXPOSE 3000

# Set environment variables
ENV NODE_ENV=production

# Default command to run when the container starts
CMD ["node", "index.js"]
dockerfile instructions

这个 Dockerfile 会为 Node.js 应用程序生成一个映像,设置环境,安装依赖项,公开端口并定义如何启动应用程序。

This very Dockerfile builds an image for a Node.js application, sets up the environment, installs dependencies, exposes a port, and defines how it should start an application.

How to Build an Image from Dockerfile?

你可以通过 Docker 的命令行界面或 CLI 使用一些重要的 Docker 命令从 Dockerfile 生成 Docker 映像。

You can build Docker images from a Dockerfile using some of the important Docker commands through Docker’s Command-Line Interface or CLI.

我们来查看一个逐步指南,了解如何基于上面示例的 Dockerfile 使用基本的 Docker 命令生成、添加标签并运行映像。

Let’s check a step-by-step guide to building, tagging, and running an image using essential Docker commands based on the above example Dockerfile.

Build Docker Image

要从 Dockerfile 生成 Docker 映像,请使用 docker build 命令 −

To build a Docker image from a Dockerfile, use the docker build command −

$ docker build -t my-node-app:v1 .
build docker image
  1. -t my-node-app:v1 − The image to be built will have the name "my-node-app" with the tag "v1".

  2. . (dot) − Specifies the build context, which is the current directory containing the Dockerfile.

List Docker Images

此命令将列出系统上当前的所有 Docker 映像。

This command will list all of the Docker images currently on your system.

$ docker images
list docker images

这会显示所有映像以及它们的标签、大小和创建日期列表。

This will display a list of all images along with their tags, sizes, and creation dates.

Tagging an Image

你可以使用 docker tag 命令将现有映像标记到另一个标签或存储库名称。

You can use the docker tag command to tag an existing image to another tag or repository name.

$ docker tag my-node-app:v1 my-registry/my-node-app:v1
tagging an imag
  1. my-node-app:v1 − The image name and the current tag.

  2. my-registry/my-node-app:v1 − Name for the new repository and tag.

Run a Docker Container

要基于特定映像运行容器,请使用 docker run 命令 −

To run a container based on a specific image, use the docker run command −

$ docker run -p 3000:3000 my-node-app:v1
  1. -p 3000:3000 − This would map the port 3000 of the host to the port 3000 inside the container (Port binding).

  2. my-node-app:v1 − This would be the name of the image you will run and the tag for that particular image.

List the Running Containers

要查看当前正在运行哪些容器,你可以使用 docker ps 命令 -

To see which containers are currently running, you can use the docker ps command −

$ docker ps
list the running containers

这将返回正在运行的容器的列表及其 ID、状态、端口和名称。

This will return the list of running containers along with their IDs, status, ports, and names.

Stop a Running Container

要停止正在运行的容器,请使用 docker stop 命令,后跟容器 ID 或名称 -

To stop a running container, use the docker stop command followed by the container ID or name −

$ docker stop <container-id or container-name>
stop a running container

你可以将“<容器 ID 或容器名称>”替换为要停止的容器的实际 ID 或名称。

You can replace "<container-id or container-name>" with the actual ID or name of the container you want to stop.

Removing an Image

要从你的系统中移除映像,你可以使用 docker rmi 命令。这需要映像 ID 或标签作为参数。

To remove an image from your system, you can use the docker rmi command. This takes either an image ID or tag as an argument.

$ docker rmi my-node-app:v1
removing an image

What is a .dockerignore File?

dockerignore 文件与 .gitignore 做同样的事情,定义应该在 Docker 构建上下文中忽略的文件和目录的模式。

The .dockerignore file does the same thing as .gitignore, defining patterns of files and directories that should be ignored for the Docker build context.

当 Docker 构建映像时,它会将整个上下文目录 - 使用 Docker 构建命令指定 - 发送到 Docker 守护程序。这意味着,使用 “.dockerignore” 排除不需要的文件和目录可以加快构建速度并减小最终映像的大小。

As Docker builds an image, it sends the whole context directory - specified with the Docker build command to the Docker daemon. That means, excluding unneeded files and directories using ".dockerignore" can speed up the build and reduce the size of the final image.

Syntax and Usage

  1. Create a ".dockerignore" file located in the root directory of your Docker build context.

  2. List files and directories (one per line) that you want Docker to ignore in the build process.

Example .dockerignore File

以下是 Node.js 应用程序的示例 “.dockerignore” 文件 -

The following is an example ".dockerignore" file for a Node.js application −

node_modules
npm-debug.log
Dockerfile
.dockerignore
.git

Explanation

  1. node_modules − Since you want to use npm install as part of your build, this excludes the node_module directory from copying all unwanted dependencies into the Docker image.

  2. npm-debug.log − Ignores npm debug logs, which are unnecessary in the Docker image.

  3. Dockerfile − This prevents the actual Dockerfile itself from being copied into the Docker image.

  4. .dockerignore − It helps to prevent the .dockerignore file itself from being included in the build context.

  5. .git − Excludes the .git directory to avoid copying unnecessary Git repository information.

Best Practices

  1. Include Specific Files − Include only those files and directories in your container that are needed to build and run your application within Docker.

  2. Using Wildcards − Asterisk () and double asterisk (*) can be used in wildcard patterns that match files and directories.

  3. Keep it Minimal − The ".dockerignore" itself should be as minimal as possible to prevent the removal of files unintentionally.

Difference between COPY and ADD instructions in a Dockerfile

COPY 和 ADD 都用于将文件从主机复制到 Docker 镜像。不过,在大多数情况下,COPY 是更好的选择,它透明得多。如果您只需要在镜像中从源复制文件到目标,您应该使用 COPY 指令。

Both COPY and ADD are used for copying files from your host machine into the Docker image. However, in most cases, COPY is a preferable choice; it’s much more transparent. If you need to copy only files from source to destination in the image, you should use COPY instruction.

ADD 具有附加功能,例如自动解压缩文件以及从远程 URL 获取文件的能力,但它增加了潜在的意外行为和可能的安全风险。如果您不需要这些功能,COPY 是首选指令,因为它能使 Docker 文件更清晰、可维护性更强。

ADD has additional features, such as the automatic extraction of compressed files and the ability to fetch files from remote URLs but it adds potential unexpected behavior and possible security risks. If you need none of those features, COPY is the preferred instruction for better clarity and maintainability of your Docker files.

Conclusion

在本章中,我们讨论了 Dockerfile 的复杂性、它们的使用原因以及构建 Docker 镜像所需的多个重要 Dockerfile 指令。

In this chapter, we have discussed the intricacies of Dockerfiles, why they are used, and the several important Dockerfile instructions needed to build a Docker image.

然后,我们了解了一个 Dockerfile 的示例,用以创建 NodeJs Docker 镜像以及可用于构建和标记镜像、运行容器、列出镜像和容器等的各种命令。

Then we understood an example of a Dockerfile to create a NodeJs Docker Image and the different commands that can be used to build and tag images, run containers, list images and containers, etc.

最后,我们讨论了在构建上下文中使用 Dockerignore 文件的必要性。您现在已经具备了从 Dockerfile 创建和构建镜像的能力。

Finally, we discussed why it is necessary to use a Dockerignore file in the build context. You are now well-equipped to create and build an image from a Dockerfile.