美文网首页
Docker实战系列(5)-Dockerfile

Docker实战系列(5)-Dockerfile

作者: Kevin_Luo | 来源:发表于2019-07-31 14:14 被阅读0次

    除了commit 方式 , Dockerfile 是另一种构建镜像的方式。
    Dockerfile 构建镜像是以基础镜像为基础的,Dockerfile 是一个文本文件,内容是用户编写的一些 Docker 指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
    Dockerfile 的基本指令有十三个,分别是:FROMMAINTAINERRUNCMDEXPOSEENVADDCOPYENTRYPOINTVOLUMEUSERWORKDIRONBUILD

    Dockerfile 常用指令

    基础镜像信息:FROM
    维护者信息:MAINTAINER
    镜像操作指令:RUNCOPYADDEXPOSEWORKDIRONBUILDUSERVOLUME
    容器启动时执行指令:CMDENTRYPOINT

    FROM :指定基础镜像

    如:指定 ubuntu 的 14 版本作为基础镜像

    FROM ubuntu:14
    
    RUN:执行命令

    RUN 指令在新镜像内部执行的命令,如:执行某些动作、安装系统软件、配置系统信息之类。

    格式如下两种:
    shell 格式:RUN< command > ,就像直接在命令行中输入的命令一样。 如在 Nginx 里的默认主页中写”hello“:

    RUN echo 'hello ' >/etc/Nginx/html/index.html
    

    exec 格式:RUN ["可执行文件", "参数1", "参数2"] 如在新镜像中用 yum 方式安装 Nginx:

    RUN ["yum","install","Nginx"]
    

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

    COPY:复制文件

    于将宿主机器上的的文件复制到镜像内,如果目的位置不存在,Docker 会自动创建。但宿主机器用要复制的目录必须是和 Dockerfile 文件统计目录下

    COPY [--chown=<user>:<group>] <源路径>... <目标路径>
    COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
    
    COPY package.json /usr/src/app/ #把宿主机的 package.json 复制到容器中 /usr/src/app/ 目录
    
    CMD:容器启动命令

    用于容器启动时需要执行的命令,CMD 在 Dockerfile 中只能出现一次,如果出现多个,那么只有最后一个会有效。
    其作用是在启动容器的时候提供一个默认的命令项。如果用户执行 Docker run 的时候提供了命令项,就会覆盖掉这个命令,没提供就会使用构建时的命令。

    shell 格式:CMD <命令>
    exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
    

    如容器启动时进入 bash:

    CMD /bin/bash
    

    也可以用 exec 写法:

    CMD ["/bin/bash"]
    
    MAINTAINER:指定作者
    MAINTAINER <name> <email>
    
    MAINTAINER kevin abc@126.com
    
    EXPOSE:暴露端口

    EXPOSE 命名适用于设置容器对外映射的容器端口号,如 Tomcat 容器内使用的端口 8081,则用 EXPOSE 命令可以告诉外界该容器的 8081 端口对外,在构建镜像时用 Docker run -p 可以设置暴露的端口对宿主机器端口的映射。

    EXPOSE <端口1> [<端口2>...]
    
    EXPOSE 8081
    

    EXPOSE 8081 其实等价于 Docker run -p 8081 当需要把 8081 端口映射到宿主机中的某个端口(如8888)以便外界访问时,则可以用 Docker run -p 8888:8081。

    WORKDIR:配置工作目录

    WORKDIR 命令是为 RUN、CMD、ENTRYPOINT 指令配置工作目录。其效果类似于 Linux 命名中的 cd 命令,用于目录的切换,但是和 cd 不一样的是:如果切换到的目录不存在,WORKDIR 会为此创建目录。

    WORKDIR path
    
    //如需要在 Nginx 目录下创建一个 hello.txt 的文件:
    
    //进入/usr/local/Nginx目录下 WORKDIR /usr/local/Nginx
    
    //进入/usr/local/Nginx中的html目录下 WORKDIR html
    
    // 在html目录下创建了一个hello.txt文件 RUN echo 'hello' > hello.txt
    
    ENTRYPOINT:容器启动执行命名

    ENTRYPOINT 的作用和用法和 CMD 一模一样,但是 ENTRYPOINT 有和 CMD 有 2 处不一样:

    • CMD 的命令会被 Docker run 的命令覆盖而 ENTRYPOINT 不会;
    • CMD 和 ENTRYPOINT 都存在时,CMD 的指令变成了 ENTRYPOINT 的参数,并且此 CMD 提供的参数会被 Docker run 后面的命令覆盖。
    VOLUME

    VOLUME 用来创建一个可以从本地主机或其他容器挂载的挂载点。例如我们知道 Tomcat 的 Webapps 目录是放 Web 应用程序代码的地方,此时我们要把 Webapps 目录挂载为匿名卷,这样任何写入Webapps 中的心都不会被记录到容器的存储层,让容器存储层无状态化。

     VOLUME ["path"]
    
    VOLUME /usr/local/Tomcat/Webapps # 创建 Tomcat 的 Webapps 目录的一个挂载点
    

    在运行容器时,也可以用过 Docker run -v 来把匿名挂载点挂载都宿主机器上的某个目录,如

    Docker run -d -v /home/Tomcat_Webapps:/usr/local/Tomcat/Webapps
    
    USER

    USER 命令用于指定当前望下执行的用户,需要注意的是这个用户必须是已经存在,否则无法指定。它的用法和 WORKDIR 有点像,切换用户

    USER daemon
    
    ONBUILD

    ONBUILD 用于配置当前所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。
    意思就是:这个镜像创建后,如果其它镜像以这个镜像为基础,会先执行这个镜像的 ONBUILD 命令。

    ONBUILD [INSTRUCTION]
    
    ENV:设置环境变量

    ENV 命名用于设置容器的环境变量,这些变量以 "key=value"的形式存在,在容器内被脚本或者程序调用,容器运行的时候这个变量也会保留。

    ENV \ \  #设置一个
    ENV \=\ \=\... #设置多个
    
    ENV JAVA_HOME /opt/jdk
    ENV PATH $PATH:$JAVA_HOME/bin
    

    注:

    • 具有传递性,也就是当前镜像被用作其它镜像的基础镜像时,新镜像会拥有当前这个基础镜像所有的环境变量
    • ENV 定义的环境变量,可以在 Dockerfile 被后面的所有指令( CMD 除外)中使用,但不能被 Docker run 的命令参数引用 。如:
    ENV Tomcat_home_name Tomcat_7
    RUN mkdir $Tomcat_home_name
    

    除了 ENV 之外,Docker run -e 也可以设置环境变量传入容器内,如:

    Docker run -d Tomcat -e "Tomcat_home_name=Tomcat_7"
    

    这样我们进入容器内部用 ENV 可以看到 Tomcat_home_name 这个环境变量

    编写Dockerfile

    安例:

    #在 centos 上安装 Nginx
    FROM centos
    #标明著作人的名称和邮箱
    MAINTAINER jiabuli 649917837@qq.com
    #测试一下网络环境
    RUN ping -c 1 www.baidu.com
    #安装 Nginx 必要的一些软件
    RUN yum -y install gcc make pcre-devel zlib-devel tar zlib
    #把 Nginx 安装包复制到 /usr/src/ 目录下
    ADD Nginx-1.15.8.tar.gz /usr/src/
    #切换到/usr/src/Nginx-1.15.8编译并且安装Nginx
    RUN cd /usr/src/Nginx-1.15.8 \
        && mkdir /usr/local/Nginx \
        && ./configure --prefix=/usr/local/Nginx && make && make install \
        && ln -s /usr/local/Nginx/sbin/Nginx /usr/local/sbin/ \
        && Nginx
    #删除安装 Nginx 安装目录
    RUN rm -rf /usr/src/Nginx-Nginx-1.15.8
    #对外暴露80端口
    EXPOSE 80
    #启动 Nginx
    CMD ["Nginx", "-g", "daemon off;"]
    

    其实 , 在编写 Dockerfile 来构建镜像时,可以先思考在 Linux 上安装该软件的流程,再用 Dockerfile 提供的指令转化到 Dockerfile 中即可

    用 Dockerfile 构建镜像

    编写完之后需要知道怎么使用 Dockerfile 来构建镜像,下面以构建 Nginx 镜像为例来简要说明构建流程

    • 上传安装包
      首先我们需要把要构建的软件安装包上传到服务器中,我们可以在服务器目录上创建一个专门的文件夹,如:/var/Nginx_build,然后把从 Nginx 官网下载的 Nginx-1.15.8.tar.gz 安装包上传到这个目录里。
    • 编写 Dockerfile
      如何编写 NginxDockerfile 上面已经详细介绍,现在我们只需把编写好的Dockerfile 上传到 /var/Nginx_build 目录下,当然你也可以在服务器上直接编写 Dockerfile,但是要记得一定保证Dockerfile文件和安装包在一个目录下。
    • 运行构建命令构建
      Docker build命令用于使用 Dockerfile 创建镜像。 格式:
    Docker build [OPTIONS] PATH | URL | -
    
    #OPTIONS 有很多指令,下面列举几个常用的:
    --build-arg=[] :设置镜像创建时的变量;
    -f :指定要使用的Dockerfile路径;
    --force-rm :设置镜像过程中删除中间容器;
    --rm :设置镜像成功后删除中间容器;
    --tag, -t: 镜像的名字及标签,通常 name:tag 或者 name 格式。
    
    • 因此我们构建 Nginx 可以用以下命令:
    Docker build -t Nginx:v1.0 .
    
    • 当 Dockerfile 和当前执行命令的目录不在同一个时,我们也可以指定Dockerfile,如
    Docker build -f /var/Nginx_build/Dockerfile .
    

    执行命名之后,会看到控制台逐层输出构建内容,直到输出两个 Successfully 即为构建成功

    相关文章

      网友评论

          本文标题:Docker实战系列(5)-Dockerfile

          本文链接:https://www.haomeiwen.com/subject/ziqorctx.html