Docker教程(二) - 将容器打包成Docker镜像、使用Dockerfile打包镜像

2023-10-30

本文章翻译自Docker的官方教程,有兴趣的同学可以上Docker官网进行play-with-docker学习。Docker的安装教程请参考这里(未定义)

本文翻译自Docker官方教程Doing More With Docker Images,并作出一定的修改及删减以加快上手速度。

Docker教程(二) - 将容器打包成Docker镜像、使用Dockerfile打包镜像


通过上一个教程,我们已经学会了如何从 Docker Store 下载 Docker 镜像,并用这个镜像尝试创建了几个不同的容器。但是,只会这样创建容器是没有实际意义的,我们需要学会更多对镜像的操作技巧,从而在我们的实际工作过程中,起到省钱、省时的作用。

尽管Docker Store上可以下载到各种各样的 Docker 镜像,但是,一些比较大的镜像(大于700k),就已经可能包含了许多你在你的实际应用环境中所不需要的东西,显然你并不希望直接使用这些非标准的镜像。所以,通常情况下,我们会下载一些比较标准的镜像,再添加一些我们自己所需要的东西,然后制作成为一个符合我们需求的镜像,这样以后我们就可以重用(re-use)并向其他人分享我们这个这个自定义的镜像。

在这个教程中,我们会首先简单地用 commit 的方式将我们的一个容器制作成一个镜像。然后我们会学习使用更加高效,强大的方式:Dockerfile

将容器打包成镜像

首先,我们使用交互模式打开一个 ubuntu 容器中的 shell

sudo docker container run -ti ubuntu bash

这个 ubuntu 容器是一个标准的容器,现在让我们对其进行一个小修改,我们为它安装一个叫 figlet 的软件包。

FIGlet是基于ASCII字符组成的字符画。具体可以参考这里

sudo apt-get update
sudo apt-get install -y figlet
figlet "hello docker"
exit

在这里插入图片描述
执行上面的指令,你会看见终端打印了一个很“酷炫”的 hello world 字符画。OK, 现在我们这个 ubuntu + figlet 的容器就已经准备好了。

好了,现在你觉得这个figlet很有趣(不能觉得有趣,我不要你觉得),你想向你的朋友分享一下。当然,因为这个例子很简单,你可以直接告诉你的朋友怎样去安装这个。但是,如果这是一个很复杂的过程,你可能安装了很多软件包,甚至做了很多根本无法理解的配置,让你去写一个文档去说明怎样搞就显得很麻烦了。

所以,你需要做的事是,将这个docker容器,做成一个image镜像,这样你只需要把这个镜像分享给你的朋友,他就可以用这个镜像构建出一个和你一模一样的容器来。

首先,查看一下现在我们有哪些容器。

sudo docker container ls -a

在这里插入图片描述
可见,<CONTAINER_ID> 为d304e87568da 的容器,就是我们刚才运行figlet的容器。你可以输入下面的命令看一下我们对这个容器做了哪些修改。

# example: sudo docker container diff d304e87568da
sudo docker container diff < 输入你的 CONTAINER_ID >

你会看到有一系列的文件被列出,这就是我们刚才所做的修改。

列出的是这个当前这个容器,和使用镜像构建的原始容器的不同

现在,要生成一个 ubuntu + figlet 的镜像,你需要commit这个容器。这个commit的操作会在你的本地,根据你指定的容器,创建一个镜像。

# example: sudo docker container commit d304e87568da our_figlet:v0.1
sudo docker container commit < 输入你的 CONTAINER_ID > <需要构建的镜像名:版本号>

创建完后,在查看一下现在本地的镜像

sudo docker image ls

在这里插入图片描述这时,发现我们多了一个叫our_figlet,版本号为v0.1的镜像。
镜像构建流程现在我们尝试一下用我们刚才新建的镜像来构建一个容器,并运行一下figlet

sudo docker container run our_figlet:v0.1 figlet hello

在这里插入图片描述
现在我们有了这个镜像,我们就能很轻松地构建多个相同的容器了。不过,这个镜像现在只是存在本地,你很难和你的朋友分享。你可以将这个镜像上传到服务器上,例如 DockerHub, 这样其他人就能很容易地使用到你的这个镜像。

使用 Dockerfile 打包镜像

除了直接创建静态的二进制的 docker 镜像外,我们还可以使用 Dockerfile 来创建镜像。当我们的镜像变得越来越大,越来越复杂的时候,使用Dockerfile来创建镜像,可以令你能更方便地管理你的镜像。

用上面的figlet来举个例子,我们在上面创建的our_figlet镜像,使用的是我们当前最新版本(:latest)的figlet软件包。但是,在未来的某一天,figlet更新了,我们又想用最新版本的figlet,这样,我们只能重复上面的步骤,重新创建一个新的镜像。如果你的镜像包含了9999999个这样要更新的软件包,这样做你就GG了。然而,如果你是使用Dockerfile 来创建镜像的话,你仅需要在Dockerfile 里面添加一行apt update,就可以保证以后创建出来的镜像都包含最新的figlet

OK, 现在我们开始尝试用Dockerfile来创建一个镜像。

首先,写一个简单的js程序,命名为index.js

var os = require("os");
var hostname = os.hostname();
console.log("hello from " + hostname);

本人不懂JavaScript, 上面的程序是来自Docker官方教程,为保持统一,这里依然使用js程序,如果有理解错的地方欢迎指出。

这里应该是一个简单的Hello World程序。然后在相同目录下创建一个文件,文件名为Dockerfile,复制下面的内容:

FROM alpine
RUN apk update && apk add nodejs
COPY . /app
WORKDIR /app
CMD ["node","index.js"]

准备好以后,执行以下命令,创建一个叫hello:v0.1的镜像。

sudo docker image build -t hello:v0.1 .		# 注意后面那个“.”,这个点表示当前目录

构建这个Dockerfile相当于执行了以下操作:

  1. 下载一个标准的alpine镜像
  2. 用这个镜像构建一个容器
  3. 在这个容器里面运行apk updateapk add nodejs
  4. inde.js文件复制到容器的 /app 目录下
  5. 进入 /app目录,并执行node index.js指令
  6. 最后将这个容器构建成一个新的镜像

在这里插入图片描述现在查看一下我们本地所拥有的镜像并运行这个镜像:

sudo docker images
sudo docker run hello:v0.1

在这里插入图片描述
可以看见,我们现在拥有一个版本号为v0.1的,名叫hello的镜像,运行的时候,终端会显示这个容器的ID。

容器的ID可以通过sudo docker ps -a 来查看

镜像的层

镜像检查

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker教程(二) - 将容器打包成Docker镜像、使用Dockerfile打包镜像 的相关文章

随机推荐