• docker05-dockerfile


    1.dockerfile是什么

    Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。可以理解为docker自己的语言编写的脚本。

     

    2.Dockerfile内容基础知识

    1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数

    2:指令按照从上到下,顺序执行

    3:#表示注释

    4:每条指令都会创建一个新的镜像层,并对镜像进行提交

     

    3.redis的dockerfile实例

    https://hub.docker.com/_/redis/

    FROM debian:buster-slim
    
    # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
    RUN groupadd -r -g 999 redis && useradd -r -g redis -u 999 redis
    
    # grab gosu for easy step-down from root
    # https://github.com/tianon/gosu/releases
    ENV GOSU_VERSION 1.12
    RUN set -eux; 
        savedAptMark="$(apt-mark showmanual)"; 
        apt-get update; 
        apt-get install -y --no-install-recommends ca-certificates dirmngr gnupg wget; 
        rm -rf /var/lib/apt/lists/*; 
        dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; 
        wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; 
        wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; 
        export GNUPGHOME="$(mktemp -d)"; 
        gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; 
        gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; 
        gpgconf --kill all; 
        rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; 
        apt-mark auto '.*' > /dev/null; 
        [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; 
        apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; 
        chmod +x /usr/local/bin/gosu; 
        gosu --version; 
        gosu nobody true
    
    ENV REDIS_VERSION 6.0.15
    ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-6.0.15.tar.gz
    ENV REDIS_DOWNLOAD_SHA 4bc295264a95bc94423c162a9eee66135a24a51eefe5f53f18fc9bde5c3a9f74
    
    RUN set -eux; 
        
        savedAptMark="$(apt-mark showmanual)"; 
        apt-get update; 
        apt-get install -y --no-install-recommends 
            ca-certificates 
            wget 
            
            dpkg-dev 
            gcc 
            libc6-dev 
            libssl-dev 
            make 
        ; 
        rm -rf /var/lib/apt/lists/*; 
        
        wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL"; 
        echo "$REDIS_DOWNLOAD_SHA *redis.tar.gz" | sha256sum -c -; 
        mkdir -p /usr/src/redis; 
        tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1; 
        rm redis.tar.gz; 
        
    # disable Redis protected mode [1] as it is unnecessary in context of Docker
    # (ports are not automatically exposed when running inside Docker, but rather explicitly by specifying -p / -P)
    # [1]: https://github.com/redis/redis/commit/edd4d555df57dc84265fdfb4ef59a4678832f6da
        grep -E '^ *createBoolConfig[(]"protected-mode",.*, *1 *,.*[)],$' /usr/src/redis/src/config.c; 
        sed -ri 's!^( *createBoolConfig[(]"protected-mode",.*, *)1( *,.*[)],)$!102!' /usr/src/redis/src/config.c; 
        grep -E '^ *createBoolConfig[(]"protected-mode",.*, *0 *,.*[)],$' /usr/src/redis/src/config.c; 
    # for future reference, we modify this directly in the source instead of just supplying a default configuration flag because apparently "if you specify any argument to redis-server, [it assumes] you are going to specify everything"
    # see also https://github.com/docker-library/redis/issues/4#issuecomment-50780840
    # (more exactly, this makes sure the default behavior of "save on SIGTERM" stays functional by default)
        
    # https://github.com/jemalloc/jemalloc/issues/467 -- we need to patch the "./configure" for the bundled jemalloc to match how Debian compiles, for compatibility
    # (also, we do cross-builds, so we need to embed the appropriate "--build=xxx" values to that "./configure" invocation)
        gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; 
        extraJemallocConfigureFlags="--build=$gnuArch"; 
    # https://salsa.debian.org/debian/jemalloc/-/blob/c0a88c37a551be7d12e4863435365c9a6a51525f/debian/rules#L8-23
        dpkgArch="$(dpkg --print-architecture)"; 
        case "${dpkgArch##*-}" in 
            amd64 | i386 | x32) extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=12" ;; 
            *) extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-page=16" ;; 
        esac; 
        extraJemallocConfigureFlags="$extraJemallocConfigureFlags --with-lg-hugepage=21"; 
        grep -F 'cd jemalloc && ./configure ' /usr/src/redis/deps/Makefile; 
        sed -ri 's!cd jemalloc && ./configure !&'"$extraJemallocConfigureFlags"' !' /usr/src/redis/deps/Makefile; 
        grep -F "cd jemalloc && ./configure $extraJemallocConfigureFlags " /usr/src/redis/deps/Makefile; 
        
        export BUILD_TLS=yes; 
        make -C /usr/src/redis -j "$(nproc)" all; 
        make -C /usr/src/redis install; 
        
    # TODO https://github.com/redis/redis/pull/3494 (deduplicate "redis-server" copies)
        serverMd5="$(md5sum /usr/local/bin/redis-server | cut -d' ' -f1)"; export serverMd5; 
        find /usr/local/bin/redis* -maxdepth 0 
            -type f -not -name redis-server 
            -exec sh -eux -c ' 
                md5="$(md5sum "$1" | cut -d" " -f1)"; 
                test "$md5" = "$serverMd5"; 
            ' -- '{}' ';' 
            -exec ln -svfT 'redis-server' '{}' ';' 
        ; 
        
        rm -r /usr/src/redis; 
        
        apt-mark auto '.*' > /dev/null; 
        [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark > /dev/null; 
        find /usr/local -type f -executable -exec ldd '{}' ';' 
            | awk '/=>/ { print $(NF-1) }' 
            | sort -u 
            | xargs -r dpkg-query --search 
            | cut -d: -f1 
            | sort -u 
            | xargs -r apt-mark manual 
        ; 
        apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; 
        
        redis-cli --version; 
        redis-server --version
    
    RUN mkdir /data && chown redis:redis /data
    VOLUME /data
    WORKDIR /data
    
    COPY docker-entrypoint.sh /usr/local/bin/
    ENTRYPOINT ["docker-entrypoint.sh"]
    
    EXPOSE 6379
    CMD ["redis-server"]
    View Code

     

    4.dockerfile执行流程

    (1)docker从基础镜像运行一个容器

    (2)执行一条指令并对容器作出修改

    (3)执行类似docker commit的操作提交一个新的镜像层

    (4)docker再基于刚提交的镜像运行一个新容器

    (5)执行dockerfile中的下一条指令直到所有指令都执行完成

     

    5.dockerfile内容

    1)FROM:基础镜像,当前新镜像是基于哪个镜像的

    2)MAINTAINER:镜像维护者的姓名和邮箱地址

    3)RUN:镜像构建容器时会运行此条命令

    4)EXPOSE:当前容器对外暴露出的端口

    5)WORKDIR:指定在创建容器后,终端登陆的进来默认工作目录,就像进入centos默认容器是在根目录/这里

    6)ENV:用来在构建镜像过程中设置环境变量,这个环境变量可以在后续的任何RUN指令中使用,也可以在其它指令中直接使用这些环境变量
    7)ADD:将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包

    8)COPY:类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置

    9)VOLUME:容器数据卷,用于数据保存和持久化工作

    10)CMD:指定一个容器启动时要运行的命令,Dockerfile 中可以有多个 CMD 指令,最终只有最后一个生效,CMD 会被 docker run 之后的参数替换

    11)ENTRYPOINT :指定一个容器启动时要运行的命令,docker run -it id /bin/bash,这里后面接了命令/bin/bash,对于/bin/bash命令不会覆盖ENTRYPOINT 的目录而是追加,但是会覆盖CMD的命令

    12)ONBUILD:当构建一个被继承的Dockerfile时会运行此条命令

     

    6.示例

    6.1示例1

    1)编辑dockerfile文件

    FROM centos:6.8
    MAINTAINER zzyy<zzyy167@126.com>
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    RUN ls -la
    EXPOSE 80
    CMD echo $MYPATHCMD echo "success--------------ok"
    CMD /bin/bash

    命令说明

    FROM centos:6.8                  继承自centos:6.8 
    MAINTAINER zzyy<zzyy167@126.com>    作者和邮箱
    ENV MYPATH /usr/local           定义环境变量MYPATH = /usr/local 
    WORKDIR $MYPATH              进入容器后的默认目录/usr/local 
    RUN ls -la                 运行RUN命令创建容器时,会执行命令 ls -la
    EXPOSE 80                  对外暴露端口80
    CMD echo $MYPATHCMD echo "success--------------ok"   执行命令 打印字符串
    CMD /bin/bash

     

    2)build生成新的镜像

    可以看到 la -la执行了  打印字符串也执行了

    最终成功生成新的镜像

     

    3)使用新生成的镜像创建运行容器

    进入容器,运行命令pwd查看当前目录,发现当前目录是/usr/local,说明配置生效了

     

     

    4)小结

    上面已涉及到了命令:FROM 、MAINTAINER 、ENV 、WORKDIR 、RUN 、EXPOSE 、CMD

     

    6.2示例2-CMD和ENTRYPOINT的不同

    6.2.1CMD

    1)创建dockerfle

    里面就一个ls命令

    FROM centos:6.8
    CMD ls

     

    2)build创建新的镜像

     

    3)使用镜像创建运行容器

    ls命令执行了

     

    4)使用镜像创建运行容器并追加命令

    这样子执行相当于dockerfile是下面这样

    FROM centos:6.8
    CMD ls
    CMD -la

    加了一条命令 -la

    由于-la不是命令,所以执行出错了

     

    6.2.2ENTRYPOINT

    1)dockerfile

    FROM centos:6.8
    ENTRYPOINT ls

     

    2)build创建新镜像

     

    3)创建和启动容器

    执行了命令 ls

     

    4)使用镜像创建运行容器并追加命令

    这样子执行相当于dockerfile是这样子

    FROM centos:6.8
    ENTRYPOINT ls -la

    ls和-la命令拼接起来了

    这就是CMD和ENTRYPOINT 的区别

     

    6.2示例3-ONBUILD

    6.2.1父镜像

    1)dockerfile

    FROM centos:6.8
    ONBUILD RUN echo "bei ji chengle 666666"

    ONBUILD:当这个dockerfile生成的镜像被继承的时候,会打印这段文字

     

    2)build

     

    6.3.2子镜像

    1)dockerfile

    FROM zzyy/mycentos:4.2
    RUN echo "run---qidong"

    继承自上面生成的镜像:zzyy/mycentos:4.2

     

    2)build

    由于它继承自zzyy/mycentos:4.2,所以build的时候打印了父镜像zzyy/mycentos:4.2的dockerfile里面ONBUILD要打印的字符串

     

     

    6.3带有JAVA、TOMCAT环境的centos

    1)dockerfile

    FROM  centos
    MAINTAINER    zzyy<zzyybs@126.com>
    #把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
    COPY c.txt /usr/local/cincontainer.txt
    #把java与tomcat添加到容器中 从宿主机复制jdk和tomcat到容器的usr/local目录下
    ADD jdk-8u171-linux-x64.tar.gz /usr/local/
    ADD apache-tomcat-9.0.8.tar.gz /usr/local/
    #安装vim编辑器
    RUN yum -y install vim
    #设置工作访问时候的WORKDIR路径,登录落脚点
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    #配置java与tomcat环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_171
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8
    ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    #容器运行时监听的端口
    EXPOSE  8080
    #启动时运行tomcat并且打印日志
    # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]
    # CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]
    CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out

    2)build

      dodker build -f /usr/local/docker/Dockerfile -t zzyytomcat9 .

    3)run

     docker run -d -p 9080:8080 --name myt9 -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs --privileged=true zzyytomcat9

    在tomcat的webapp目录下创建了两个容器数据卷,相当于两个项目,这样子可以在宿主机下直接对项目进行修改,容器下项目会同步

     

     
     

  • 相关阅读:
    Feign原理 (图解)
    纠错:Feign 没用 短连接
    【转】linux 查看哪些进程用了swap
    【转】交换分区SWAP
    【改】linux中分区的概念
    【转】SPI FLASH与NOR FLASH的区别 详解SPI FLASH与NOR FLASH的不一样
    【转】DDR3和eMMC区别
    ARP (地址解析协议)
    【转】一文搞懂C语言回调函数
    【改】shell 判断文件中有无特定子串方法(grep)
  • 原文地址:https://www.cnblogs.com/jthr/p/15158497.html
Copyright © 2020-2023  润新知