docker从入门到实践: (2)docker构建

在上一篇教程里,我们学会了docker的使用,也体验了docker的隔离性,在里面随意增删软件,不用的时候直接删除镜像容器,很方便。但是,还有问题,如果你的朋友也想试用你的软件,怎么办呢?或者你换了台电脑,又要重新pull然后在docker里install么?

当然不用,我们说过docker具有快速部署的优点。今天我们学习怎么构建我们自己的docker镜像。


一:docker commit

最直观的思路,自然是将我们的容器保存下来。而docker也为此提供了很方便的命令,即 docker commit。其格式为

docker commit -a "author" -m "message" <exiting-container> <hub-user>/<repo-name>[:<tag>]

是不是很像 git的commit命令?其中 exiting-container为你的容器名称或 id,hub-user 为你登录的 DockerHub 用户名,repo-name 为你想给新镜像起的名字。

镜像构建成功之后,就可以分享了

你可以使用 docker save <image> | gzip > fileName 将 image 保存为文件,然后拷贝给他人,再通过 docker load -i fileName导入使用。

这么做太麻烦了。推荐方式是使用 docker push 命令将其推送到 DockerHub,当然你需要先登录。

我把上次的 ubuntu 做了commit,并 push 到了 DockerHub,成功之后就可以在DockerHub看到自己的镜像了,之后可以随时拉取使用。

另外,通过docker history 可以看到容器的创建历史,我们可以试下。

我们发现,在软件内部增删软件、文件等操作在这里都无法体现,因此我们的镜像事实上成了一个黑盒,没有文档就不知道其具体有什么功能,即使你添加了文档,经过一次次更改文档很可能也没有同步了,非常不方便别人或者自己以后使用。事实上,docker 提供了更方便强大的方式构建镜像,即 Dockerfile。

另外,commit 方式在特定场景下也有其用途,比如程序崩溃、被入侵后保存现场时,就很有用。

二:Dockerfile

Dockerfile 是一个文本文件,其内包含了一条条的指令,描述我们的镜像该如何构建,就像我们程序的源码。在这之前,补充一个知识,就是我们的 docker 镜像文件事实上是分层的。你应该注意到拉取 ubuntu 的时候,它pull 了很多次。而分层的操作也方便不同镜像间共享相同的层,这显著的节省了客户机的存储空间以及下载时间。

例如,我再拉取一个 nginx 镜像,你会发现第一层已经存在了,直接复用。

为什么要讲这个?因为 Dockfile 的每一条指令的内容,就是描述该层应当如何构建。

我们首先来定制一个 nginx 镜像。

任意新建一个文件夹,建立一个文本文件,命名为 Dockerfile。

文本内容如下:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

然后执行docker build命令构建镜像

docker build -t "name:tag" path

可以发现,如之前所说,新的容器分两层构建。注意命令最后有一个点,表示当前文件夹。

然后,执行 docker run 启动镜像。

这时访问http://127.0.0.1:8080应该就能看到我们的页面了。注意之前的镜像可能已经绑定了本机8080端口,你需要停止它或者换一个端口。还有-d 参数表示后台运行,注意-d 并不影响容器的运行时间,只是将其放到了后台,换句话说,如果你的容器本身没有运行不退出的进程,即使加了-d 容器依然会自动退出。

同样你可以将其推送到 DockerHub,或者仅仅将你的 Dockerfile 分享给他人就可使用。另外,你可以将 Dockerfile 与你的代码一同上传 github 或其他系统,更方便你的应用环境搭建,也可以进行docker 的版本管理。甚至,你还可以设置Docker Hub结合Github自动化构建镜像

接下介绍常用的 Dockerfile 命令。

  1. FROM 命令

FROM为指定基础镜像,像之前我们基于官方 nginx 进行定制,这样可以省略大量的重复工作。DockerHub 上有大量的镜像,ubuntu、mysql、php、python 等等,一定要选择合适的作为基础镜像,比如开发 django 就选用 python 或者django 镜像,而不要去用 php 镜像。

2. RUN 命令

RUN 命令即用来在容器中执行命令的,相当于你之前手动在 docker 里面执行命令。

其格式也很简单,RUN <command>即可,command可以是容器能执行的任何命令。

这里说下本人的经验,RUN 命令不一定能成功执行,你不必一遍遍更改然后 build 实验,可以直接 run 一个基础镜像,然后去执行命令,等成功了再写入 Dockerfile,会方便很多。

另外,之前说过,每条命令会构建一层,所以不要写太多层 RUN,也不要只有一层,单独的功能模块组合到一层,更利于快速构建以及复用。比如下面这个例子:

FROM php:7.1.22-fpm

# Install PHP and composer dependencies
RUN apt-get update \
    && apt-get install -qq git curl libmcrypt-dev libjpeg-dev libpng-dev libfreetype6-dev libbz2-dev \
    && RUN apt-get clean

# Install needed extensions
RUN docker-php-ext-install pdo pdo_mysql mcrypt zip gd

3. COPY 命令

COPY 命令用于将文件拷贝到镜像中。

COPY <源路径> <目标路径>

你可以将需要的文件拷贝到镜像内,注意这里源路径是相对路径,即相对上文构建命令里的最后一个参数所指定的目录(上文例子为`.`),不能随意引用其它文件。另外,尽量不要在构建目录里放入无关文件,因为 docker 会将目录下所有文件打包发送给服务进程,如图所示

4. CMD命令

CMD 命令为容器启动时的默认命令,因为容器其实本质是一个进程(后面会细讲)。比如 ubuntu 镜像默认CMD 命令为/bin/bash,因此事实上我们只要执行 docker run -it ubuntu就可以得到一个交互式 shell。如果我们传入其它命令,比如 执行 docker run ubuntu uname,容器就会执行我们指定的命令。

以上就是最常用的Dockerfile 命令,建议大家自己尝试构建一个,会有更深的体会。另外还有很多命令以及细节,可以参考这篇文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值