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

祝您使用愉快!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/750773.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络编程套接字——实现简单的UDP网络程序

目录 1、预备知识 1.1、认识端口号 1.2、端口号 vs 进程pid 1.3、认识TCP协议 1.4、认识UDP协议 1.5、网络字节序 2、socket编程接口 2.1、socket常见API 2.2、sockaddr结构 3、实现一个简易的UDP服务器和客户端通信 log.hpp UdpServer.hpp UdpClient.cc Main.cc…

upload-labs通关方式

pass-1 通过弹窗可推断此关卡的语言大概率为js,因此得出两种解决办法 方法一 浏览器禁用js 关闭后就逃出了js的验证就可以正常php文件 上传成功后打开图片链接根据你写的一句话木马执行它,我这里采用phpinfo() 方法二 在控制台…

【网络编程基础(一)】网络基础和SOCKET

这里写目录标题 1、网络三要素2、IPV4和IPV6区别3、网络交互3.1、交互模型图3.2、基础通信协议3.3、OSI参考模型与TCP/IP参考模型对应关系 4、SOCKET网络套接字4.1、SOCKET分类4.2、基于流式套接字的编程流程4.3、网络通信雏形4.4、socket函数4.4.1、socket函数示例 4.5、bind函…

蓝桥杯小白赛第 7 场 3.奇偶排序(sort排序 + 双数组)

思路:在第一次看到这道题的时候我第一想法是用冒泡,但好像我的水平还不允许我写出来。我又读了遍题目发现它的数据很小,我就寻思着把它分成奇偶两部分。应该怎么分呢? 当然在读入的时候把这个问题解决就最好了。正好它的数据范围…

【相关问题解答1】bert中文文本摘要代码:import时无法找到包时,几个潜在的原因和解决方法

【相关问题解答1】bert中文文本摘要代码 写在最前面问题1问题描述一些建议import时无法找到包时,几个潜在的原因和解决方法1. 模块或包的命名冲突解决方法: 2. 错误的导入路径解决方法: 3. 第三方库的使用错误解决方法: 4. 包未正…

C++算法学习心得八.动态规划算法(4)

1.零钱兑换(322题) 题目描述: 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。 你可以认为每种硬币的数量是无限的。…

CSDN学习笔记总索引(2024)——我的创作纪念日(1024)

2021-05-21至2024-03-17笔记,收集并展示浏览阅读点赞收藏等数据。 (本笔记适合初通Python,对其基本数据类型字符串str、列表list、元组tuple、字典dict初步了解,认识Linux获取Html文本指令crul、会使正则模块re的coder翻阅) 【学习的细节是欢…

【C++】每日一题 105 从前序和中序序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 #include <iostream> #include <vector> #include <unordered_map>struct TreeN…

华为机试真题练习汇总(41~50)

华为机试真题练习汇总&#xff08;41~50&#xff09; 华为机试真题练习汇总&#xff08;41~50&#xff09;* HJ41 称砝码* HJ42 学英语* HJ43 迷宫问题* HJ44 SudokuHJ45 名字的漂亮度HJ46 截取字符串HJ48 从单向链表中删除指定值的节点** HJ50 四则运算 华为机试真题练习汇总&…

VS2019加QT5.14中Please assign a Qt installation in ‘Qt Project Settings‘.问题的解决

第一篇&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/aoxuestudy/article/details/124312629 error:There’ no Qt version assigned to project mdi.vcxproj for configuration release/x64.Please assign a Qt installation in “Qt Project Settings”. 一、分…

修改Docker 默认存储路径,镜像容器移动到新路径

修改Docker 默认存储路径&#xff0c;镜像容器移动到新路径 查看当前docker的默认存储目录1 停止docker服务2 数据迁移3 配置目录4 重启docker服务5 查看 主机 ubuntu20.04 查看当前docker的默认存储目录 docker info显示 Docker Root Dir: /var/lib/docker1 停止docker服务…

船舶工控机维修 日本古野FURUNO工控机主板 船用雷达配件

古野海洋雷达是迄今为止为休闲划船者打造的最佳碰撞规避系统。雷达系统让您“看到”黑暗、薄雾和暴风雨天气条件。当仅在大型船舶上使用时&#xff0c;雷达设备现在结构紧凑&#xff0c;吸引很少的电能&#xff0c;并且尺寸适合小至 18 英尺的船只。雷达与带有最新数字图表的 A…

PPO:推动语言模型对齐的关键技术

PPO&#xff1a;推动语言模型对齐的关键技术 最新的人工智能研究揭示&#xff0c;通过人类反馈的强化学习(RLHF)是训练大型语言模型(LLMs)的关键技术。尽管某些AI从业者因熟悉监督学习而回避使用RL&#xff0c;但RL技术其实并不复杂&#xff0c;并能显著提升LLM的性能。本文深…

Linux基础开发工具之yum与vim

1. Linux软件包管理器——yum 1.1 什么是软件包&#xff1f; 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, …

Nginx离线安装(保姆级教程)

1、下载与安装gcc-c环境 获取rpm包的方式很多&#xff0c;在这里推荐使用yum工具获取&#xff0c;因为手动从官网下载&#xff0c;手动执行rpm -Uvh *.rpm --nodeps --force命令进行安装&#xff0c;可能会缺少某个依赖&#xff0c;我们也不确定到底需要哪些依赖。 因此需要准…

基于Linux内核的socket编程(TCP)的C语言示例

原文地址&#xff1a;https://www.geeksforgeeks.org/socket-programming-cc/ 服务端&#xff1a; #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <unistd.h>#…

【Conda】详细讲解

Conda 1. 前言2. 关键特点3. Conda命令 1. 前言 Conda是一个流行的包管理器和环境管理器&#xff0c;主要用于Python编程语言&#xff0c;但也可以用来安装、运行和更新包和环境中的任何语言&#xff0c;如R、Ruby、Lua、Scala、Java等。Conda主要是为了方便数据科学、机器学习…

Python之Web开发中级教程----搭建Web框架二

Python之Web开发中级教程----搭建Web框架二 搭建虚拟环境 虚拟环境的作用 虚拟环境可以搭建独立的python运行环境, 使得单个项目的运行环境与其它项目互不影响. 搭建虚拟环境 &#xff08;1&#xff09;安装 sudo pip install virtualenv sudo pip install virtualenvwra…

17个工作必备的Python自动化代码分享(上篇)

引言 Python是一种流行的编程语言&#xff0c;以其简单性和可读性而闻名。因其能够提供大量的库和模块&#xff0c;它成为了自动化各种任务的绝佳选择。让我们进入自动化的世界&#xff0c;探索17个可以简化工作并节省时间精力的Python脚本。 目录&#xff08;上篇&#xff0…

在线答疑系统|基于springboot框架+ Mysql+Java+Tomcat的在线答疑系统设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 学生功能模块 教师后台功能模块 管理员功能模块 系统功能设计 数据库E-R图设计 lunwen参考 摘要 研…