Module 01 · Containers and Containerization
Review of Docker Concepts and Understanding a DockerfileDocker 概念回顾与 Dockerfile 理解
Estimated time needed: 30 minutes
预计所需时间:30 分钟
This reading is designed to enhance your understanding of Docker concepts and guide you through the process of comprehending a Dockerfile.
本阅读旨在提升您对 Docker 概念的理解,并指导您理解 Dockerfile 的过程。
Reading Overview: 阅读概述
- Docker Concepts Docker 概念
- Understanding a Dockerfile
理解 Dockerfile
Docker Concepts Docker 概念
Overview 概述
Docker simplifies the process of creating, deploying, and managing applications by using containers. Containers allow you to package an application with its dependencies into a standardized unit for software development. Docker provides tools and a platform to build, ship, and run containers across various environments.
Docker 通过使用容器简化了创建、部署和管理应用程序的过程。容器允许您将应用程序及其依赖项打包成一个标准化的软件开发展示单元。Docker 提供了工具和平台,用于在各个环境中构建、分发和运行容器。
Dockerfile
A text file that contains instructions for building a Docker image. It specifies the base image, sets the working directory, installs dependencies, copies application code, exposes ports, and defines commands to run the application.
一个包含构建 Docker 镜像指令的文本文件。它指定基础镜像、设置工作目录、安装依赖项、复制应用程序代码、暴露端口,并定义运行应用程序的命令。
Container 容器
An instance of a Docker image that runs as a process on the host machine. Containers are lightweight, portable, and isolated, making them ideal for deploying and scaling applications.
一个在主机上作为进程运行的 Docker 镜像实例。容器轻量级、可移植且隔离,非常适合部署和扩展应用程序。
Docker Image Storage Docker 镜像存储
Docker images are stored in registries, which can be public or private. Public registries like Docker Hub host millions of images, while organizations often use private registries for security and control.
Docker 镜像存储在镜像仓库中,镜像仓库可以是公有的或私有的。公有镜像仓库如 Docker Hub 托管着数百万个镜像,而组织通常使用私有镜像仓库以实现安全性和控制。
Where Docker Images Exist Docker 镜像存在位置
Local Machine: When you build a Docker image, it's initially stored locally on your machine. You can list local Docker images using the docker images command.
本地机器:当你构建一个 Docker 镜像时,它最初会存储在你的本地机器上。你可以使用 docker images 命令列出本地 Docker 镜像。
Registry: After building, you can push Docker images to a registry, making them accessible from anywhere with access to that registry.
注册表:构建完成后,您可以将 Docker 镜像推送到注册表,使其可以从任何可以访问该注册表的地点获取。
Dockerfile
Below is a sample Dockerfile for reference. The subsequent explanation details the commands used, providing a comprehensive understanding of how to write a Dockerfile.
以下是一个参考用的 Dockerfile。随后的解释详细说明了所使用的命令,为您提供全面理解如何编写 Dockerfile 的指导。
Dockerfile
# Use the official Node.js image as the base image
FROM node:14
# Set environment variables
ENV NODE_ENV=production
ENV PORT=3000
# Set the working directory
WORKDIR /app
# Copy package.json and package-lock.json files
COPY package*.json ./
# Install dependencies
RUN npm install --production
# Copy the rest of the application code
COPY . .
# Add additional file
ADD public/index.html /app/public/index.html
# Expose the port on which the application will run
EXPOSE $PORT
# Specify the default command to run when the container starts
CMD ["node", "app.js"]
# Labeling the image
LABEL version="1.0"
LABEL description="Node.js application Docker image"
LABEL maintainer="Your Name"
# Healthcheck to ensure the container is running correctly
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD curl -fs http://localhost:$PORT || exit 1
# Set a non-root user for security purposes
USER node
Understanding the Dockerfile 理解 Dockerfile
1: Specify the Base Image 1: 指定基础镜像
To begin, specify the base image using the FROM instruction. In this case, the official Node.js image version 14 is used.
首先,使用 FROM 指令指定基础镜像。在此情况下,使用官方 Node.js 镜像版本 14。
FROM node:14
FROM: Specifies the base image for the Docker container.
FROM : 指定 Docker 容器的基础镜像。
node:14: Pulls the official Node.js image with version 14 from the Docker registry.
node:14 : 从 Docker 镜像仓库拉取官方 Node.js 14 版本镜像。
2: Set Environment Variables 2:设置环境变量
Next, define the necessary environment variables with the ENV instruction. Here, NODE_ENV is set to production and PORT is set to 3000.
接下来,使用 ENV 指令定义必要的环境变量。这里, NODE_ENV 被设置为 production, PORT 被设置为 3000。
ENV NODE_ENV=production
ENV PORT=3000
ENV: Sets environment variables inside the Docker container.
ENV : 在 Docker 容器内设置环境变量。
NODE_ENV=production: Sets the Node.js environment to production.
NODE_ENV=production : 将 Node.js 环境设置为生产环境。
PORT=3000: Sets the port on which the Node.js application will listen.
PORT=3000 : 设置 Node.js 应用程序监听的端口。
3: Set the Working Directory 3: 设置工作目录
Then, specify the working directory inside the container using the WORKDIR instruction. This sets /app as the working directory.
然后,使用 WORKDIR 指令在容器内部指定工作目录。这将 /app 设置为工作目录。
WORKDIR /usr/src/app
WORKDIR: Defines the working directory for subsequent instructions, simplifying file path references.
WORKDIR : 定义后续指令的工作目录,简化文件路径引用。
/usr/src/app: The directory inside the container to store your application code, keeping it organized and easily accessible.
/usr/src/app : 容器内部用于存储您的应用程序代码的目录,保持其组织并易于访问。
4: Copy Package Files 4: 复制软件包文件
After defining the working directory, use the COPY instruction to copy the package.json and package-lock.json files into the container. These files are essential for installing the application dependencies.
在定义工作目录后,使用 COPY 指令将 package.json 和 package-lock.json 文件复制到容器中。这些文件对于安装应用程序依赖项至关重要。
COPY package*.json ./
COPY: Copies files from your local machine to the container.
COPY : 将文件从您的本地计算机复制到容器中。
package*.json ./: Copies both package.json and package-lock.json files
package*.json ./ : 复制 package.json 和 package-lock.json 文件
5: Install Dependencies 5: 安装依赖项
With the package files copied, execute the RUN instruction to install the production dependencies listed in package.json.
在复制了包文件后,执行 RUN 指令以安装 package.json 中列出的生产依赖项。
RUN npm install --production
- RUN: Executes commands in the container during the build process.
RUN:在构建过程中执行容器中的命令。 npm install --production: Installs dependencies listed inpackage.jsonwithout devDependencies.npm install --production:安装package.json中列出的依赖项,但不包括 devDependencies。
6: Copy Application Code 6:复制应用程序代码
Once the dependencies are installed, copy the rest of the application code into the container using the COPY instruction.
一旦安装了依赖项,请使用 COPY 指令将剩余的应用程序代码复制到容器中。
COPY . .
COPY . .: Copies all files and directories from the current directory on the local host to the current directory in the Docker container.
COPY . . : 将本地主机当前目录下的所有文件和目录复制到 Docker 容器的当前目录。
7: Add Additional File(s) 7: 添加附加文件
Additionally, use the ADD instruction to include any extra files. Here, the index.html file is added to the public directory.
此外,使用 ADD 指令包含任何额外文件。此处,将 index.html 文件添加到 public 目录。
# ADD <source_path> <destination_path>
ADD public/index.html /app/public/index.html
public/index.html: Path to the file or directory on the host machine.public/index.html: 主机上的文件或目录的路径。/app/public/index.html: Path where you want to add the file or directory inside the Docker image./app/public/index.html: 您希望在 Docker 镜像中添加文件或目录的路径。
8: Expose the Application Port 8: 暴露应用端口
Next, inform Docker that the container listens on the specified port with the EXPOSE instruction. Here, it exposes the port defined by the PORT environment variable.
接下来,使用 EXPOSE 指令通知 Docker 容器监听指定端口。这里,它暴露了由 PORT 环境变量定义的端口。
EXPOSE $PORT
EXPOSE: Informs Docker that the container will listen on the specified port at runtime.EXPOSE: 告知 Docker 容器在运行时将监听指定端口。$PORT: The environment variable representing the port number defined earlier.$PORT: 代表先前定义的端口号的环境变量。
9: Specify the Default Command 9: 指定默认命令
Define the default command to run when the container starts using the CMD instruction. Here, it runs node app.js.
使用 CMD 指令定义容器启动时运行的默认命令。这里,它运行 node app.js。
CMD ["node", "app.js"]
CMD: This instruction specifies the default command and/or parameters to execute at the entry point of the container.
CMD : 该指令指定在容器的入口点执行的默认命令和/或参数。
["node", "app.js"]: This array specifies the command to run any arguments for that command. In this case, it tells Docker to execute the node command with app.js as the argument.
["node", "app.js"] : 该数组指定运行该命令的任何参数。在这种情况下,它告诉 Docker 使用 app.js 作为参数来执行 node 命令。
Note: The filename app.js is commonly used as the main file for Node.js applications. However, depending on your project structure or naming conventions, the main file could have a different name.
注意:文件名 app.js 通常用作 Node.js 应用程序的主文件。然而,根据您的项目结构或命名约定,主文件可能有不同的名称。
10: Label the Image 10: 标记镜像
Then, add metadata to the image with the LABEL instruction, including the version, description, and maintainer information.
然后,使用 LABEL 指令向镜像添加元数据,包括版本、描述和维护者信息。
LABEL version="1.0"
LABEL description="Node.js application Docker image"
LABEL maintainer="Your Name"
LABEL: Adds metadata to the Docker image.
LABEL : 为 Docker 镜像添加元数据。
version="1.0": Specifies the version of the Docker image.
version="1.0" : 指定 Docker 镜像的版本。
description="Node.js application Docker image" : Provides a description of the Docker image.
description="Node.js application Docker image" : 提供 Docker 图像的描述。
maintainer="Your Name": Specifies the maintainer of the Docker image.
maintainer="Your Name" : 指定 Docker 镜像的维护者。
11: Add a Healthcheck 11: 添加健康检查
For ensuring the container is running correctly, define a health check using the HEALTHCHECK instruction. This command checks the application’s health by sending a request to the specified port.
为确保容器正常运行,使用 HEALTHCHECK 指令定义一个健康检查。该命令通过向指定端口发送请求来检查应用程序的健康状况。
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD curl -fs http://localhost:$PORT || exit 1
HEALTHCHECK: Configures a health check to ensure the container is running correctly.
HEALTHCHECK : 配置健康检查以确保容器正常运行。
--interval=30s: Specifies the interval between health checks.
--interval=30s : 指定健康检查的间隔时间。
--timeout=10s: Sets the timeout for each health check.
--timeout=10s : 设置每个健康检查的超时时间。
--start-period=5s: Defines the start period during which the container must initialize before health checks begin.
--start-period=5s : 定义容器必须初始化的起始时间段,在此时间段内健康检查才会开始。
--retries=3: Sets the number of retries before considering the container unhealthy.
--retries=3 : 设置在认为容器不健康之前重试的次数。
CMD curl -fs http://localhost:$PORT || exit 1: Specifies the command to run for health checks. It checks if a request to http://localhost:$PORT succeeds; otherwise, it exits with code 1, indicating failure.
CMD curl -fs http://localhost:$PORT || exit 1 : 指定用于健康检查的命令。它检查对 http://localhost:$PORT 的请求是否成功;否则,以代码 1 退出,表示失败。
12: Set a Non-Root User 12: 设置非根用户
Finally, for security purposes, set a non-root user with the USER instruction. Here, the user is set to node
最后,出于安全目的,使用 USER 指令设置一个非根用户。这里,用户被设置为 node
USER node
USER: Sets the user that will run the subsequent instructions in the Dockerfile.
USER : 设置将在 Dockerfile 中运行后续指令的用户。
node: Specifies the user named node to run the commands for security purposes.
node : 指定以 node 命名的用户出于安全目的运行命令。
This step-by-step explanation shows the flow of creating a Dockerfile, highlighting how each instruction builds upon the previous one to create a fully functional Docker image. 这一逐步解释展示了创建 Dockerfile 的流程,突出了每条指令如何基于前一条指令构建,最终创建一个功能完整的 Docker 镜像。
Summary 摘要
In this reading, you learned about Docker concepts and the process of creating a Dockerfile. The provided Dockerfile and the outlined steps demonstrate how to build a Docker image for a Node.js application. It starts with the official Node.js base image, sets up environment variables, defines a working directory, and installs the necessary dependencies. The application code is then copied into the container, and a health check is included to ensure the container runs correctly. Finally, a non-root user is set for enhanced security.
通过本次阅读,你学习了 Docker 概念以及创建 Dockerfile 的过程。提供的 Dockerfile 和概述的步骤展示了如何为 Node.js 应用程序构建 Docker 镜像。它从官方 Node.js 基础镜像开始,设置环境变量,定义工作目录,并安装必要的依赖项。然后,将应用程序代码复制到容器中,并包含了一个健康检查以确保容器正常运行。最后,设置了非 root 用户以增强安全性。