zoukankan      html  css  js  c++  java
  • Dockerfile常用指令总结(转载)

    Dockerfile的指令集相对来说很少,下面对常用的指令进行记录和总结

    什么是Dockerfile?

    dockerfile用于快速有序且直观地完成对镜像的定制。

    Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

    Dockerfile常用指令

    FROM

    FROM指令是整个Dockerfile的入口,必须是第一条指令。其代表新制作镜像的基础镜像。

    基础镜像可以自己制作,也可以从开源的仓库pull,例如dockerhub或是国内阿里云的免费仓库。

    Docker中存在一种特殊的情况,就是不以任何基础镜像为基准,此时可以第一句话使用:

    FROM scratch
    

    来表示以空白镜像为基础,也就是直接将可执行文件复制进镜像。例如swarm、coreos/etcd等。

    RUN指令

    是dockerfile中最常用的指令之一。用来执行命令行上的命令。

    • RUN的格式分为两种:
    第一种:
    shell格式:RUN<命令>,类似于直接在终端输入命令。例如:
    
    RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/tomcat/welcome.html
    
    第二种:
    exec格式:RUN ["可执行文件", "参数1", "参数2"]。
    RUN既然可以像在命令行那样工作,那么就也可以实现传参来运行指令:
    
    FROM ubuntu:14.04
    
    RUN apt-get update
    RUN apt-get install -y gcc libc6-dev make
    RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz"
    RUN mkdir -p /usr/src/redis
    RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
    RUN make -C /usr/src/redis
    RUN make -C /usr/src/redis install
    

    RUN一次就代表Dockerfile中的一层。而docker镜像的构建就是不断去完善每一层需要做的事情。而dockerfi对一个file中层数是有限制的,最大不超过127层。因此,RUN提供命令的串联功能,也就是允许每一层可包含多种操作,他们会按照书写顺序来依次执行。

    • 那么上面的例子可以变为:
    FROM ubuntu:14.04
    RUN buildDeps='gcc libc6-dev make' 
        && apt-get update 
        && apt-get install -y $buildDeps 
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" 
        && mkdir -p /usr/src/redis 
        && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 
        && make -C /usr/src/redis 
        && make -C /usr/src/redis install 
        && rm -rf /var/lib/apt/lists/* 
        && rm redis.tar.gz 
        && rm -r /usr/src/redis 
        && apt-get purge -y --auto-remove $buildDeps
    

    换行用 ,注释用 # ,平时书写注意缩进来保证文件的可读性。上述例子中的最后一句还进行了无关文件的清理,进一步保证每一层的最优和最小。

    注意事项:
    镜像的初衷是进行功能的模块化,也是尽可能让每个容器干最少的事情,那么我们在书写dockerfile的时候要注意这个问题,每一层的东西确保是必须的,否则就不要进行安装或是拷贝。

    MAINTAINER

    指定作者

    • 句法:
    MAINTAINER <name>
    

    LABEL

    该指令是为镜像添加标签。

    • 句法:
    LABEL <key>=<value> <key>=<value> <key>=<value> ...
    
    • 一个Dockerfile种可以有多个LABEL,如下:
    LABEL multi.label1="value1" 
    multi.label2="value2" 
    other="value3"
    

    说明:LABEL会继承基础镜像种的LABEL,如遇到key相同,则值覆盖

    COPY指令

    该指令用于将宿主机文件拷贝至镜像内的指定路径。

    • 格式:
    COPY <源路径>... <目标路径>
    或
    COPY ["<源路径1>",... "<目标路径>"]
    

    也就是说,原路径可以有多个,而目标路径唯一。
    注意事项:

    1、可以使用符合GO规范的通配符,例如:COPY hom* /mydir/
    2、目的路径可以是镜像内的绝对路径,也可以是相对于当前工作目录的相对路径。
    3、COPY过来的文件权限与原始权限相同。如需更改,请用传统Liunx的chmod命令进行修改即可。
    

    ADD高级复制

    • ADD的本质作用类似于COPY,但是其更复杂:
    1、ADD过来的压缩包可以自动在目标路径下进行解压
    2、原始路径可以是一个连接,ADD过程会尝试从该链接下载所需的文件到目的路径。
    3、一般情况下,建议使用COPY而不是ADD,因为COPY过来的文件可以配合使用RUN来进行解压或是其他操作,搭配使用更灵活,且单条语句所负担的功能唯一。、
    

    WORKDIR

    该指令用于指定Dockerfile中该指令下面的操作所在的工作目录。

    类似于 cd 命令。

    CMD 服务启动指令

    Docker不是虚拟机而是一个进程,作为进程,当然可以制定启动镜像时的具体参数。说白了就是制定一些你想自动启动的服务。

    • 格式:
    shell 格式:CMD <命令>
    exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
    参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
    
    • 注意事项:
    1、CMD中的启动参数可以被更新覆盖。例如:
    Dockerfile中若是用CMD指定启动镜像时执行/bin/bash,那么在启动镜像时输入docker run -it ubuntu ./test.sh 则会用./test.sh命令来覆盖/bin/bash命令。
    2、推荐使用exec格式的CMD书写。这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 ",而不要使用单引号。
    3、如果使用 shell 格式的话,实际的命令会被包装为 sh -c 的参数的形式进行执行。比如:CMD echo /java
    在实际执行中,会将其变更为:
    CMD [ "sh", "-c", "echo /java" ]
    

    ENV设置环境变量

    说是环境变量还不说是一个全局变量。在前面定义,后面可以通过 $ 取值进行使用。

    • 格式:
    ENV <key> <value>
    ENV <key1>=<value1> <key2>=<value2>...
    

    例如可以指定一些包的版本号,这样更新镜像很方便,或是保存一些密码(该功能慎用,自己玩还是可以的)

    ARG 构建参数

    语法形式: ARG <name>[=<default value>]
    

    ARG和ENV效果类似,都是用来设置观景变量的。唯一 不同的是dockerfile中的ARG编译好后是不会出现在打开的容器内的。

    ARG在dockerfile中创建一个全局参数,参数可以给定一个默认值,在编译时可以传参对其进行覆盖。如果ARG指令有默认值并且在构建期间没有接收到参数、则使用默认值。一个dockerfile中可以包含多个ARG参数。

    docker build --build-arg <varname>=<value>
    

    可以使用ARG或ENV指令来指定RUN指令可用的变量,如果ARG和ENV同时指定了一个相同名称的变量、则ENV设置的变量会覆盖ARG设置的变量。如下:

    1 FROM ubuntu
    2 ARG CONT_IMG_VER
    3 ENV CONT_IMG_VER v1.0.0
    4 RUN echo $CONT_IMG_VER
    

    使用 docker build --build-arg CONT_IMG_VER=v2.0.1 . 最终输出v1.0.0 。

    一个ARG指令的有效范围在其定义的构建阶段内、如果要在多个阶段中都有效、则必须在每个阶段都使用ARG指令;与ARG不同 ENV设置参数的有效期为整个构建期内。

    VOLUME 挂在共享卷

    • 格式为:
    VOLUME ["<路径1>", "<路径2>"...]
    VOLUME <路径>
    

    Docker的使用原则除了每个容器干尽量少的事情外,还尽可能要求容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,也就是将本地磁盘的某一个目录挂载至容器内。同时这样的共享目录可以被多个不同的容器所使用。

    除了可以在dockerfile中指定这一参数外,在运行启动容器时也可以附带这一参数来指定共享卷:

    docker run -it --name container-test -h CONTAINER -v /data debian /bin/bash
    

    上述命令也可以覆盖dockerfile中的目录设定。

    USER 指定用户

    在书写dockerfile时,某些层的操作若想切换用户名,可以使用该参数指定某些层的用户,并且是存在的用户名。

    • 格式:USER <用户名>

    如果以 root 执行的脚本,在执行期间希望改变身份,比如希望以某个已经建立好的用户来运行某个服务进程,不要使用 su 或者 sudo,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 gosu

    # 建立 redis 用户,并使用 gosu 换另一个用户执行命令
    RUN groupadd -r redis && useradd -r -g redis redis
    # 下载 gosu
    RUN wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64" 
        && chmod +x /usr/local/bin/gosu 
        && gosu nobody true
    # 设置 CMD,并以另外的用户执行
    CMD [ "exec", "gosu", "redis", "redis-server" ]
    

    EXPOSE暴漏端口

    • 句法:
    EXPOSE <端口1> [<端口2>...]
    

    EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。

    要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。

    转载文档

    https://www.jianshu.com/p/2a90fc6ee383
    
  • 相关阅读:
    APP之百度地图SDK的AK值获取(android)
    横向滚动菜单-选中标题居中显示
    函数按引用传参问题
    js验证提交
    Java servlet ajax
    数据库3种读
    mybatis插件
    mybatis 缓存
    从前端对象中获取的文本变为字符串,并替换其中一些指定的字符
    多个窗口开启后,切换到指定title的窗口
  • 原文地址:https://www.cnblogs.com/evescn/p/12470762.html
Copyright © 2011-2022 走看看