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

  • Post author:
  • Post category:其他


本文章翻译自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 update



    apk 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

来查看



镜像的层



镜像检查



版权声明:本文为cedian0443原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。