Docker 解析:使用 Dockerfile 自动构建镜像

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Docker 解析:使用 Dockerfile 自动构建镜像

简介


Docker 容器是使用 基础 镜像创建的。一个镜像可以是基本的,只包含操作系统的基本要素,也可以包含一个准备好启动的复杂的预构建应用程序堆栈。

在使用 Docker 构建镜像时,每个操作(例如执行的命令,比如 apt-get install)都会形成一个新的层叠在之前的层之上。然后可以使用这些基础镜像来创建新的容器。

在这篇 DigitalOcean 文章中,我们将尽可能自动化这个过程,并演示通过 Dockerfiles 来实现 Docker 和容器的最佳实践和方法:逐步、自动地从基础镜像构建容器。

术语表


1. Docker 简介


2. Dockerfiles


3. Dockerfile 语法


  1. 什么是语法?
  2. Dockerfile 语法示例

4. Dockerfile 命令


  1. ADD
  2. CMD
  3. ENTRYPOINT
  4. ENV
  5. EXPOSE
  6. FROM
  7. MAINTAINER
  8. RUN
  9. USER
  10. VOLUME
  11. WORKDIR

5. 如何使用 Dockerfiles


6. Dockerfile 示例:创建安装 MongoDB 的镜像


  1. 创建空的 Dockerfile
  2. 定义我们的文件及其目的
  3. 设置要使用的基础镜像
  4. 定义维护者(作者)
  5. 更新应用程序仓库列表
  6. 设置下载 MongoDB 的参数和命令
  7. 设置 MongoDB 的默认端口
  8. 保存 Dockerfile
  9. 构建我们的第一个镜像
  10. 运行 MongoDB 实例

Docker 简介


Docker 项目提供了一些在一些 Linux 内核特性之上构建的高级工具。其目标是帮助开发人员和系统管理员将应用程序及其所有依赖项一起移植,并在各种系统和机器上 无忧地 运行。

Docker 通过为应用程序创建安全的基于 LXC(即 Linux 容器)的环境来实现这一目标,这些环境被称为 “Docker 容器”。这些容器是使用 Docker 镜像 创建的,这些镜像可以通过手动执行命令或通过 Dockerfiles 自动构建。

注意: 要了解更多关于 Docker 及其部分(例如 Docker 守护程序、CLI、镜像等)的信息,请查看我们的项目介绍文章:如何在 Ubuntu 16.04 上安装和使用 Docker。

Dockerfiles


每个 Dockerfile 都是一个脚本,由各种命令(指令)和参数依次列出,用于自动在基础镜像上执行操作以创建(或形成)一个新镜像。它们用于组织事物,并通过简化整个部署过程大大帮助部署。

Dockerfiles 以定义一个图像 FROM 开始,该图像是 构建过程 的起点。随后是各种其他方法、命令和参数(或条件),以返回一个新的图像,该图像将用于创建 Docker 容器。

它们可以通过以各种方式提供 Dockerfile 的内容来使用,以便由 docker 守护程序 构建图像(如 如何使用 部分中所述)。

Dockerfile 语法


在我们开始讨论 Dockerfiles 之前,让我们快速了解其语法及其实际含义。

什么是语法?


在编程中,语法简单地意味着一种结构,用于按顺序排列命令、参数和执行应用程序所需的所有其他内容,以执行一个过程(即一个函数/一系列指令)。

这些结构基于明确定义的规则,并且程序员必须遵循这些规则,以与使用或期望它们的任何计算机应用程序(例如解释器、守护程序等)进行交互。如果脚本(即包含要执行的一系列任务的文件)没有正确结构化(即语法错误),计算机程序将无法解析它。解析大致可以理解为对输入进行检查,最终目标是理解其含义。

Dockerfiles 使用简单、清晰的语法,使它们非常容易创建和使用。它们被设计为自解释的,特别是因为它们允许像良好编写的应用程序源代码一样进行注释。

Dockerfile 语法示例


Dockerfile 语法由两种主要的行块组成:注释和命令 + 参数。

# 用于注释的行块
命令 参数 参数 ..

一个简单的示例:

# 打印 "Hello docker!"
RUN echo "Hello docker!"

Dockerfile 命令(指令)


目前有大约十几种不同的命令集,Dockerfiles 可以包含这些命令集以使 Docker 构建一个镜像。在本节中,我们将在单独讨论所有这些命令之前逐一介绍它们。

注意: 如前一节(Dockerfile 语法)所述,所有这些命令都应按照您希望它们由 docker 守护程序执行的顺序(即执行)依次列出(即编写)在单个纯文本文件(即 Dockerfile)中。然而,其中一些命令(例如 MAINTAINER)可以放置在您认为合适的任何位置(但始终在 FROM 命令之后),因为它们不构成任何执行,而是 定义的值(即一些附加信息)。

ADD


ADD 命令有两个参数:源和目的地。它基本上将主机上源目录中的文件复制到容器自己的文件系统中的设置目的地。然而,如果源是一个 URL(例如 http://github.com/user/file/),那么将下载该 URL 的内容并放置在目的地。

示例:

# 用法: ADD [源目录或 URL] [目的地目录]
ADD /my_app_folder /my_app_folder

CMD


CMD 命令与 RUN 类似,用于执行特定命令。然而,与 RUN 不同的是,CMD 不是在构建时执行,而是在使用正在构建的镜像实例化容器时执行。因此,它应被视为在基于该镜像创建容器时执行的初始默认命令。

澄清一下: CMD 的一个示例是在容器创建时运行一个已经使用 RUN(例如 RUN apt-get install …)在镜像中安装的应用程序。使用 CMD 设置的默认应用程序执行命令将成为默认命令,并替换在创建时传递的任何命令。

示例:

# 用法 1: CMD 应用程序 "参数", "参数", ..
CMD "echo" "Hello docker!"

ENTRYPOINT


ENTRYPOINT 参数设置每次使用正在构建的镜像创建容器时使用的具体默认应用程序。例如,如果您在镜像中安装了特定应用程序,并且您将使用该镜像仅运行该应用程序,您可以使用 ENTRYPOINT 来指定,这样每次从该镜像创建容器时,您的应用程序将成为目标。

如果将 ENTRYPOINT 与 CMD 结合使用,可以从 CMD 中删除 “应用程序”,只留下将传递给 ENTRYPOINT 的 “参数”。

示例:

# 用法: ENTRYPOINT 应用程序 "参数", "参数", ..
# 注意: 参数是可选的。它们可以由 CMD 提供,
#      或在创建容器时提供。
ENTRYPOINT echo
# 使用 CMD 的示例:
# 通过 CMD 设置的参数可以在 *run* 期间被覆盖
CMD "Hello docker!"
ENTRYPOINT echo

ENV


ENV 命令用于设置环境变量(一个或多个)。这些变量由“键值”对组成,可以被脚本和应用程序在容器内访问。Docker 的这一功能为运行程序提供了巨大的灵活性。

示例:

# 用法: ENV 键 值
ENV SERVER_WORKS 4

EXPOSE


EXPOSE 命令用于将指定端口与容器内运行的进程与外部世界(即主机)进行网络关联。

示例:

# 用法: EXPOSE [端口]
EXPOSE 8080

要了解 Docker 网络,请查看 Docker 容器网络文档。

FROM


FROM 指令可能是 Dockerfile 中最关键的指令。它定义了用于启动构建过程的基础镜像。它可以是任何镜像,包括您之前创建的镜像。如果在主机上找不到 FROM 镜像,Docker 将尝试在 Docker Hub 或其他容器存储库中找到它(并下载)。它需要是 Dockerfile 中声明的第一个命令。

示例:

# 用法: FROM [镜像名称]
FROM ubuntu

MAINTAINER


可以在文件中的任何位置设置的命令之一(尽管最好是在顶部声明)是 MAINTAINER。这个非执行命令声明了作者,因此设置了镜像的作者字段。然而,它应该在 FROM 之后声明。

示例:

# 用法: MAINTAINER [姓名]
MAINTAINER 作者的姓名

RUN


RUN 命令是 Dockerfile 的中心执行指令。它以命令作为参数并运行它以形成镜像。与 CMD 不同,它实际上用于构建镜像(在前一个镜像的顶部形成另一层,该层被提交)。

示例:

# 用法: RUN [命令]
RUN aptitude install -y riak

USER


USER 指令用于设置基于正在构建的镜像运行容器的 UID(或用户名)。

示例:

# 用法: USER [UID]
USER 751

VOLUME


VOLUME 命令用于启用容器访问主机机器上的目录(即挂载它)。

示例:

# 用法: VOLUME ["/dir_1", "/dir_2" ..]
VOLUME ["/my_files"]

WORKDIR


WORKDIR 指令用于设置 CMD 中定义的命令要执行的位置。

示例:

# 用法: WORKDIR /路径
WORKDIR ~/

如何使用 Dockerfiles


使用 Dockerfiles 就像让 Docker 守护程序运行一个一样简单。执行脚本后的输出将是新 Docker 镜像的 ID。

用法:

# 在当前位置使用 Dockerfile 构建一个镜像
# 例如:docker build -t [name] .
docker build -t my_mongodb .

Dockerfile 示例:创建一个安装 MongoDB 的镜像


在 Dockerfiles 的最后一节中,我们将创建一个 Dockerfile 文档,并逐步填充它,最终得到一个可以用来创建运行 MongoDB 容器的 Dockerfile。

注意: 在开始编辑 Dockerfile 后,所有下面各节的内容和参数都将依次写入(追加)到其中,遵循我们的示例和Docker 语法部分的解释。您可以在本教程的最后部分看到最终结果。

创建空的 Dockerfile


使用 nano 文本编辑器,让我们开始编辑我们的 Dockerfile。

nano Dockerfile

定义我们的文件及其目的


虽然可选,但始终是一个好习惯,让自己和其他人在必要时能够弄清楚这个文件是什么,以及它的目的是什么。因此,我们将用花哨的注释(#)开始我们的 Dockerfile 来描述它。

############################################################
# Dockerfile to build MongoDB container images
# Based on Ubuntu
############################################################

设置要使用的基础镜像


# 将基础镜像设置为 Ubuntu
FROM ubuntu

定义维护者(作者)


# 文件作者 / 维护者
MAINTAINER Example McAuthor

设置下载 MongoDB 的参数和命令


################## 开始安装 ######################
# 按照 MongoDB 文档的说明安装 MongoDB
# 参考:http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/
# 添加软件包验证密钥
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
# 将 MongoDB 添加到存储库源列表
RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | tee /etc/apt/sources.list.d/mongodb.list
# 更新存储库源列表
RUN apt-get update
# 安装 MongoDB 软件包(.deb)
RUN apt-get install -y mongodb-10gen
# 创建默认数据目录
RUN mkdir -p /data/db
##################### 安装结束 #####################

设置 MongoDB 的默认端口


# 公开默认端口
EXPOSE 27017
# 执行入口点(MongoDB)的默认端口
CMD ["--port 27017"]
# 设置默认容器命令
ENTRYPOINT usr/bin/mongod

保存 Dockerfile


在将所有内容追加到文件后,是时候保存并退出了。按下 CTRL+X,然后按 Y 确认并保存 Dockerfile。

最终文件应如下所示:

############################################################
# Dockerfile to build MongoDB container images
# Based on Ubuntu
############################################################
# 将基础镜像设置为 Ubuntu
FROM ubuntu
# 文件作者 / 维护者
MAINTAINER Example McAuthor
################## 开始安装 ######################
# 按照 MongoDB 文档的说明安装 MongoDB
# 参考:http://docs.mongodb.org/manual/tutorial/install-mongodb-on-ubuntu/
# 添加软件包验证密钥
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
# 将 MongoDB 添加到存储库源列表
RUN echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | tee /etc/apt/sources.list.d/mongodb.list
# 更新存储库源列表
RUN apt-get update
# 安装 MongoDB 软件包(.deb)
RUN apt-get install -y mongodb-10gen
# 创建默认数据目录
RUN mkdir -p /data/db
##################### 安装结束 #####################
# 公开默认端口
EXPOSE 27017
# 执行入口点(MongoDB)的默认端口
CMD ["--port 27017"]
# 设置默认容器命令
ENTRYPOINT usr/bin/mongod

构建我们的第一个镜像


根据之前的解释,我们已经准备好用 docker 创建我们的第一个 MongoDB 镜像了!

docker build -t my_mongodb .

注意: 这里的 -t [name] 标志用于给镜像打标签。要了解在构建过程中还可以做什么,请运行 docker build --help

运行 MongoDB 实例


使用我们构建的镜像,现在我们可以进行最后一步:创建一个运行 MongoDB 实例的容器,可以使用我们选择的名称(如果需要,可以使用 -name [name])。

docker run -name my_first_mdb_instance -i -t my_mongodb

注意: 如果没有设置名称,我们将需要处理复杂的包含字母数字的 ID,可以通过使用 docker ps -l 命令列出所有容器来获取。

注意: 要从容器中分离出来,请使用转义序列 CTRL+P,然后是 CTRL+Q

祝您使用愉快!


目录
相关文章
|
22天前
|
Docker 容器
将本地的应用程序打包成Docker镜像
将本地的应用程序打包成Docker镜像
|
6天前
|
NoSQL PHP MongoDB
docker push推送自己搭建的镜像
本文详细介绍了如何搭建和复盘两个Web安全挑战环境:人力资源管理系统和邮件管理系统。首先,通过Docker搭建MongoDB和PHP环境,模拟人力资源管理系统的漏洞,包括nosql注入和文件写入等。接着,复盘了如何利用这些漏洞获取flag。邮件管理系统部分,通过目录遍历、文件恢复和字符串比较等技术,逐步绕过验证并最终获取flag。文章提供了详细的步骤和代码示例,适合安全研究人员学习和实践。
24 3
docker push推送自己搭建的镜像
|
22天前
|
数据库 Docker 容器
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。
Docker在现代软件开发中扮演着重要角色,通过Dockerfile自动化构建Docker镜像,实现高效、可重复的构建过程。Dockerfile定义了构建镜像所需的所有指令,包括基础镜像选择、软件安装、文件复制等,极大提高了开发和部署的灵活性与一致性。掌握Dockerfile的编写,对于提升软件开发效率和环境管理具有重要意义。
42 9
|
22天前
|
存储 缓存 运维
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像。此机制减少存储占用,提高构建和传输效率。Docker还通过缓存机制提升构建和运行效率,减少重复工作。文章深入解析了Docker镜像分层存储与缓存机制,包括具体实现、管理优化及实际应用案例,帮助读者全面理解其优势与挑战。
43 4
|
22天前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
50 3
|
25天前
|
安全 持续交付 Docker
深入理解并实践容器化技术——Docker 深度解析
深入理解并实践容器化技术——Docker 深度解析
45 2
|
1月前
|
运维 持续交付 虚拟化
深入解析Docker容器化技术的核心原理
深入解析Docker容器化技术的核心原理
46 1
|
1月前
|
存储 关系型数据库 Linux
【赵渝强老师】什么是Docker的镜像
Docker镜像是一个只读模板,包含应用程序及其运行所需的依赖环境。镜像采用分层文件系统,每次修改都会以读写层形式添加到原只读模板上。内核bootfs用于加载Linux内核,根镜像相当于操作系统,上方为应用层。镜像在物理存储上是一系列文件的集合,默认存储路径为“/var/lib/docker”。
|
1月前
|
缓存 JavaScript 安全
深入理解Docker镜像构建过程
深入理解Docker镜像构建过程
71 0