docker之dockerfile

1. dockerfile 是什么 ?

1. 定义

​ dockerfile 是用来构建 Docker 镜像的构建文件,是由一系列命令和参数构成的脚本

2. 文件实例

以 centos 为例

FROM scratch
ADD centos-8-container.tar.xz /

LABEL org.label-schema.schema-version="1.0" \
    org.label-schema.name="CentOS Base Image" \
    org.label-schema.vendor="CentOS" \
    org.label-schema.license="GPLv2" \
    org.label-schema.build-date="20190927"

CMD ["/bin/bash"]

3. dockerfile、Docker 镜像和 Docker 容器的关系

从应用软件的角度来看,Dockerfile、Docker 镜像、Docker 容器分别代表软件开发的三个阶段

  • Dockerfile 是软件的原材料,包括执行代码、文件、环境变量、依赖包、运行时环境等,面向开发
  • Docker 镜像是软件的交付品,由 dockerfile 文件运行 docker build 指令生成,成为交付标准
  • Docker 容器可以认为是软件的运行态,当运行 Docker 镜像时,真正开始提供服务,涉及运维和部署

三者缺一不可,合力充当 Docker 体系的基石

2. dockerfile 基础知识

1. dockerfile 语法

  1. 每条保留字指令都必须为大写字母且后面至少跟随一个参数
  2. 指令按照从上到下,顺序执行
  3. # 表示注释
  4. 每条指令都会创建一个新的镜像层,并对镜像进行提交

2. dockerfile 执行流程

  1. docker 从基础镜像运行一个容器
  2. 执行一条指令并对容器进行修改
  3. 执行类似 docker commit 的操作提交一个新的镜像层
  4. docker 再基于刚提交的镜像运行一个新容器
  5. 执行 dockerfile 中的下一条指令直到所有指令偶执行完成

3. dockerfile 保留字指令

保留字指令 作用 备注
FROM 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 作者+作者邮箱
RUN 镜像构建时需要运行的命令
EXPOSE 当前容器对外暴露的端口
WORKDIR 指定创建容器后,终端默认登陆时进入的工作目录
ENV 构建镜像中设置环境变量
ADD 将宿主机目录下的文件拷贝进镜像 会自动处理URL和解压tar
COPY 将宿主机目录下的文件拷贝进镜像 不会自动处理URL,也不解压tar
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令 存在多个CMD指令,只生效最后一个,docker run 之后的参数会覆盖原来参数
ENTRYPOINT 指定一个容器启动时要运行的命令 存在多个ENTRYPOINT指令,只生效最后一个,docker run 之后的参数会追加到原来参数列表中
ONBUILD 当父镜像被子镜像继承时,父镜像的ONBUILD被触发

4. dockerfile 使用案例

1. 自定义 centos 镜像

  1. 默认 centos 镜像情况

    1. 运行该镜像默认进入 / 目录
    2. 不支持 vim
    3. 不支持 ifconfig
  2. 编写自己的 dockerfile 文件

    # 当前镜像基于 centos 镜像
    FROM centos
    
    # 作者+邮箱
    MAINTAINER lyy<[email protected]>
    
    # 设置环境变量
    ENV MYPATH /tmp
    
    # 设置镜像运行落脚点
    WORKDIR $MYPATH
    
    # 运行yum命令安装vim
    RUN yum -y install vim
    
    # 运行yum命令安装net-tools
    RUN yum -y install net-tools
    
    # 向外暴露80端口
    EXPOSE 80
    
    # 指定容器启动时运行的命令
    CMD /bin/bash
    
  3. 运行构建命令

    # 将 /mydocker/dockerFile 文件构建成名为 mycentos 版本号为 1.3 的镜像
    docker build -f /mydocker/dockerFile -t mycentos:1.3 .
    
  4. 运行构建出的镜像

    docker run -it mycentos:1.3
    

2. CMD 和 ENTRYPOINT 的区别

  1. 共同点

    都是指定一个容器启动时要运行的命令,且只生效最后一个

  2. 区别

    1. 使用 CMD 作为 dockerfile 命令

      1. 编写 dockerFile2

        FROM centos
        RUN yum -y install curl
        CMD ["curl","-s","http://www.baidu.com"]
        
      2. 构建镜像

        docker build -f /mydocker/dockerFile2 -t myip .
        
      3. 运行容器

        docker run myip
        

        curl 命令将 www.baidu.com 的 html 内容显示到控制台

        当给 curl 加上 -i 参数,表示显示内容中加上协议头

        当运行:

        docker run myip -i
        

        报错:

        docker: Error response from daemon: OCI runtime create failed: container_linux.go:346: starting container process caused “exec: “-i”: executable file not found in $PATH”: unknown.

    2. 使用 ENTRYPOINT 作为 dockerfile 命令

      1. 编写 dockerFile3

        FROM centos
        RUN yum -y install curl
        # 将 CMD 替换为 ENTRYPOINT 
        ENTRYPOINT  ["curl","-s","http://www.baidu.com"]
        
      2. 构建镜像

        docker build -f /mydocker/dockerFile3 -t myip2 .
        
      3. 运行容器

        docker run myip2
        

        输出结果与前面包含 CMD 命令的 dockerfile 一致

        当运行:

        docker run myip -i
        

        正确输出协议头和 html 内容

    3. CMD 和 ENTRYPOINT 的区别在于,CMD 将 docker run 后面的参数替换为要执行的参数;而 ENTRYPOINT 将 docker run 后面的参数追加到要执行的命令中

3. 自定义 tomcat9

  1. 编写 dockerfile

    FROM centos
    
    MAINTAINER lyy<[email protected]>
    
    # 将宿主机中的文件c复制到容器中
    COPY c /usr/local/cincontainer
    
    # 解压并拷贝tomcat和jdk
    ADD apache-tomcat-9.0.30.tar.gz /usr/local/
    ADD jdk-8u231-linux-x64.tar.gz /usr/local/
    # 运行yum安装vim
    RUN yum -y install vim
    
    ENV MYPATH /usr/local
    
    WORKDIR $MYPATH
    # 设置环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_231
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.30
    ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.30
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    # 暴露端口8080
    EXPOSE 8080
    # 容器启动时运行 tomcat
    CMD /usr/local/apache-tomcat-9.0.30/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.30/bin/logs/catalina.out
    
  2. 构建镜像

    docker build -f /mydocker/tomcat9/dockerfile -t lyytomcat9 .
    
  3. 运行容器

    docker run -d -p:7777:8080 --name myt9 
    -v /mydocker/tomcat9/test:/usr/local/apache-tomcat-9.0.30/webapps/test 
    -v /mydocker/tomcat9/tomcat9logs:/usr/local/apache-tomcat-9.0.30/logs 
    lyytomcat9
    

    -d:后台运行

    -p:向外映射 7777 端口

    –name:重命名

    -v:添加容器卷

  4. 验证

    curl localhost:7777
    

    正确返回 tomcat 页面信息

    docker exec d67c82132a22 pwd
    

    正确返回容器落脚点

    docker exec d67c82132a22 java -version
    

    正确返回 jdk 版本号

参考资料:尚硅谷周阳 Docker 教程

发布了65 篇原创文章 · 获赞 261 · 访问量 13万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章