一、通过docker commit命令构建镜像

  docker commit 构建镜像可以想象为是将运行的镜像进行重命名另存一份。我们先创建一个容器,并在容器里做出修改,就像修改代码一样,最后再将修改提交为一个镜像。

# docker run -i -t ubuntu /bin/bash
root@b437ffe4d630:/# apt-get -yqq update
root@b437ffe4d630:/# apt-get -y install apache2

  以上的操作我们启动了一个容器,并在里面安装了Apache。我们会将这个容器作为一个Web服务器来运行,所以我们想把它的当前状态保存下来。这样我们就不必每次都创建一个新容器并再次在里面安装Apache了。为了完成此项工作,需要先使用exit命令从容器里退出,通过docker ps -a命令查询待保存docker的CONTAUBER ID,之后再运行docker commit命令:

# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b437ffe4d630 ubuntu "/bin/bash" minutes ago Exited () seconds ago clever_pare
b87f9dde62b0 devopsil/puppet "/bin/bash" days ago Up days evil_archimedes # docker commit b437ffe4d630 test/apache2
9c30616364f44a519571709690e3c92a5cad4ad01c007d8126eb6d63670d33f4 # docker images test/apache2
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test/apache2 latest 9c30616364f4 seconds ago 254.4 MB

  在使用docker commit命令中,指定了要提交的修改过的容器的ID(可以通过docker ps命令得到刚创建的容器ID),以及一个目标镜像仓库和镜像名,这里是test/apahce2。需要注意的是,docker commit提交的只是创建容器的镜像与容器的当前状态之间有差异的部分,这使得该更新非常轻量。通过docker images 可以查看新创建的镜像信息。也可以在提交镜像时指定更多的数据(包括标签)来详细描述所做的修改。

# docker commit -m="A new custom image" --author="Bourbon Tian" b437ffe4d630 test/apache2:webserver
27fc508c41d1180b1a421380d755cf00f9dfb6b0d354b9eccaec94ae58a06675

  这条命令里,我们指定了更多的信息选项:

  • -m 用来指定创建镜像的提交信息;
  • --author 用来列出该镜像的作者信息;
  • 最后在test/apache2后面增加了一个webserver标签。

  通过使用docker inspect命令来查看新创建的镜像的详细信息:

# docker inspect test/apache2:webserver
[
{
"Id": "27fc508c41d1180b1a421380d755cf00f9dfb6b0d354b9eccaec94ae58a06675",
"Parent": "f5bb94a8fac47aaf15fb4e4ceb138d59ac2fcf004cd3f277cebe2174fd7a6c70",
"Comment": "A new custom image",
"Created": "2017-05-17T07:29:46.000512241Z",
"Container": "b437ffe4d63047dd34653f5256bb6eda54acfd3db99f72f2262a9b9af7f31334",
...

  如果想从刚创建的镜像运行一个容器,可以使用docker run命令:

# docker run -t -i test/apache2:webserver /bin/bash

二、通过docker build命令和 Dockerfile 文件创建docker镜像

  Dockerfile使用基本的基于DSL语法的指令来构建一个Docker镜像,之后使用docker build命令基于该Dockerfile中的指令构建一个新的镜像。

# mkdir /opt/static_web
# cd /opt/static_web/
# vim Dockerfile

  首先创建一个名为static_web的目录用来保存Dockerfile,这个目录就是我们的构建环境(build environment),Docker则称此环境为上下文(context)或者构建上下文(build context)。Docker会在构建镜像时将构建上下文和该上下文中的文件和目录上传到Docker守护进程。这样Docker守护进程就能直接访问你想在镜像中存储的任何代码、文件或者其他数据。这里我们还创建了一个Dockerfile文件,我们将用它构建一个能作为Web服务器的Docker镜像。

# Version: 0.0.
FROM ubuntu:latest #Docker从基础镜像运行一个容器。
MAINTAINER Bourbon Tian "bourbon@1mcloud.com" #设置镜像信息。
RUN apt-get update  #更新
RUN apt-get install -y nginx #安装nginx
RUN echo 'Hi, I am in your container' > /usr/share/nginx/html/index.html #修改文件
EXPOSE 80 #指定80端口开放

  Dockerfile由一系列指令和参数组成。每条指令都必须为大写字母,切后面要跟随一个参数。Dockerfile中的指令会按照顺序从上到下执行,所以应该根据需要合理安排指令的顺序。每条指令都会创建一个新的镜像层并对镜像进行提交。Docker大体上按照如下流程执行Dockerfile中的指令。

从上面可以看出,如果你的Dockerfile由于某些原因(如某条指令失败了)没有正常结束,那你也可以得到一个可以使用的镜像。这对调试非常有帮助:可以基于该镜像运行一个具备交互功能的容器,使用最后创建的镜像对为什么你的指令会失败进行调试。

Dockerfile也支持注释。以#开头的行都会被认为是注释,# Version: 0.0.1这就是个注释

  FROM:

  每个Dockerfile的第一条指令都应该是FROM。FROM指令指定一个已经存在的镜像,后续指令都是将基于该镜像进行,这个镜像被称为基础镜像(base iamge)。在这里ubuntu:latest就是作为新镜像的基础镜像。也就是说Dockerfile构建的新镜像将以ubuntu:latest操作系统为基础。在运行一个容器时,必须要指明是基于哪个基础镜像在进行构建。

  MAINTAINER:

  MAINTAINER指令,这条指令会告诉Docker该镜像的作者是谁,以及作者的邮箱地址。这有助于表示镜像的所有者和联系方式

  RUN:

  在这些命令之后,我们指定了三条RUN指令。RUN指令会在当前镜像中运行指定的命令。这里我们通过RUN指令更新了APT仓库,安装nginx包,并创建了一个index.html文件。像前面说的那样,每条RUN指令都会创建一个新的镜像层,如果该指令执行成功,就会将此镜像层提交,之后继续执行Dockerfile中的下一个指令。

  EXPOSE:

  EXPOSE指令是告诉Docker该容器内的应用程序将会使用容器的指定端口。这并不意味着可以自动访问任意容器运行中服务的端口。出于安全的原因,Docker并不会自动打开该端口,而是需要你在使用docker run运行容器时来指定需要打开哪些端口。

  执行docker build命令时,Dockerfile中的所有指令都会被执行并且提交,并且在该命令成功结束后返回一个新镜像。

# cd static_web
# docker build -t="test/static_web" .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
...
Successfully built 94728651ce15

  上面命令中最后的“.”告诉Docker到当前目录中去找Dockerfile文件。也可以指定一个Git仓库地址来指定Dockerfile的位置,这里Docker假设在Git仓库的根目录下存在Dockerfile文件:

# docker build -t="test/static_web:v1" git@github.com:test/static_web

  构建出错:

# docker build -t="test/static_web" .
Sending build context to Docker daemon 2.048 kB
Sending build context to Docker daemon
Step : FROM ubuntu:latest
---> f5bb94a8fac4
Step : MAINTAINER Bourbon Tian "bourbon@1mcloud.com"
---> Using cache
---> ce64f2e75a74
Step : RUN apt-get update
---> Using cache
---> e98d2c152d1d
Step : RUN apt-get install -y ngin
---> Running in 2f16c5f11250
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package ngin
The command '/bin/sh -c apt-get install -y ngin' returned a non-zero code:

  在构建镜像时,由于RUN语句错误或者其他错误导致构建失败时,可以我们需要调试一下这次失败,我们可以通过docker run命令来基于这次构建到目前为止已经成功的最后一步创建一个容器,这里它的ID是e98d2c152d1d:

# docker run -t -i e98d2c152d1d /bin/bash
root@55aee4322f77:/# apt-get install -y ngin
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package ngin

构建docker镜像的更多相关文章

  1. 多阶段构建Docker镜像

    在Docker 17.05及更高的版本中支持支持一种全新的构建镜像模式:多阶段构建: 多阶段构建Docker镜像的最大好处是使构建出来的镜像变得更小: 目前常见的两个构建镜像的方式为: 1.直接使用某 ...

  2. 使用Jenkins pipeline流水线构建docker镜像和发布

    新建一个pipeline job 选择Pipeline任务,然后进入配置页面. 对于Pipeline, Definition选择 "Pipeline script from SCM" ...

  3. Docker:使用Jenkins构建Docker镜像

    Docker  彭东稳  1年前 (2016-12-27)  10709次浏览  已收录  0个评论 一.介绍Jenkins Jenkins是一个开源项目,提供了一种易于使用的持续集成系统,使开发者从 ...

  4. 打包应用和构建Docker镜像(docker在windows上)

    在构建Docker时编译应用 一般有两种方法在构建镜像时进行打包应用.第一种方法就是使用基本的镜像,该镜像包括应用平台和构建工具,因此在Dockerfile中,复制源代码到镜像中并在构建镜像时编译ap ...

  5. 构建Docker镜像两种方式的比较-Dockerfile方式和S2I方式

    前言 写Dockerfile是构建Docker镜像最通常的方式,接触过Docker的童鞋多少了解一些.前段时间研究OpenShift(paas的一种),发现了另外一种构建Docker镜像的方式:S2I ...

  6. 使用docker Maven插件本地构建docker镜像并发布到远程服务器

    1.登录网站https://start.spring.io/,生成一个基本的SpringBoot应用. 2.将应用导入Eclipse IDE并创建Application类.目录结构如下: Applic ...

  7. Maven插件构建Docker镜像

    背景 微服务架构下,微服务在带来良好的设计和架构理念的同时,也带来了运维上的额外复杂性,尤其是在服务部署和服务监控上.单体应用是集中式的,就一个单体跑在一起,部署和管理的时候非常简单,而微服务是一个网 ...

  8. [转] 构建Docker镜像两种方式的比较-Dockerfile方式和S2I方式

    原文地址:https://www.cnblogs.com/tianshifu/p/8127837.html 前言 写Dockerfile是构建Docker镜像最通常的方式,接触过Docker的童鞋多少 ...

  9. 使用Buildpacks高效构建Docker镜像

    1. 前言 Spring Boot 2.3.0.RELEASE 正式发布了几天了,其中有个新的特性:可以将Spring Boot应用代码直接打包为Docker镜像.这是什么科技?我赶紧去官网查了一番才 ...

  10. SpringBoot 构建 Docker 镜像的 3 种方式

    本文将介绍3种技术,通过 Maven 把 SpringBoot 应用构建成 Docker 镜像. (1)使用 spring-boot-maven-plugin 内置的 build-image. (2) ...

随机推荐

  1. ffmpeg码率控制

    一.VBR与CBR的含义和区别 VBR是动态码率.CBR是静态码率. VBR(Variable Bitrate)动态比特率.也就是没有固定的比特率,压缩软件在压缩时根据音频数据即时确定使用什么比特率, ...

  2. SDL_AudioSpec(转)

    转贴地址:http://www.cnblogs.com/nanguabing/archive/2012/04/12/2444084.html ============================= ...

  3. EasyGui

    EasyGui 在IDLE上运行EasyGui可能存在冲突 EasyGui是运行在Tkinter上并哟拥有自身的事件循环,而IDLE也是Tkinter写的一个应用程序并页拥有自身的事件循环.两者同时运 ...

  4. printf("%f\n", 3);输出结果为什么是0.000000(转载)

    printf不会关心你输入的参数的类型,你输入的实际是 printf("%f",3),但是这个整型3不会被隐式类型转换为浮点型,而是被直接按内存内容当作浮点型 也就是说,内部使用等 ...

  5. Coins and Queries(codeforce 1003D)

    Polycarp has nn coins, the value of the i-th coin is aiai . It is guaranteed that all the values are ...

  6. linux上的第一个c语言程序

    1.编辑源文件 输入命令如下: root@ubuntu:/home/amy# vi hello.c 文件内容如下: #include<stdio.h> int main() { print ...

  7. ubuntu apt-get用法

    如何在ubuntu下面直接查找想要安装的软件?比如我想安装tomcat,但是我又不知道ubuntu里面有哪些版本,也不知道都需要装什么,但是我能确认我装的是tomcat,那么我就可以用搜索命令:例如: ...

  8. 【原创】4. MYSQL++ 之 SQLTypeAdapter类型、SQLQueryParms类型 与 SQLBuffer

    1. mysqlpp::SQLBuffer 该类型其实就是SQLTypeAdapter传入的各种类型(int, string, double, long, String, …) 的包装,包装的结果就是 ...

  9. CentOS7 启动docker.service失败(code=exited, status=1/FAILURE)

    启动报错 Job for docker.service failed because the control process exited with error code. See "sys ...

  10. 自定义的parse_url逆向函数http_build_url,将数组转为url字符串

    parse_url函数可以讲一个url字符串解析成一个数组,但是php中似乎没有parse_url的逆向函数来讲一个解析出来的数组组合成url字符串,只有一个http_build_query用来将数组 ...