一、什么是Dockerfile

1)Dockerfile是一个用来构建镜像的文本文件,文本内容包含一条条构建镜像所需的指令和说明。

2)Docker通过读取Dockerfile中的指令自动生成镜像。

3)Docker里的镜像绝大部分都是在别的镜像的基础上去进行创建的,也就是使用镜像的分层结构。

4)Docker镜像由只读层组成,运行的容器会在Docker的镜像上面多加一层可写的容器层。任何对文件的更改都只存在容器层。因此任何对容器的操作不会影响到镜像。

二、Dockerfile基本结构

Dockerfile 一般分为四部分

1)基础镜像信息            (必须参数)

                在dockerfile种使用   #作为注释    第一行必须指定基础镜像

                例如:

                     FROM nginx

    2)维护者信息               (可选参数)

                例如:

                      MAINTAINET  xx@xx.com

    3)镜像操作指令           (重要参数)

                操作指令包含: 包括ADD、ENV、EXPOSE等

                例如:

                    RUN  apk  add  curl

    4)容器启动执行命令 (重要参数)

例如:CMD ["nginx", "-g", "daemon off;"]

如下示例

FROM docker.io/centos
LABEL "auth"=“xx" \
      "mail"=“xx@xx.com"
ENV TIME_ZOME Asia/Shanghai
RUN yum install -y gcc gcc-c++ make openssl-devel prce-devel
ADD nginx-1.14.2.tar.gz /opt/
RUN cd /opt/nginx-1.14.2 && \
    ./configure --prefix=/usr/local/nginx && \
    make -j 4 && \
    make install

RUN rm -rf /opt/nginx* && \
    yum clean all && \
    echo "${TIME_ZOME}" > /etc/timezone && \
    ln -sf /usr/share/zoneinfo/${TIME_ZOME} /etc/localtime

COPY nginx.conf /usr/local/nginx/conf/
WORKDIR /usr/local/nginx/
EXPOSE 80
CMD ["./sbin/nginx","-g","daemon off;"]

三、镜像构建工作逻辑

1、在一个自定义的目录下有Dockerfile文件;

命名首字母 必须是 大写 ;

引用的文件必须在 当前的目录及其 以下 目录 ;

如果有些文件不需要被打包,可以将这些文件 放在 当前目录下隐藏文件(.dockeringore)中;

2、在当前目录下执行docker build来进行打包成镜像,Dockerfile中的命令必须是docker支持的命令;
3、基于刚才打包的镜像启动容器;

通过Dockerfile制作成镜像并启动容器的过程如下:

docker打包程序 ubuntu dockerfile打包命令_容器

其中上面提到的CMD指令还有后面介绍的ENTRYPOINT指令都是在docker run的时候执行,其他指令在docker build的时候执行。

四、Dockerfile指令详解

FROM:重要且必须是开篇第一个非注释行,用于为镜像文件构建过程指定基础镜像,后续的指令运行是在此基础上运行。在实践中,基础镜像可以是任何可用镜像文件,默认情况下,docker build 会在docker主机上查找指定的镜像文件,在其不存在时,则会从docker HUB上拉取镜像,如果找不到镜像,则会报错。

MAINTANIER:用于指定Dockerfile制作者本人的信息,目前已经废弃。

LABEL:指定Dockerfile的元数据标签信息,我们可以将MAINTANIER的作者信息写在LABEL标签里。

RUN:用于指定docker build过程中运行的程序,其可以是任何可执行命令。

CMD:类似于RUN命令,CMD指令也可以运行命令或应用程序,RUN指令运行于镜像文件构建过程,CMD运行于docker run的时候;CMD指令的首要目的在于启动容器的时候运行程序,他运行结束后,容器也将终止,不过CMD指令可以被docker run的命令选项所覆盖;在Dockerfile中可以存多个CMD指令,但仅最后一个会生效;

ENTRYPOINT:类似CMD指令功能,用于容器指定默认运行程序,从而使得容器像是一个单独的可执行程序。

与CMD不同的是,由ENTRYPOINT启动程序不会被docker run命令指定的参数覆盖,而且,这些命令参数会被当做参数传递给ENTRYPOINT指定的程序。docker run 命令的 --entrypoint选项的参数可覆盖NETRYPOINT指定的程序。

ADD:    将本地或者远程文件,添加到容器中,tar类型文件会自动解压。

COPY:从docker主机复制文件到镜像中。类似ADD,但是不会自动解压压缩文件。

ENV:用于为镜像定义所需环境变量,并可被dockerfile文件中位于其后的其他指令所调用。

EXPOSE:用于为容器打开指定要监听的端口以实现与外部通信,在docker run的时候,如果没有指定-P参数,是不会暴露在docker主机上的。协议支持TCP或UDP,默认是TCP。EXPOSE指令可以一次指定多个端口。

VOLUME :用于在镜像中创建一个挂载点目录,以挂载docker主机上的卷或者其它容器上的卷。

WORKDIR:指定工作目录,类似于cd命令,每一次只影响当前目录到后的目录。

USER:用于指定运行镜像时的或运行dockerfile中任何RUN,CMD或者ENTRYPOINT指令指定的程序的用户名或UID。

ARG:在build时使用,用于在构建运行时传递变量。

ONBUILD:用于在dockerfile中定义一个触发器。

dockerfile用于build镜像文件,此映像文件亦可作为base image被另一个dockerfile用作FROM指令参数,并以之构建新的映像,在后面的dockerfile中的FROM指令在build过程中被执行时,将会触发创建其base image的dockerfile文件中的ONBUILD指令定义的触发器。

五、Docker镜像打包案例

基础镜像:CentOS7.8.2003+JDK1.8

1)编写dockerfile

1)编写dockerfile
## Set the base image to Centos7 install jdk1.8
FROM                centos:7
MAINTAINER          xx@xx.com

ENV REFRESHED_AT    2020-11-04

COPY  jdk1.8.0_101  /usr/local/jdk1.8

RUN   yum  -y  install  vi   net-tools iproute nc
ENV JAVA_HOME /usr/local/jdk1.8
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH

CMD tail -f /dev/null

2)构建镜像

生成镜像,名称: centos7_jdk8
# docker build -t centos7_jdk8 .
# docker images | grep centos
3)测试镜像
# docker run -it centos7_jdk8 /bin/bash
4)导入导出镜像
# docker save centos7_jdk8 -o centos7_jdk8.tar 
# docker load -i centos7_jdk8.tar

后端镜像示例

1)镜像Dockerfile

文件名:Dockerfile

FROM centos7_jdk8
MAINTAINER  xx@xx.com

ENV JAVA_OPTS="-server -Xms1g -Xmx2g"
RUN mkdir /gscdp-terminal

ADD gscdp-terminal.jar /gscdp-terminal/gscdp-terminal.jar
ADD conf /gscdp-terminal/conf
ADD start.sh /gscdp-terminal/start.sh
ADD entrypoint.sh /gscdp-terminal/entrypoint.sh
ADD hosts /tmp/

WORKDIR /gscdp-terminal
RUN chmod +x start.sh entrypoint.sh

EXPOSE 8113
ENTRYPOINT cat /tmp/hosts  >>  /etc/hosts; sh /gscdp-terminal/entrypoint.sh 
-d postgre-server-db:5432,nacos-server-gsdss:8848,redis-server-gsdss:6379 -c 'bash /gscdp-terminal/start.sh;'

2)管理服务启动顺序脚本

文件名:entrypoint.sh

3)服务启动脚本

文件名:start.sh
#!/bin/bash
java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar gscdp-terminal.jar  
--spring.config.location=conf/bootstrap.properties --logging.config=conf/logback.xml
4)hosts文件
文件名:hosts
5)服务配置文件
文件名:bootstrap.properties  logback.xml

前端镜像示例

1)Dockerfile文件

文件名:Dockerfile

FROM nginx:1.18

RUN mkdir /home/gscdp-web
ADD gscdp-terminal-web.tar.gz /home/gscdp-web
ADD entrypoint.sh /home/gscdp-web/entrypoint.sh

ADD mis_8990.conf /etc/nginx/conf.d/mis_8990.conf
ADD hosts /tmp/hosts

EXPOSE 8990
WORKDIR /home/gscdp-web
ENTRYPOINT ["sh","entrypoint.sh"]

2)服务启动脚本

文件名:entrypoint.sh

3)hosts文件

文件名:hosts

4)nginx配置文件

文件名:mis_8990.conf

Docker镜像构建案例DoDocker镜像构建案例cker镜像构建案例DDocker镜像构建案例ocker镜像