Dockerfile语法及构建源码安装apache镜像

基本结构

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

Docker 通过读取Dockerfile 中的指令自动生成镜像。并且支持以 # 开头的注释行。

Docker分为四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操作指令
  • 容器启动时默认要执行的指令

指令

FROM

FROM : Dockerfile中第一条指令必须是FROM指令,表示从哪个基础镜像开始构建镜像

FROM centos:7	//基于centos7基础镜像构建新的镜像
FROM scratch	//表示不以任何镜像为基础

MAINTAINER

MAINTAINER : 镜像维护者个人信息,维护者的姓名和邮箱

MAINTAINER "xxxx <***@163.com\>"	//维护者姓名和邮箱

RUN

RUN : 构建镜像时需要执行的命令,有两种命令执行方式

shell形式执行
格式:
    RUN <command>	//RUN后边直接跟shell命令,linux操作系统上默认shell为/bin/sh -c
    
exec形式执行
格式:
    RUN ["executable", "param1", "param2"]	//执行可执行文件,executable为可执行文件,param为选项或参数;exec形式可以指定使用其他终端

两种形式对比:
    RUN echo "123"
    RUN ["/bin/bash", "-c", "echo hello"]

注:多行命令不要写多个RUN,Dockerfile中每一个RUN指令都会建立一层镜像,多少个RUN就构建了多少层镜像,会造成镜像的臃肿、多层,不仅仅增加了构件部署的时间,还容易出错。

ADD

ADD :该命令将复制指定的到容器中的。其中可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL(类似wget);还可以是一个tar文件(会自动解压为目录)。

ADD <src>... <dest>
    ADD ["<src>",... "<dest>"]	//用于支持包含空格的路径
示例:
    ADD test /tmp/    		//添加"test"文件到镜像的"/tmp"目录
    ADD abc* /mydir/		//添加所有以"abc"开头的文件到镜像的"/mydir"目录

COPY

格式为COPY 。

复制本地主机的(为Dockerfile所在目录的相对路径,文件或目录)为容器中的。目标路径不存在时会自动创建。
当使用本地目录为源目录时,推荐使用COPY。

CMD

CMD : 指定镜像启动为容器后默认执行的命令,每个 Dockerfile 只能有一条 CMD 命令;如果指定了多条命令,只有最后一条会被执行,如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令

格式:
    CMD ["executable","param1","param2"]	//执行可执行文件,此方式优先
    CMD command param1 param2 			//执行shell内部命令
    CMD ["param1","param2"]			//设置了ENTRYPOINT,则为ENTRYPOINT添加参数

示例:
    CMD ["echo","This is a 1"]
    CMD echo "This is a 1"

ENTRYPOINT

ENTRYPOINT : 类似于 CMD 指令,但其不会被创建容器时指定的命令覆盖,如果创建容器时指定了命令那么这些命令会被当作参数送给 ENTRYPOINT 指令指定的程序;CMD 和ENTRYPOINT 同在时 CMD 的内容会被当作参数传递给 ENTRYPOINT 指定的命令。

格式:
    ENTRYPOINT ["executable", "param1", "param2"] 	//执行可执行文件, 此方式优先
    ENTRYPOINT command param1 param2 			//shell内部命令

ENV

ENV :设置环境变量。此环境变量为镜像启动为容器之后容器中的环境变量

格式:
    ENV <key> <value>		//<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
    ENV <key>=<value> ...	//可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示

EXPOSE

EXPOSE :指定镜像启动为容器后开放的端口

格式:
    EXPOSE <port> [<port>...]

示例:
    EXPOSE 80 443
    EXPOSE 8080
    EXPOSE 222/tcp 111/udp

注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口

WORKDIR

WORKDIR :工作目录,类似于cd命令 可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。

格式:
    WORKDIR /path/to/workdir

示例:
   
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd   //最终路径为/a/b/c。

注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。

USER

USER :指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

 格式:
  USER user
  USER user:group
  USER uid
  USER uid:gid

 示例:
  USER www

 注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。

ARG

ARG :在构建镜像时设置变量,此变量只在Dockerfile中有效

格式:
    ARG <name>[=<default value>]

示例:
    ARG dir="/var/www/html"
    RUN mkdir $dir

VOLUME

VOLUME :创建镜像时指定挂载点,一旦此镜像被启动为容器,则自动为该容器挂载匿名卷

格式:
    VOLUME ["/path/to/dir"]

示例:
    VOLUME ["/data"]
    VOLUME ["/var/www","/var/log/apache2","/etc/apache2"]

ONBUILD

ONBUILD :用于设置镜像触发器,当有其他镜像以此镜像为基础镜像时自动调用 ONBUILD 指定的命令

格式:
  ONBUILD [INSTRUCTION]

示例:
    ADD test /tmp/
    ONBUILD ADD test /tmp/	//ONBUILD用于基础镜像中

HEALTHCHECK

HEALTHCHECK :镜像启动为容器后健康状况检查命令

格式:
    HEALTHCHECK [OPTIONS] CMD command	//在容器内部运行一个命令来检查容器的健康状况
    HEALTHCHECK NONE			//如果基础镜像有健康检查指令,使用此指令可以屏蔽掉其健康检查指令

选项
    --interval=<间隔>	//两次健康检查的间隔,默认为 30 秒
    --timeout=<时长>	//健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒
    --retries=<次数>	//当连续失败指定次数后,则将容器状态视为 unhealthy,默认 3 次

示例:
    HEALTHCHECK --interval=4m --timeout=3s CMD curl http://localhost || exit 1

创建镜像

编写完成Dockerfile后,可以通过docker build命令来创建镜像。

基本的格式为docker build [选项] 路径,该命令将读取指定路径下(包括子目录)的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录为空目录。

另外,可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让Docker忽略路径下的目录和文件。

要指定镜像的标签信息,可以通过-t选项。

格式:
    docker build  -t 镜像名:镜像标签 -f Dockerfile文件名 .

选项:
    -t		//指定通过Dockerfile文件构建的镜像名称和标签
    -f		//指定Dockerfile文件名

案例:构建apache镜像

结构

[root@localhost ~]# tree apache/
apache/
├── Dockerfile
└── package
    ├── apr-1.7.0.tar.bz2
    ├── apr-util-1.6.1.tar.gz
    └── httpd-2.4.49.tar.gz
[root@localhost ~]# vim apache/Dockerfile 
[root@localhost ~]# cat apache/Dockerfile 
#基础镜像
FROM centos
#作者信息
LABEL MAINTAINER='lxx'
#变量
ENV APR_VERSION 1.7.0 
ENV APR_UTIL_VERSION 1.6.1
ENV APACHE_VERSION 2.4.49
#上传本机上的apache压缩包,会自动解压
ADD  package/* /usr/src/
#切换当前工作目录
WORKDIR /usr/src/
#执行命令进行安装操作
RUN yum -y install openssl-devel pcre-devel pcre  expat-devel libtool gcc gcc-c++ make  && \
    cd  apr-$APR_VERSION   &&   sed -i '/$RM "$cfgfile"/d' configure && \ 
    ./configure --prefix=/usr/local/apr  &&     make && make install  && \ 
    cd ../apr-util-$APR_UTIL_VERSION  && \
    ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr  && \
    make && make install  &&  \
    cd ../httpd-$APACHE_VERSION    &&  \
    ./configure --prefix=/usr/local/apache \
    --enable-so \
    --enable-ssl \
    --enable-cgi \
    --enable-rewrite \
    --with-zlib \
    --with-pcre \
    --with-apr=/usr/local/apr \
    --with-apr-util=/usr/local/apr-util/ \
    --enable-modules=most \
    --enable-mpms-shared=all \
    --with-mpm=prefork   && \
    make && make install
#暴露容器端口
EXPOSE 80 443
#前台运行
CMD  ["/usr/local/apache/bin/apachectl","-D","FOREGROUND"] 

//构建镜像
[root@localhost ~]# docker build -t luohengjie/1-apachev1.0:1.1 apache/
Sending build context to Docker daemon  10.85MB
Step 1/10 : FROM centos
 ---> 5d0da3dc9764
Step 2/10 : LABEL MAINTAINER='lxx'
 ---> Running in 50004c6596c5
Removing intermediate container 50004c6596c5
 ---> 46c3bee9edd2
Step 3/10 : ENV APR_VERSION 1.7.0
 ---> Running in d9872b308a6f
Removing intermediate container d9872b308a6f
 ---> 4c7ba82a3b32
Step 4/10 : ENV APR_UTIL_VERSION 1.6.1
 ---> Running in 1ed93ba35462
Removing intermediate container 1ed93ba35462
 ---> 7e9dd1372b74
Step 5/10 : ENV APACHE_VERSION 2.4.49
 ---> Running in 5074f7bbe594
Removing intermediate container 5074f7bbe594
 ---> 1001f044dcf1
Step 6/10 : ADD  package/* /usr/src/
 ---> 15d252f5c865
Step 7/10 : WORKDIR /usr/src/
 ---> Running in dd1f24967d08
Removing intermediate container dd1f24967d08
 ---> af1e52197f3a
Step 8/10 : RUN yum -y install openssl-devel pcre-devel pcre  expat-devel libtool gcc gcc-c++ make  &&     cd  apr-$APR_VERSION   &&   sed -i '/$RM "$cfgfile"/d' configure &&     ./configure --prefix=/usr/local/apr  &&     make && make install  &&     cd ../apr-util-$APR_UTIL_VERSION  &&     ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr  &&     make && make install  &&      cd ../httpd-$APACHE_VERSION    &&      ./configure --prefix=/usr/local/apache     --enable-so     --enable-ssl     --enable-cgi     --enable-rewrite     --with-zlib     --with-pcre     --with-apr=/usr/local/apr     --with-apr-util=/usr/local/apr-util/     --enable-modules=most     --enable-mpms-shared=all     --with-mpm=prefork   &&     make && make install
 ---> Running in ec6e8df69eac
....略
make[1]: Leaving directory '/usr/src/httpd-2.4.49'
Removing intermediate container ec6e8df69eac
 ---> c2fc0e72c939
Step 9/10 : EXPOSE 80 443
 ---> Running in 44af7d86c3be
Removing intermediate container 44af7d86c3be
 ---> f3c31ff60c5c
Step 10/10 : CMD  ["/usr/local/apache/bin/apachectl","-D","FOREGROUND"]
 ---> Running in 639d579e5b09
Removing intermediate container 639d579e5b09
 ---> 0adc40110aa7
Successfully built 0adc40110aa7
Successfully tagged luohengjie/1-apachev1.0:1.1

//查看镜像
[root@localhost ~]# docker images
REPOSITORY                TAG       IMAGE ID       CREATED          SIZE
luohengjie/1-apachev1.0   1.1       0adc40110aa7   11 minutes ago   702MB
httpd                     v1.0      3471d3329f64   46 hours ago     721MB
luohengjie/nginx          v1.20.1   57f37b97be37   5 days ago       550MB
nginx                     latest    f652ca386ed1   6 days ago       141MB
centos                    latest    5d0da3dc9764   2 months ago     231MB
//启动容器测试
[root@localhost ~]# docker run -it --name test -p 80:80 luohengjie/1-apachev1.0:1.1 
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message

猜你喜欢

转载自blog.csdn.net/weixin_46115601/article/details/121803803