Docker学习笔记五:Dockerfile

    xiaoxiao2021-12-14  16

    通用参考和推荐

    docker build命令使用Dockerfile或者上下文构建镜像,构建上下文是指定的本地路径或者URL的文件。本地路径是本地文件系统的目录,URL是本地的Git仓库。构建是由Docker守护进程运行的,而不是CLI。构建过程首先要做的就是把整个上下文递归的传给守护进程,强烈建议在一个空目录下进行构建过程。

    容器应该是短暂的使用一个.dokerignore文件避免安装不必要的包每个容器只运行一个进程最小化层的数量多行参数排序建立缓存

    Dockerfile指令

    格式:

    # Commnet INSTRUCTION arguments

    INSTRUCTION(指令)大小写不敏感,但约定使用大写。

    环境变量:

    环境变量的格式可以是 $variable_name 或者 ${variable_name},${variable:-word}表示如果variable设置了,结果将是那个值,如果没有设置,则 结果是word;${variable:+word} 表示如果设置了variable,结果将是word,如果没有设置,则结果为空。

    FROM

    FROM <image>

    OR

    FROM <image>:<tag>

    OR

    FROM <image>@<digest>

    FROM指令为后面的指令设置基础镜像。一个有效的Dockerfile文件必须以FROM作为第一条非注释指令。

    MAINTAINER

    MAINTAINER <name>

    设置生成的镜像的Author字段

    RUN

    RUN有两种格式:

    RUN <command> shell格式,这个命令在shell中执行,Linux中默认是/bin/sh -c,windows系统默认是cmd /S /CRUN ["executable", "param1", "param2"] exec格式

    RUN指令将在当前镜像的新的一层执行任何命令并提交结果。

    apt-get

    避免执行apt-get upgrade和dist-upgrade,因为许多基础镜像中的必须包不会在特权容器中升级。

    CMD

    CMD有三种格式:

    CMD ["executable", "param1", "param2"] exec格式,首选的格式CMD ["param1", "param2"] 作为ENTRYPOINT的默认参数CMD command param1 param2 shell格式

    CMD的主要目的是为执行容器提供默认值。这些默认值可以包含可执行文件,或它们可以忽略可执行文件,在这种情况下,必须指定ENTRYPOINT指令。

    当使用shell格式或exec格式时,CMD指令设置的命令将会在运行容器时执行。使用JSON数组声明一个命令是,必须使用执行文件的绝对路径。

    FROM ubuntu CMD ["/usr/bin/wc", "--help"]

    在一个Dockerfile文件中只允许有一条CMD指令,如果有多条CMD指令,那么最后一条CMD指令生效。如果用户在执行docker run命令是指定了参数,那么将覆盖CMD指定的默认值。

    注意: exec格式作为JSON数组的格式被解析,因此必须使用双引号将单词引起来,而不是单引号。

    RUN和CMD的区别:RUN实际上在构建镜像过程中运行命令并提交结果;CMD在构建镜像过程中不执行任何操作,但指定了预执行命令(即在运行镜像时执行)。

    LABEL

    LABEL执行是向镜像中添加元数据,一个LABEL是一个键值对,在LABEL的值中使用添加空格,使用双引号和反斜线。示例:

    LABEL "com.example.vendor"="ACME Incorporated" LABEL com.example.label-with-value="foo" LABEL version="1.0" LABEL description="This text illustrates \ that label-values can span multiple lines."

    Docker可以指定多个标签,每个标签产生一个新层,多个层会导致效率低下,因此建议将多个标签合并到一个标签:

    LABEL multi.label1="value1" multi.label2="value2" other="value3"

    或:

    LABEL multi.label1="value1" \ multi.label2="value2" \ other="value3"

    查看镜像的LABEL可以使用docker inspect命令:

    "Labels": { "com.example.vendor": "ACME Incorporated" "com.example.label-with-value": "foo", "version": "1.0", "description": "This text illustrates that label-values can span multiple lines.", "multi.label1": "value1", "multi.label2": "value2", "other": "value3" },

    EXPOSE

    EXPOSE <port> [<port>...]

    EXPOSE指令通知Docker容器在运行时监听的端口。

    ENV

    ENV <key> <value> ENV <key>=<value> ...

    ENV指令设置环境变量的值为。第二种格式可以设置多个键值对,推荐在一条ENV指令中设置多个键值对,因为这样产生一个缓存层。

    ADD

    ADD … ADD [“”,… “”] 对于包含空格的路径,使用这种格式

    ADD指令复制新文件、目录或远程文件URL并添加他们到容器的文件系统路径,可以指定多个。每个可以包含通配符。

    所有的新文件或目录使用UID和GID为0创建。如果是一个远程文件URL,目标将会是600的权限。如果远程文件有HTTP Last-Modified头,这个HTTP头部的时间戳将用于设置目标文件的mtime。

    ADD指令遵循以下规则:

    必须包含在构建的上下文中,不能使用ADD ../something /something。如果是一个URL,不是以斜杠结束,文件将被从URL下载并拷贝到。如果是一个URL,以斜杠结束,文件名将从URL中获取,文件被下载到/。例如:ADD http://example.com/foobar /将会创建文件/foobar。不能是http://example.com类的URL。如果是目录,目录的所有内容将被复制,包括文件系统元数据(目录本身不复制,只是它的内容)。如果是一个gzip,bzip2或者xz类型的压缩归档文件,文件将被作为一个目录解压。远程URL文件不会被解压。如果一个目录被复制或者解压,与tar -x的行为相同:结果唯一: 1、无论在目标路径是否存在和 2、源目录树的内容,冲突以逐个文件为基础解析为”2.”

    注意:文件是否被识别为识别的压缩格式仅基于文件的内容,而不是文件的文件名。例如:一个空文件以.tar.gz结尾,则不会被识别为压缩文件,并且不会生成任何解压缩错误消息,而是该文件将被文件简单的复制到目的地。

    如果是其他类型的文件,它将于它的元数据一起单独的复制。在这种情况下,如果以/结尾,它将被认为是目录,的内容将被写在/base()。如果指定了多个,无论是直接或使用通配符,必须是目录,并且以/结束。如果不是以斜杠结束,将会被认作是一个常规文件,的内容将被写入。如果不存在,所有在路径中不存在的目录将会被创建。

    COPY

    COPY <src>... <dest>COPY ["<src>",... "<dest>"] 路径中包含空格时需要这种格式

    COPY指令从复制新文件文件或目录并添加它们到容器的文件系统路径。是一个绝对路径,或者相对WORKDIR的路径,其中源将被复制到目标容器内。

    COPY test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/ COPY test /absoluteDir/ # 添加 "test" 到 /absoluteDir/

    所有的文件和目录以UID和GID 0 创建。

    COPY遵循如下规则:

    路径必须在构建的上下文中,不能使用COPY ../something /something如果是一个目录,目录的所有内容包括元数据将会被复制。

    注意:目录本身不会被复制,只有它的内容。

    如果是其他类型的文件,它将于它的元数据一起被单独复制。这种情况下,如果以斜杠/结束,它将会被认作是目录,的内容将被写在/base()。如果指定了多个,或者直接或者使用通配符,必须是目录,且以/结束。如果没有以斜杠结束,将会认作是一般文件,并且的内容将被写入。如果不存在,所有在路径中不存在的目录将会被创建。

    ENTRYPOINT

    ENTRYPOINT ["executable", "param1", "param2"] exec格式,推荐ENTRYPOINT command param1 param2 shell格式

    ENTRYPOINT允许配置容器作为可执行文件运行。

    例如,下面的例子将会以默认内容启动nginx,监听端口80:

    docker run -i -t --rm -p 80:80 nginx

    docker run <image>的命令行参数将附加在exec格式的ENTRYPOINT中的所有元素之后,并将覆盖使用CMD指令所有元素。这允许将参数传递到入口点,例如:docker run <iamge> -d将把-d参数传给入口点,可以使用–entrypoint标志覆盖ENTRYPOINT指令。

    shell形式防止使用任何CMD或者运行命令行参数,但是缺点是ENTRYPOINT将作为/bin/sh -c的子命令启动,不传递信号。这意味着可执行文件将不是容器的PID 1,并且不接收Unix信号,因此您的可执行文件将不会从docker stop <container>接收到SIGTERM。

    只有Dockerfile文件的最后一条ENTRYPOINT指令生效。

    CMD和ENTRYPOINT是如何互相影响的

    1、Dockerfile应该至少指定一个CMD或者ENTRYPOINT命令 2、当使用容器作为可执行文件使用时,应该定义ENTRYPOINT 3、CMD应该用作定义ENTRYPOINT命令的默认参数或在容器中执行ad-hoc命令的一种方法 4、当运行带有替代参数的容器时,CMD将被覆盖

    下表显示了对不同ENTRYPOINT/CMD组合执行的命令:

    No ENTRYPOINTENTRYPOINT exec_entry p1_entryENTRYPOINT [“exec_entry”, “p1_entry”]No CMDerror,not allowed/bin/sh -c exec_entry p1_entryCMD [“exec_cmd”, “p1_cmd”]exec_cmd p1_cmd/bin/sh -c exec_entry p1_entry exec_cmd p1_cmdCMD [“p1_cmd”, “p2_cmd”]p1_cmd p2_cmd/bin/sh -c exec_entry p1_entry p1_cmd p2_cmdCMD exec_cmd p1_cmd/bin/sh -c exec_ cmd p1_cmd/bin/sh -c exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd

    VOLUME

    VOLUME ["/data"]

    VOLUME命令创建指定名称的挂载点,并将其标记为从本地主机或者其他容器保留外部挂载的卷。该值可以是JSON数组或者具有多个参数的纯字符串。

    USER

    USER daemon

    USER指令设置在运行镜像时使用的用户名或UID,以及Dockerfile中任何RUN,CMD,ENTRYPOINT指令的用户名。

    WORKDIR

    WORKDIR /path/to/worddir

    WORKDIR用来设置在Dockerfile文件中接下来的RUN,CMD,ENTRYPOINT,COPY和ADD等指令的工作目录。如果不存在,将会被创建,即使以后的Dockerfile指令都不使用。

    通过Dockerfile创建镜像

    制作Dockerfile文件

    1、创建工程目录

    $ mkdir mydockerbuilder

    2、进入工程目录,创建Dockerfile

    $ cd mydockerbuilder && touch Dockerfile

    3、编写Dockerfile

    $ vim Dockerfile FROM docker/whaleasy:latest RUN apt-get -y update && apt-get install -y fortunes CMD /usr/games/fortune -a | cowsay

    三行内容分别为:

    指定基础镜像,即基于whaleasy:latest创建新镜像

    更新镜像并安装fortunes引用程序

    镜像加载后执行的命令

    4、创建镜像

    $ docker build -t docker-whale . Sending build context to Docker daemon 2.048 kB ...snip... Removing intermediate container a8e6faa88df3 Successfully built 7d9495d03763

    镜像的创建过程

    docker build -t docker-whale .命令使用当前目录下的Dockerfile文件制作一个叫docker-whale的镜像。制作过程中出现的信息含义如下:

    首先Docker检查以确保它有它需要构建的一切。

    Sending build context to Docker daemon 2.048 kB

    然后Docker加载whalesay:latest镜像,如果本地没有,Docker将会下载此镜像。

    Step 1 : FROM docker/whalesay:latest ---> fb434121fc77

    接下来Docker使用apt-get包管理器更新包并安装fortunes

    Step 2 : RUN apt-get -y update && apt-get install -y fortunes ---> Running in 27d224dfa5b2 Ign http://archive.ubuntu.com trusty InRelease Ign http://archive.ubuntu.com trusty-updates InRelease Ign http://archive.ubuntu.com trusty-security InRelease Hit http://archive.ubuntu.com trusty Release.gpg ....snip... Get:15 http://archive.ubuntu.com trusty-security/restricted amd64 Packages [14.8 kB] Get:16 http://archive.ubuntu.com trusty-security/universe amd64 Packages [134 kB] Reading package lists... ---> eb06e47a01d2 Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: fortune-mod fortunes-min librecode0 Suggested packages: x11-utils bsdmainutils The following NEW packages will be installed: fortune-mod fortunes fortunes-min librecode0 0 upgraded, 4 newly installed, 0 to remove and 3 not upgraded. Need to get 1961 kB of archives. After this operation, 4817 kB of additional disk space will be used. Get:1 http://archive.ubuntu.com/ubuntu/ trusty/main librecode0 amd64 3.6-21 [771 kB] ...snip...... Setting up fortunes (1:1.99.1-7) ... Processing triggers for libc-bin (2.19-0ubuntu6.6) ... ---> c81071adeeb5 Removing intermediate container 23aa52c1897c

    最后Docker完成构建并报告结果:

    Step 3 : CMD /usr/games/fortune -a | cowsay ---> Running in a8e6faa88df3 ---> 7d9495d03763 Removing intermediate container a8e6faa88df3 Successfully built 7d9495d03763
    转载请注明原文地址: https://ju.6miu.com/read-964049.html

    最新回复(0)