Docker 简明教程
Docker - Dockerfile
Dockerfile 是一种文本文档,你可以在其中写下要创建镜像的所有指令。该文件中的第一个条目指定基本镜像,基本镜像是一个预制的镜像,其中包含你的应用程序所需的所有依赖项。然后,你可以向 Dockerfile 发送命令,以安装附加软件、复制文件或运行脚本。其结果是一个 Docker 镜像:一个自给自足的可执行文件,其中包含运行应用程序所需的所有信息。
Dockerfile 是一种颇具吸引力的用于创建和部署应用程序的方式。它们有助于以一种更加轻松的方式和可重复的方式创建环境。Dockerfile 还能自动执行部署流程。
Dockerfile 用于创建根据具体需求单独准备的新自定义镜像。例如,Docker 镜像可以具有特定版本的 Web 服务器,或者例如数据库服务器。
Important Instructions used in Dockerfile
Dockerfile 是一种文本文档,其中包含所有用于构建 Docker 镜像的不同步骤和说明。Dockerfile 中描述的主要元素包括基本镜像、所需依赖项以及在容器中执行应用程序部署的命令。
Dockerfile 的基本指令如下所示 −
Best Practices for Dockerfile
一份编写得当的 Dockerfile 对于所有高效且安全的容器化应用程序都至关重要。Dockerfile 是构建 Docker 镜像的蓝图,其中详细说明了顺畅运行应用程序所需的环境、依赖关系和配置。
通过最佳实践,你可以创建更精简、更快速且更可靠的 Docker 镜像,从而最终实现工作流的自动化,提高应用程序的效率。以下给出了一组 10 个基本的 Dockerfile 最佳实践−
-
Use Official Base Images − 构建于官方的 Docker Hub 镜像之上。它们通常是最小的,并且维护良好。通常情况下,它们针对安全性和大小进行了优化,为自定义镜像奠定了坚实的基础。
-
Use multi-stage builds 以便通过放弃不需要的构建工具和依赖关系来缩减最终的镜像大小。通过这种方式,你可以对构建和运行时环境进行分区,以达到最佳效率。
-
Minimize the Number of Layers − 如前所述,Dockerfile 中的每条指令都会创建一个层。尽可能在一条 RUN 指令中组合任何相互关联的命令。这将有助于减少为任何构建创建的层数,从而使构建更具可缓存性。
-
Leverage Build Cache − 确保 Dockerfile 中可能更频繁更改的指令(比如 COPY)放置在末尾。这将使在后期进行更改后能够更快速地再次构建。
-
Install Only Necessary Packages − 在应用程序中仅安装必要的包和依赖关系,以减小镜像大小和潜在的漏洞。
-
Use '.dockerignore' − 要从构建上下文中排除不必要的文件和目录,请添加一个“.dockerignore”文件。这将加快构建速度,并防止敏感信息泄露到镜像中。
-
Use Non-Root User − 使用非 root 用户运行容器,以增强安全性。在 Dockerfile 中给特定用户和组提供另一个隔离层始终是个好主意。
-
Image Scanning − 经常扫描你的 Docker 镜像中的漏洞。有许多工具可以使用,比如 Trivy 和 Clair。随时更新你的基础镜像和依赖关系,以最大程度地减少潜在的风险。
-
Document your Dockerfile − 为 Dockerfile 添加注释和说明,你以后会感谢自己。这有助于其他人,甚至是以后的你,理解构建过程。
-
Pin Versions − 固定基础镜像和依赖关系的版本,因为这确保了再现性,并通过更新避免任何意外问题。
现在,你可以通过在 Dockerfile 工作流中创建健壮且高效的容器化应用程序来针对速度、安全性和可维护性优化容器构建。
Dockerfile - Example
我们将编写一个 Dockerfile,用于一个简单的 Flask Web 应用程序,该应用程序提供消息“Hello, World!”。具体来说,我们将展示如何使用上面介绍的几条指令来创建和通过容器运行此应用程序。
Dockerfile Code
# Use the official Python image as a base
FROM python:3.9-slim-buster
# Set environment variables
ENV PYTHONUNBUFFERED 1
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
# Set the working directory in the container
WORKDIR /app
# Copy the requirements file and install dependencies
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
# Copy the application code into the container
COPY . /app
# Expose port 5000 to the outside world
EXPOSE 5000
# Run the Flask app when the container launches
CMD ["flask", "run"]
Code Explanation
-
FROM python:3.9-slim-buster - 这行将基础镜像设置为来自 Docker Hub 的官方 Python 3.9 slim-buster 镜像 - 一个包含必要的 Python 运行时环境的轻量级镜像。
-
ENV PYTHONUNBUFFERED 1 - 设置环境变量并确保不缓冲输出,这有助于调试。
-
ENV FLASK_APP=app.py - 这指定了主应用程序文件。
-
ENV FLASK_RUN_HOST=0.0.0.0 - Flask 应用程序将对 IP 地址 0.0.0.0 可用。
-
WORKDIR /app - 这行将容器中的工作目录设置为 /app。从此处开始的每个其他命令都将在该目录中工作。
-
COPY requirements.txt requirements.txt - 这将 requirements.txt 文件从本地机器复制到容器内的 /app 目录。
-
RUN pip install -r requirements.txt - 这将安装 requirements.txt 文件中列出的 Python 包依赖项。
-
COPY . /app - 这将将整个当前目录(Dockerfile 和应用程序代码所在的位置)复制到容器内的 /app 目录。
-
EXPOSE 5000 - 这告诉 Docker 容器在运行时侦听端口 5000。
-
CMD ['flask', 'run'] - 这是容器启动过程中执行的默认命令。它启动 Flask 开发服务器。
How Does It Work?
您需要生成一个 requirements.txt 文件,其中列出 Flask 应用程序的所有依赖项,例如 Flask。您在与 Flask 应用程序代码(app.py)的同一目录中将此 Dockerfile 保存为 Dockerfile,并且不带文件扩展名。然后,您可以通过执行命令 docker build -t my-flask-app 来创建 Docker 镜像。(将 my-flask-app 替换为您要为镜像指定的名称)。
最后,您可以使用 docker run -p 5000:5000 my-flask-app 来运行容器。这将启动 Flask 应用程序,您可以在 http://localhost:5000/ 中通过浏览器访问它。这样,您的应用程序将运行在可移植和可重现的环境中,可以在不同的环境中轻松部署和管理。
Conclusion
总之,Docker 改变了我们进行应用程序开发、部署和整体管理的方式。通过 Docker 实现容器化,帮助开发者在各种不同的环境中实现更高的可移植性、可扩展性和一致性。简单来说,Dockerfile 是容器化的单元;如果没有 Dockerfile,组件和配置将无从谈起。
我们在本文中学习了如何使用探索的最佳实践和示例使 Dockerfile 有效且安全。优化镜像大小、利用构建缓存并遵循安全准则,以便我们的应用程序在任何 Docker 环境中都能顺畅可靠地运行。之后,请记住,掌握 Dockerfile 是释放 Docker 的全部能力并在单击之间减少数小时例行工作的方法。
FAQ
Q 1. What is a Dockerfile and why do you need it?
Dockerfile 或多或少是一个包含指令的纯文本文件。它提供了 Docker 镜像的构建蓝图,即容器的蓝图。Dockerfile 详细说明了要安装的所有内容,从操作系统基础到其他每个包依赖项,甚至指定容器启动时需要运行的命令。
Dockerfile 将使镜像创建过程变得高效,并且能够确保在多种环境中的一致性和可复制性。
Q 2. What are some key instructions in a Dockerfile?
其中一些必要的指令有:FROM - 它定义了从中开始构建的基础镜像;RUN - 它执行包含在镜像构建过程中作为一部分的命令,例如软件安装;COPY - 它将文件或目录从本地机器复制到镜像;EXPOSE - 用于声明容器内应用程序将使用的端口;最后 CMD,它设置了容器启动时要运行的默认命令。
Q 3. How are COPY and ADD different in a Dockerfile?
ADD 命令会在 Dockerfile 中将文件添加到您的镜像中。但是,ADD 和 COPY 之间存在重要的差异。COPY 是以透明且可预测的方式从本地机器将文件或目录传输到镜像的首选方法。
ADD 的其他一些功能是能够从远程 URL 提取文件,甚至可以自动提取压缩档案,就像它对 .tar 或 .zip 文件所做的那样。这使得 ADD 看起来更加灵活,但它在提取方面的古怪行为通常导致 COPY 由于简单而更加受欢迎。
请注意,如果您必须下载远程文件,则通常应该使用 curl 或 wget 等下载工具将它们分隔成不同的 RUN 指令,以减少不必要的图像层。