状态: 已弃用
本文已弃用,不再维护。
原因
本文中的技术已经过时,可能不再反映 Docker 的最佳实践。
请参阅
介绍
Docker 容器是使用 base 镜像创建的。 映像可以是基本的,只有操作系统基础,或者它可以包含一个复杂的预构建应用程序堆栈,准备启动。
使用 Docker 构建映像时,所采取的每个操作(即 执行的命令(例如 apt-get install)在前一层之上形成一个新层。 这些基础镜像可以用来创建新的容器。
在这篇 DigitalOcean 文章中,我们将了解如何尽可能地自动化这个过程,并展示通过 Dockerfiles 制作大部分 Docker 和容器的最佳实践和方法:构建容器的脚本,逐步- 逐层,自动从基础图像开始。
词汇表
1. Docker 简介
2. Dockerfiles
3. Dockerfile 语法
- 什么是语法?
- Dockerfile 语法示例
4. Dockerfile 命令
- 添加
- 命令
- 入口点
- 环境噪声
- 暴露
- 从
- 维护者
- 跑
- 用户
- 体积
- 工作目录
5. 如何使用 Dockerfile
6. Dockerfile 示例:创建镜像以安装 MongoDB
- 创建空 Dockerfile
- 定义我们的文件及其目的
- 设置要使用的基本映像
- 定义维护者(作者)
- 更新应用程序存储库列表
- 设置下载 MongoDB 的参数和命令
- 设置 MongoDB 的默认端口
- 保存 Dockerfile
- 建立我们的第一个形象
- 运行 MongoDB 实例
Docker 简介
Docker 项目 提供了更高级别的工具,它们可以协同工作,构建在一些 Linux 内核特性之上。 目标是帮助开发人员和系统管理员移植应用程序——连同它们的所有依赖项——并让它们跨系统和机器运行无头痛。
Docker 通过创建安全的、基于 LXC 的(即 Linux Containers)应用程序环境称为“Docker 容器”。 这些容器是使用 Docker 映像 创建的,可以通过手动执行命令或通过 Dockerfiles 自动执行命令来构建。
注: 了解更多关于 Docker 及其部件(例如 Docker 守护进程、CLI、图像等),请查看我们对该项目的介绍性文章:如何在 Ubuntu 16.04 上安装和使用 Docker。
Dockerfiles
每个 Dockerfile 都是一个脚本,由连续列出的各种命令(指令)和参数组成,以自动对基础镜像执行操作,以创建(或形成)新镜像。 它们用于组织事物,并通过简化从开始到结束的过程极大地帮助部署。
Dockerfile 以定义 构建过程 开始的映像开始。 随后是各种其他方法、命令和参数(或条件),作为回报,提供用于创建 docker 容器的新图像。
可以通过向 docker 守护进程 提供 Dockerfile 的内容(以各种方式)来构建映像(如 如何使用 部分所述),从而使用它们。
Dockerfile 语法
在我们开始讨论 Dockerfiles 之前,让我们快速回顾一下它的语法以及它的实际含义。
什么是语法?
很简单,编程中的语法意味着命令、参数和其他所有东西的结构,这些都是对应用程序进行编程以执行过程(即 一个函数/指令集合)。
这些结构基于规则,明确而明确地定义,程序员应遵循它们与任何计算机应用程序(例如 解释器,守护进程等)使用或期望它们。 如果一个脚本(即 包含要执行的一系列任务的文件)的结构不正确(即 语法错误),计算机程序将无法解析它。 粗略的解析可以理解为遍历输入,最终目标是理解其含义。
Dockerfile 使用简单、干净和清晰的语法,这使得它们非常容易创建和使用。 它们被设计成不言自明的,特别是因为它们允许评论就像一个好的和正确编写的应用程序源代码一样。
Dockerfile 语法示例
Dockerfile 语法由两种主行块组成:注释和命令+参数。
# Line blocks used for commenting command argument argument ..
一个简单的例子:
# Print "Hello docker!" RUN echo "Hello docker!"
Dockerfile 命令(说明)
目前,Dockerfile 可以包含十几种不同的命令来让 Docker 构建映像。 在本节中,我们将在处理 Dockerfile 示例之前分别介绍所有这些。
注意: 如上一节(Dockerfile 语法)所述,所有这些命令都要列出(即 写)连续,在一个单一的纯文本文件(即 Dockerfile),按照您希望它们执行的顺序(即 由 docker 守护进程执行)来构建映像。 但是,其中一些命令(例如 MAINTAINER)可以放置在您认为合适的任何位置(但总是在 FROM 命令之后),因为它们不构成任何执行,而是定义 的 值(即 只是一些额外的信息)。
添加
ADD 命令有两个参数:源和目标。 它基本上将文件从主机上的源复制到设置目标的容器自己的文件系统中。 但是,如果源是 URL(例如 http://github.com/user/file/),然后下载 URL 的内容并放置到目的地。
例子:
# Usage: ADD [source directory or URL] [destination directory] ADD /my_app_folder /my_app_folder
命令
命令 CMD 与 RUN 类似,可用于执行特定命令。 但是,与 RUN 不同,它不会在构建期间执行,而是在使用正在构建的映像实例化容器时执行。 因此,它应该被视为执行的初始默认命令(即 运行)基于图像创建容器。
澄清一下: CMD 的一个例子是在创建已经使用 RUN 安装的容器时运行应用程序(例如 在镜像中运行 apt-get install ...)。 使用 CMD 设置的此默认应用程序执行命令成为默认命令,并替换在创建期间传递的任何命令。
例子:
# Usage 1: CMD application "argument", "argument", .. CMD "echo" "Hello docker!"
入口点
ENTRYPOINT 参数设置每次使用图像创建容器时使用的具体默认应用程序。 例如,如果您在映像中安装了特定应用程序,并且您将使用此映像仅运行该应用程序,则可以使用 ENTRYPOINT 声明它,并且每当从该映像创建容器时,您的应用程序将成为目标。
如果将 ENTRYPOINT 与 CMD 耦合,则可以从 CMD 中删除“应用程序”,并留下将传递给 ENTRYPOINT 的“参数”。
例子:
# Usage: ENTRYPOINT application "argument", "argument", .. # Remember: arguments are optional. They can be provided by CMD # or during the creation of a container. ENTRYPOINT echo # Usage example with CMD: # Arguments set with CMD can be overridden during *run* CMD "Hello docker!" ENTRYPOINT echo
环境噪声
ENV 命令用于设置环境变量(一个或多个)。 这些变量由“键值”对组成,脚本和应用程序等可以在容器内访问它们。 Docker 的这一功能为运行程序提供了极大的灵活性。
例子:
# Usage: ENV key value ENV SERVER_WORKS 4
暴露
EXPOSE命令用于关联指定端口,使容器内部正在运行的进程与外界联网(即 主人)。
例子:
# Usage: EXPOSE [port] EXPOSE 8080
要了解 Docker 网络,请查看 Docker 容器网络文档。
从
FROM 指令可能是 Dockerfile 中最重要的。 它定义了用于启动构建过程的基础镜像。 它可以是任何图像,包括您之前创建的图像。 如果在主机上找不到 FROM 映像,Docker 将尝试从 Docker Hub 或其他容器存储库中找到(并下载)它。 它必须是在 Dockerfile 中声明的第一个命令。
例子:
# Usage: FROM [image name] FROM ubuntu
维护者
可以在文件中的任何位置设置的命令之一 - 尽管如果在顶部声明它会更好 - 是 MAINTAINER。 这个非执行命令声明作者,因此设置图像的作者字段。 尽管如此,它应该在 FROM 之后。
例子:
# Usage: MAINTAINER [name] MAINTAINER authors_name
跑
RUN 命令是 Dockerfile 的中央执行指令。 它将命令作为参数并运行它以形成图像。 与 CMD 不同,它实际上 是 用于构建图像(在已提交的前一层之上形成另一层)。
例子:
# Usage: RUN [command] RUN aptitude install -y riak
用户
USER 指令用于设置基于正在构建的图像运行容器的 UID(或用户名)。
例子:
# Usage: USER [UID] USER 751
体积
VOLUME 命令用于允许从容器访问主机上的目录(即 安装它)。
例子:
# Usage: VOLUME ["/dir_1", "/dir_2" ..] VOLUME ["/my_files"]
工作目录
WORKDIR 指令用于设置执行 CMD 定义的命令的位置。
例子:
# Usage: WORKDIR /path WORKDIR ~/
如何使用 Dockerfile
使用 Dockerfiles 就像让 Docker 守护进程运行一个一样简单。 执行脚本后的输出将是新 docker 镜像的 ID。
用法:
# Build an image using the Dockerfile at current location # Example: docker build -t [name] . docker build -t my_mongodb .
Dockerfile 示例:创建镜像以安装 MongoDB
在 Dockerfiles 的最后一节中,我们将创建一个 Dockerfile 文档,并逐步使用 Dockerfile 的最终结果填充它,该 Dockerfile 可用于创建 docker 映像以运行 MongoDB 容器。
注意: 开始编辑 Dockerfile 后,按照我们的示例和 Docker 语法[X229X ] 部分。 您可以在本演练的最新部分查看最终结果。
创建空 Dockerfile
使用 nano 文本编辑器,让我们开始编辑 Dockerfile。
nano Dockerfile
定义我们的文件及其目的
尽管是可选的,但让自己和每个人都弄清楚(必要时)这个文件是什么以及它打算做什么总是一个好习惯。 为此,我们将以花哨的注释 (#) 开始我们的 Dockerfile 来描述它。
############################################################ # Dockerfile to build MongoDB container images # Based on Ubuntu ############################################################
设置要使用的基本映像
# Set the base image to Ubuntu FROM ubuntu
定义维护者(作者)
# File Author / Maintainer MAINTAINER Example McAuthor
设置下载 MongoDB 的参数和命令
################## BEGIN INSTALLATION ###################### # Install MongoDB Following the Instructions at MongoDB Docs # Ref: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/ # Add the package verification key RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 # Add MongoDB to the repository sources list RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | tee /etc/apt/sources.list.d/mongodb.list # Update the repository sources list RUN apt-get update # Install MongoDB package (.deb) RUN apt-get install -y mongodb-10gen # Create the default data directory RUN mkdir -p /data/db ##################### INSTALLATION END #####################
设置 MongoDB 的默认端口
# Expose the default port EXPOSE 27017 # Default port to execute the entrypoint (MongoDB) CMD ["--port 27017"] # Set default container command ENTRYPOINT usr/bin/mongod
保存 Dockerfile
将所有内容附加到文件后,就该保存并退出了。 按 CTRL+X,然后按 Y 确认并保存 Dockerfile。
这是最终文件的样子:
############################################################ # Dockerfile to build MongoDB container images # Based on Ubuntu ############################################################ # Set the base image to Ubuntu FROM ubuntu # File Author / Maintainer MAINTAINER Example McAuthor ################## BEGIN INSTALLATION ###################### # Install MongoDB Following the Instructions at MongoDB Docs # Ref: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/ # Add the package verification key RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 # Add MongoDB to the repository sources list RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | tee /etc/apt/sources.list.d/mongodb.list # Update the repository sources list RUN apt-get update # Install MongoDB package (.deb) RUN apt-get install -y mongodb-10gen # Create the default data directory RUN mkdir -p /data/db ##################### INSTALLATION END ##################### # Expose the default port EXPOSE 27017 # Default port to execute the entrypoint (MongoDB) CMD ["--port 27017"] # Set default container command ENTRYPOINT usr/bin/mongod
建立我们的第一个形象
使用前面的解释,我们已经准备好用 docker 创建我们的第一个 MongoDB 镜像了!
docker build -t my_mongodb .
注意: 这里的-t [name]标志位是用来标记图像的。 要了解更多关于在构建期间还可以做什么,请运行 docker build --help
。
运行 MongoDB 实例
使用我们构建的镜像,我们现在可以进行最后一步:使用我们选择的名称(如果需要,使用 -name [name])创建一个运行 MongoDB 实例的容器。
docker run -name my_first_mdb_instance -i -t my_mongodb
注意: 如果没有设置名称,我们将需要处理复杂的字母数字 ID,这些 ID 可以通过使用 docker ps -l
列出所有容器来获得。
注意: 要将自己从容器中分离出来,请使用转义序列 CTRL+P
后跟 CTRL+Q
。
享受!