Docker容器技术介绍(七)--- Dockerfile简介

来源:互联网 发布:mac软件分享 编辑:程序博客网 时间:2024/05/29 19:49

Docker 创建镜像有多种方式,比如之前介绍过的docker commit 命令可以把我们在容器中的修改保存并生成一个新的镜像,除此之外,我们还可以编写一个Dockerfile,然后根据这个Dockerfile去构建镜像,而Dockerfile包含了生成这个镜像的基本信息。

一个Dockerfile一般由四部分组成:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令

首先我们来看一个简单的Dockerfile样例:

FROM scratchADD ubuntu-trusty-core-cloudimg-amd64-root.tar.gz /# a few minor docker-specific tweaks# see https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrapRUN set -xe \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L40-L48&& echo '#!/bin/sh' > /usr/sbin/policy-rc.d \&& echo 'exit 101' >> /usr/sbin/policy-rc.d \&& chmod +x /usr/sbin/policy-rc.d \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L54-L56&& dpkg-divert --local --rename --add /sbin/initctl \&& cp -a /usr/sbin/policy-rc.d /sbin/initctl \&& sed -i 's/^exit.*/exit 0/' /sbin/initctl \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L71-L78&& echo 'force-unsafe-io' > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L85-L105&& echo 'DPkg::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' > /etc/apt/apt.conf.d/docker-clean \&& echo 'APT::Update::Post-Invoke { "rm -f /var/cache/apt/archives/*.deb /var/cache/apt/archives/partial/*.deb /var/cache/apt/*.bin || true"; };' >> /etc/apt/apt.conf.d/docker-clean \&& echo 'Dir::Cache::pkgcache ""; Dir::Cache::srcpkgcache "";' >> /etc/apt/apt.conf.d/docker-clean \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L109-L115&& echo 'Acquire::Languages "none";' > /etc/apt/apt.conf.d/docker-no-languages \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L118-L130&& echo 'Acquire::GzipIndexes "true"; Acquire::CompressionTypes::Order:: "gz";' > /etc/apt/apt.conf.d/docker-gzip-indexes \\# https://github.com/docker/docker/blob/9a9fc01af8fb5d98b8eec0740716226fadb3735c/contrib/mkimage/debootstrap#L134-L151&& echo 'Apt::AutoRemove::SuggestsImportant "false";' > /etc/apt/apt.conf.d/docker-autoremove-suggests# delete all the apt list files since they're big and get stale quicklyRUN rm -rf /var/lib/apt/lists/*# this forces "apt-get update" in dependent images, which is also good# enable the universeRUN sed -i 's/^#\s*\(deb.*universe\)$/\1/g' /etc/apt/sources.list# make systemd-detect-virt return "docker"# See: https://github.com/systemd/systemd/blob/aa0c34279ee40bce2f9681b496922dedbadfca19/src/basic/virt.c#L434RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container# overwrite this with 'CMD []' in a dependent DockerfileCMD ["/bin/bash"]


Dockerfile 的注释以 ‘#’ 开头


Dockerfile 的第一句非注释指令是基础镜像信息,用 FROM 关键字指定,比如这里的 FROMscratch 表示该镜像是在 scratch镜像基础上制作的


ADD 关键字可以把宿主机的文件添加到镜像中的指定位置, ADD ubuntu-trusty-core-cloudimg-amd64-root.tar.gz /

表示把宿主机中ubuntu-trusty-core-cloudimg-amd64-root.tar.gz 复制到容器中的 / 目录下


RUN 关键字可以用来运行shell命令,每一个RUN关键字会提交一次(相当于docker commit一次),产生一个层(Layer),所以如果不想有太多的层,应该一个RUN

关键字执行多个命令,比如 

RUN mkdir -p /run/systemd && echo 'docker' > /run/systemd/container
这条RUN命令 执行了 mkdir 和 echo 两个shell命令


CMD 指令指定容器运行时默认执行的命令,当你在启动容器时没有明确指定执行的COMMAND时就会用该CMD



常用指令介绍


1.FROM
指定所创建镜像的基础镜像,如果本地不存在,则默认会去Docker Hub下载指定镜像。
格式为FROM <image>,或FROM <image>:<tag>,或FROM <image>@<digest>。


2.RUN
运行指定命令。
格式为RUN <command>或 RUN ["executable","param1","param2"]。注意,后一个指令会被解析为Json数组,因此必须用

双引号。前者默认将在shell终端中运行命令,即/bin/sh -c;后者则使用exec执行,不会启动shell环境。
指定使用其他终端类型可以通过第二种方式实现,例如RUN ["/bin/bash","-c","echo hello"]。
每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\来换行。


3.CMD
CMD指令用来指定启动容器时默认执行的命令。它支持三种格式:

CMD ["executable","param1","param2"] 使用exec执行,是推荐使用的方式;
CMD command param1 param2 在/bin/sh中执行,提供给需要交互的应用;
CMD ["param1","param2"]提供给ENTRYPOINT的默认参数。
每个Dockerfile只能有一条CMD命令。如果指定了多条命令,只有最后一条会被执行。
如果用户启动容器时手动指定了运行的命令(作为run的参数),则会覆盖掉CMD指定的命令。


4.LABEL
LABEL指令用来指定生成镜像的元数据标签信息。
格式为LABEL<key>=<value><key>=<value><key>=<value>...。
例如:

LABEL maintainer="SvenDowideit@home.org.au"
来指定作者


5.EXPOSE
声明镜像内服务所监听的端口。
格式为EXPOSE <port> [<port>...]。
例如:
EXPOSE 22 80
注意,该指令只是起到声明作用,并不会自动完成端口映射。


6.ENV
指定环境变量,在镜像生成过程中会被后续RUN指令使用,在镜像启动的容器中也会存在。
格式为ENV <key> <value> 或 ENV <key>=<value>...。
例如:

ENV VERSION 14.04


7.ADD
该命令将复制指定的<src>路径下的内容到容器中的<dest>路径下。
格式为ADD <src> <dest>。
其中<src>可以是Dockerfile所在目录的一个相对路径(文件或目录),也可以是一个URL,还可以是

一个tar文件(如果为tar文件,会自动解压到<dest>路径下)。

<dest>可以是镜像内的绝对路径,或者相对于工作目录(WORKDIR)的相对路径。


8.COPY
格式为COPY <src> <dest>。

COPY 命令和ADD 非常类似,只是COPY命令只支持把宿主机的文件拷贝到镜像中,一般这种情况下推荐使用COPY命令。

目标路径不存在时,会自动创建。


9.WORKDIR
为后续的RUN、CMD和ENTRYPOINT指令配置工作目录。
格式为WORKDIR/path/to/workdir。
可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。


完整的指令请查阅:Dockerfile reference


接下来,我们使用 centos:6.9 作为基础镜像,搭建一个Nginx镜像

Dockerfile:

#设置基础镜像FROM centos:6.9#作者信息LABEL maintainer=zhangy@tv189.com#开放端口EXPOSE 80#安装NginxRUN yum makecache && yum install -y --nogpgcheck epel-release && yum install -y --nogpgcheck nginx#关闭Nginx守护进程RUN sed -in '3a daemon off;' /etc/nginx/nginx.conf#启动NginxCMD ["/usr/sbin/nginx", "-c", "/etc/nginx/nginx.conf"]

然后使用docker build 命令来构建镜像

[root@localhost sshd_ubuntu]# docker build --helpUsage: docker build [OPTIONS] PATH | URL | -Build a new image from the source code at PATH  -c, --cpu-shares=0    CPU shares (relative weight)  --cgroup-parent=      Optional parent cgroup for the container  --cpu-period=0        Limit the CPU CFS (Completely Fair Scheduler) period  --cpu-quota=0         Limit the CPU CFS (Completely Fair Scheduler) quota  --cpuset-cpus=        CPUs in which to allow execution (0-3, 0,1)  --cpuset-mems=        MEMs in which to allow execution (0-3, 0,1)  -f, --file=           Name of the Dockerfile (Default is 'PATH/Dockerfile')  --force-rm=false      Always remove intermediate containers  --help=false          Print usage  -m, --memory=         Memory limit  --memory-swap=        Total memory (memory + swap), '-1' to disable swap  --no-cache=false      Do not use cache when building the image  --pull=false          Always attempt to pull a newer version of the image  -q, --quiet=false     Suppress the verbose output generated by the containers  --rm=true             Remove intermediate containers after a successful build  -t, --tag=            Repository name (and optionally a tag) for the image

在Dockerfile所在的目录执行
docker build -t lamp:nginx .

[root@localhost sshd_ubuntu]# lsDockerfile[root@localhost sshd_ubuntu]# docker build -t lnmp:nginx .Sending build context to Docker daemon 2.048 kBSending build context to Docker daemon Step 0 : FROM centos:6.9 ---> e071bce628baStep 1 : LABEL maintainer zhangy@tv189.com ---> Using cache ---> 0d618389ca76Step 2 : EXPOSE 80 ---> Using cache ---> fc6a935299abStep 3 : RUN yum makecache && yum install -y --nogpgcheck epel-release && yum install -y --nogpgcheck nginx ---> Running in 62cacd14c2edLoaded plugins: fastestmirror, ovl............Complete! ---> ad23365869fbRemoving intermediate container 62cacd14c2edStep 4 : RUN sed -in '3a daemon off;' /etc/nginx/nginx.conf ---> Running in b763f003f645 ---> 302402a29363Removing intermediate container b763f003f645Step 5 : CMD /usr/sbin/nginx -c /etc/nginx/nginx.conf ---> Running in b0c755098664 ---> 7befb6b4f77aRemoving intermediate container b0c755098664Successfully built 7befb6b4f77a

看到 Successfully build xxx 表示构建成功,使用docker images 查看

[root@localhost sshd_ubuntu]# docker imagesREPOSITORY            TAG                 IMAGE ID            CREATED             VIRTUAL SIZElnmp                  nginx               7befb6b4f77a        46 seconds ago      948.1 MBnginx                 myself              ffbf82fc975d        3 hours ago         108.3 MBubuntu                sshd2               f5e51900b258        8 hours ago         382.9 MBcentos                6.9                 e071bce628ba        3 weeks ago         194.7 MBphp                   5.6.32-fpm          57a62c38abf7        4 weeks ago         369.2 MBnginx                 latest              2ecc072be0ec        7 weeks ago         108.3 MBubuntu                14.04               b44ce450cb60        10 weeks ago        188 MBquay.io/coreos/etcd   v3.0.4              3b17a5f34e6c        16 months ago       43.3 MB

测试运行该镜像

[root@localhost sshd_ubuntu]# docker run -d -p 8080:80 lnmp:nginxf49435d6ccb956cad18535a3b40fa8c89d1fbd14e6d3e326e175221823d23858[root@localhost sshd_ubuntu]# docker ps --no-truncCONTAINER ID                                                       IMAGE               COMMAND                                      CREATED             STATUS              PORTS                  NAMESf49435d6ccb956cad18535a3b40fa8c89d1fbd14e6d3e326e175221823d23858   lnmp:nginx          "/usr/sbin/nginx -c /etc/nginx/nginx.conf"   14 seconds ago      Up 14 seconds       0.0.0.0:8080->80/tcp   happy_einstein      [root@localhost sshd_ubuntu]# curl '127.0.0.1:8080'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">    <head>        <title>Test Page for the Nginx HTTP Server on EPEL</title>        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />        <style type="text/css">            /*<![CDATA[*/            body {                background-color: #fff;

这样一个基于centos的nginx镜像就构建好了,你可以把该镜像push到Docker Hub上供别人下载使用 :)

That's it!











阅读全文
0 0