构建镜像

构建Docker镜像有两种方式

1.使用 docker commit命令

2.使用docker build命令&Dockerfile文件

一.使用docker commit命令构建镜像

docker commit 容器名称/容器ID  镜像仓库名/镜像名称[:TAG]

-a "作者信息"

-m "提交信息"

步骤:

1.选取一个基础镜像创建一个容器

2.对容器进行相关修改

3.使用docker commit命令提交修改

example:基于ubuntu基础镜像制作包含apache2的镜像

1.运行一个基于ubuntu基础镜像的交互式容器:docker run -i -t ubuntu /bin/bash

2.进入容器中利用apt-get包管理工具安装apache:

apt-get update

apt-get install apache2

exit

3.退出容器后提交

docker commit 

更改容器
提交容器


使用 docker inspect 镜像名  查看详情

可以看到:Parent字段存储了父镜像ubuntu的imageId,container:保存了docker commit 提交时容器的id

二.使用dockerfile构建镜像

对比使用docker commit构建镜像,dockerfile提供了镜像构建的可重复性,透明性,幂等性。

核心步骤:

1.创建Dockerfile文件,在Dockerfile中使用DLS(Domain Specific Language)领域专用语言来定义每一步操作。

2.使用Docker build命令基于Dockerfile中的指令构建一个新的镜像。

后续描述会基于一下形式描述

一些基本概念->镜像构建实例->docker build指令&dockerfile详细语法详解 

1.一些基本概念

构建环境:保存Dockerfile文件的目录,也称构建上下文,在该目录中可以存放在构建镜像中需要使用的代码文件配置文件等,Docker在构建镜像时将上下文和上下文中的目录文件上传至Docker守护进程,这样守护进行就可以直接访问用户想在镜像中存储的任何代码,文件,数据。请为每个需要构建的镜像创建单独的上下文目录。

Dockerfile文件:用来存储如何构建镜像的语句的文件,存储于构建上下文的根目录下。

.dockerignore:在构建上下文的根目录下,如果存在该文件,该文件内容会被按行切割,每行都是一条文件过滤匹配模式,其作用类似于git系统的.gitignore,该文件用来防止构建上下文中不属于构建需要的文件被上传至Docker守护进程

2.一个简单的镜像构建实例

创建上下文环境:nginx_image

创建Dockfile文件

编辑Dockfile并保存

在上下文环境下运行docker build -t "freesnow1992/nginx" .   构建镜像

此时一个可用的镜像就已经构建好了,相关Dockfile指令&docker build命令含义参照下面的说明

三.docker build指令&dockerfile详细语法详解 


Docker build 


构建缓存:

Docker会为Dockerfile中的每一条语句新建一个镜像,每个镜像都是一个可复用模块,后续其他构建流程中可使用已经构建过的镜像层来加速构建流程。

任何事情都有两面

好的一面:构建缓存加速了构建过程,同时也减少了存储,因为Docker使用  “写时复制”  使用同一镜像层构建的新镜像,增加的存储只是本条命令产生的新文件。

坏的一面:对于一些非幂等的语句由于使用了构建缓存导致结果不符合预期,例如:RUN apt-get update 指令,如果使用了构建缓存,此时的更新还是使用构建缓存镜像的更新。为了避免这个情况的发生可以使用--no-cache来强制不使用构建缓存。



Docker build用于通过dockerfile定义的指令来构建镜像

格式:Docker build 额外参数 构建上下文

构建上下文:用于指明构建上下文目录的路径,其可以是git仓库源地址,必须保证dockerfile存在于构建上下文的根目录下

额外参数

-t  仓库/镜像:TAG     用于指定构建后镜像的镜像名&Tag

-no-cache  不使用构建缓存,

查看镜像构建过程&镜像层

docker history 镜像ID



Dockerfile的指令

FROM

形式:FROM  基础镜像名

含义:指定一个构建过程的基础镜像,后续构建过程将基于此镜像展开。所以每个Dockerfile的第一条指令必须是FROM

例子:FROM ubuntu:14.04  制定构建基础镜像为ubuntu 14.04


MAINTAINER

形式:MAINTAINER  作者相关信息

含义:用于说明本次构建镜像的作者信息(作者姓名 联系方式)

例子:MAINTAINER   linghu linghu@example.com


RUN

形式: RUN 命令 参数

            RUN ["命令","参数”,..]

含义:RUN指令会在当前镜像创建的容器中运行制定指令,默认情况下RUN指令会在shell中使用命令包装器/bin/sh -c 来执行

           如果运行的镜像不支持shell平台,或不希望在shell中运行可使用exec格式的RUN指令  RUN ["指令","参数"]

例子:

RUN apt-get update && apt-get install -y nginx  使用shell包装器来执行,apt-get包管理器更新&安装nginx

RUN ["apt-get","update"]    使用exec格式制定指令

RUN ["apt-get","install","-y","nginx"]


EXPORT

形式:EXPORT [端口/协议(默认tcp,可指定tpc/udp):通知Docker容器在运行时侦听指定的端口

含义:EXPOSE 指令实际上并未发布端口。它充当构建镜像的人员和运行容器的人员之间的一种文档类型,有关打算发布哪些端口的信息。要在运行容器时实际发布端口,请在 docker run 上使用 -p 标志来发布和映射一个或多个端口,或使用 -P 标志来发布所有公开的端口并将它们映射为高阶端口。

注意:如果将 -P 和 docker run 一起使用,将公开EXPORT指定的端口,但是-P 在主机上使用临时的高阶主机端口,因此该端口对于                 TCP 和 UDP 将是不同的。论使用哪种 EXPOSE 设置,都可以在运行时使用 -p 标志覆盖它们

例子:

EXPORT  80/tcp


CMD 

形式: CMD ["命令","参数",".."]

            CMD 命令 参数    使用该形式Docker会在指定的命令前加上 /bin/sh -c ,不建议使用

含义: CMD用于指定容器启动时要运行的命令,效果同docker run 中指定的命令

注意:CMD命令可以被docker run 中的命令覆盖

            Dockerfile 中只能存在一条CMD指令,如果存在多条也只有最后一条会被执行

            如果容器想运行多个进程,可以使用类似supervisor的服务管理工具

例子:

CMD ["nginx","-g","daemon off;"]

CMD nginx -g "daemon off;"


ENTRYPOINT

形式:ENTRYPOINT ["命令“,"参数",..]

           ENTRYPOINT 命令 参数    使用该形式Docker会在指定的命令前加上 /bin/sh -c ,不建议使用

含义:ENTRYPOINT用于指定容器启动时要运行的命令,效果同docker run 中指定的命令,但是不会被docker run中的参数覆盖,此时如果docker run 存在指令参数,将被作为ENTRYPOINT 指定的命令的参数 传递进来,如果docker run 中没有指定参数,但此时dockerfile文件中存在CMD指令,则cmd指令的参数将作为ENTRYPOINT指定的命令的参数传递进来

注意:如果要强制覆盖ENTRYPOINT的命令,可使用 docker run --entrypoint 进行覆盖

例子:

Dokerfile文件中相关内容如下

----------------------------------

CMD ["-g","daemon off;"]

ENTRYPOINT ["nginx"]

----------------------------------

docker  run -d -P freesnow1992/nginx :相当于容器启动是的命令为 nginx -g “daemon off;"

docker run -d - P freesnow1992/nginx -h :相当于容器启动时的命令为 nginx -h,此时覆盖了CMD中指定的参数


WORKDIR

形式: WORKDIR 路径名

含义:用来从镜像创建一个新容器时,在容器内部设置一个工作目录,CMD,ENTRYPOINT指定的程序会在这个目录下执。同时可以               使用该指令为Dockerfile中的后续一系列指令设置工作目录

注意:在运行Docker run时可以通过-w参数予以覆盖

例子:

WORKDIR /usr/local 切换当前工作目录为/usr/local


ENV

形式:ENV  变量名   变量值 (只可以设置单个环境变量)

           ENV 变量名1=变量值 变量名2=变量值 

含义:用来在镜像构建过程中设置环境变量。新的环境变量可以在后续的任何RUN指令中使用,同时环境变量也将在后续由该镜像创建的任何容器中生效。

注意:在运行Docker run时 可以通过 -e 来传递环境变量此时只对该容器的运行时有效

例子:

ENV WDPATH = /usr/local

WORKDIR $WDPATH


USER

形式: USER user/uid:group/gid(用户名必须已经存在,可使用镜像中存在的,或在之前使用RUN useradd 进行新增)

含义:用来指定该镜像会以什么样的用户运行,默认会以root用户运行

注意:在运行Docker run 时,可以通过 -u 来更改用户

例子:

USER 0 使用root用户运行容器


VOLUME

形式:VOLUME ["挂载点",...]

含义:用于向基于镜像创建的容器添加卷。

注意:1.卷可以在容器间共享&重用

           2.卷的挂载点会绕过联合文件系统

           3.对卷的修改会立即生效,但不会对更新镜像产生影响

           4.卷会一直存在知道没有任何容器使用它

例子:

VOLUME   ["/opt/test"]


ADD

形式:ADD 构建上下文的文件目录/url地址    镜像中的目的地址

含义:用来将构建上线文中的文件目录复制到镜像中

注意:

           ADD 指令通过目的地址的末尾字符来判定文件源时目录还是文件,如果以/结尾,那么Docker认为源位置指向一个目录,否则认   为指向一个文件

            不能将构建上下文之外的文件进行ADD操作

           如果源文件是归档格式,ADD命令会自动进行unpakc操作

           如果目的路径不存在,ADD会自动进行创建,形如使用了mkdir -p

例子:

ADD     main.go    /usr/local/src/main.go


COPY

形式:ADD 构建上下文的文件目录    镜像中的位置

含义:同ADD命令,但是不会针对归档文件进行unpack操作

例子:

COPY    main.go /usr/local/src/main.go


LABLE

形式:LABEL 键="值"    键="值"

含义:使用LABEL为镜像添加元数据

例子:

LABEL version="1.0"    location="Shanghai"    role="Register Center"


STOPSIGNAL

形式:STOPSIGNAL 信号值/信号名称

含义:用于指定在执行docker stop执行停止容器时,会发给容器的信号,默认情况下会发出SIGTERM,其目的是为了让容器能够优雅的退出,但是如果容器在接受相应指令后(10s)内还是没有停止,此时Docker会帮它退出,此时会发送SIGKILL信号将容器杀死。

例子:

STOPSIGNAL 9

STOPSIGNAL SIGKILL


ARG

形式: ARG  变量名 

         ARG  变量名=默认值

含义:设置构建过程中使用的变量,和ENV不同,其在镜像生成的容器中并不会存在。

特点:1.ARG存在两个作用域,在FROM命令前定义的变量仅对FROM命令有效,对后续命令无效,在FROM后设置的ARG变量对后续命令有效

例子:

ARG base_image  

ARG tag="latest"

FROM ${base_image}:${tag}

Docker build --build-arg base_image=ubuntu

此时效果为

FROM ubuntu:latest


ONBUILD

形式:ONBUILD    Dockerfile内部其他指令

含义:用于为镜像构建创建触发器。当以该镜像作为基础镜像的子镜像在构建时,ONBUILD指令会执行。

特点:ONBUILD指令只能被继承一次,即只会在子镜像中执行,而不会在孙子镜像中执行。ONBUILD常用于创建模版镜像

           ONBUILD内的指令不会在构建本镜像时执行

例子:

创建nginx镜像模版 freesnow1992/nginx_tpl

FROM ubuntu

MAINTAINER linghu "linghu@example.com"

RUN apt-get update && apt-get install -y nginx

RUN rm /usr/share/nginx/html/index.html

ONBUILD ADD /www /usr/share/nginx/html/

EXPOSE 80

LABEL role="nginx server"

CMD ["-g","daemon off;"]

ENTRYPOINT ["nginx"]

在后续以  freesnow1992/nginx_tpl 为基础镜像的子镜像构建过程中,ONBUILD指令会在FROM之后执行

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容