【docker知识】DockerFile语法 2:构造指令

news2024/11/18 3:19:17

1官方文档:Dockerfile reference | Docker Documentation     

   

一、说明

        我们将以HelloWorld案例的方法,由浅入深地理解DockerFile指令,并生成自己的镜像。为了避免冗长的官网文章污染您的视线,这里将重要的,常见的指令应用展现出来。这里不累述更深刻的语句用法,因为篇幅实在太大。

二、镜像制作过程

2.1 编写和制作过程

使用dockerfile制作镜像,简单地说就是以下三步:

  • 编写dockerfie
  • docker build 指令编译
  • run新镜像

2.2 docker build语法

docker build就是制作image的编译过程。

语法是:

docker build [OPTIONS] PATH | URL | -

2.3 官网上的[OPTIONS](参数)表

Name, shorthand

Default

Description

--add-host

Add a custom host-to-IP mapping (host:ip)

--build-arg

Set build-time variables

--cache-from

Images to consider as cache sources

--cgroup-parent

Optional parent cgroup for the container

--compress

Compress the build context using gzip

--cpu-period

Limit the CPU CFS (Completely Fair Scheduler) period

--cpu-quota

Limit the CPU CFS (Completely Fair Scheduler) quota

--cpu-shares , -c

CPU shares (relative weight)

--cpuset-cpus

CPUs in which to allow execution (0-3, 0,1)

--cpuset-mems

MEMs in which to allow execution (0-3, 0,1)

--disable-content-trust

true

Skip image verification

--file , -f

Name of the Dockerfile (Default is PATH/Dockerfile)

--force-rm

Always remove intermediate containers

--iidfile

Write the image ID to the file

--isolation

Container isolation technology

--label

Set metadata for an image

--memory , -m

Memory limit

--memory-swap

Swap limit equal to memory plus swap: -1 to enable unlimited swap

--network

Set the networking mode for the RUN instructions during build

--no-cache

Do not use cache when building the image

--platform

Set platform if server is multi-platform capable

--pull

Always attempt to pull a newer version of the image

--quiet , -q

Suppress the build output and print image ID on success

--rm

true

Remove intermediate containers after a successful build

--security-opt

Security options

--shm-size

Size of /dev/shm

--squash

experimental (daemon)
Squash newly built layers into a single new layer

--tag , -t

Name and optionally a tag in the name:tag format

--target

Set the target build stage to build.

--ulimit

Ulimit options

--help

Print usage

注意,此表格首先掌握-t,-f 就基本够了,其它参数可以用时现学。

三、制作Hello-world镜像实例

        我们先从制作Hello-world镜像实验开始。该案例虽很简单,但足以表明制作过程的必要步骤,剩下的仅仅是制作更复杂的案例。

3.1 环境要求

  • ubuntu或其它linux
  • 已经安装docker
  • 已经安装了gcc

3.2 制作路径过程

先建立工程目录imgmajer:

mkdir -p ~/imgmaker/src ~/imgmaker/build
cd ~/imgmaker
touch  dockerfile

 结构如下:

3.3 建立C语言hello-world程序

cd ~/imgmaker/src
vim hello.c

1)hello-world程序

#include <stdio.h>

int main(int argc, char *argv[])
{
        printf("hello world\n");
        return 0;
}

2)编译

cd ~/imgmaker
gcc  ./src/hello.c -o ./build/hello

 至此,~/imgmaker/build目录下有了hello进程。

3.4 建立dockerfile文件

cd ~/imgmaker
sudo vim dockerfile

将以下文本粘贴进去。

FROM ubuntu:20.04
MAINTAINER smith smith@qq.com
RUN mkdir  /data
COPY ./build/hello /data
ENTRYPOINT ["/data/hello", "smith"]

3.5 编译产生结果镜像

    docker build -t hellome:1.0 .

        编译后生成镜像hellome:1.0,可以通过docker images看到。 

3.6 执行run生成容器

        启动新建镜像:

    docker run hellome:1.0

        至此,基于dockerfile完整地构造出一个新镜像hellome。

四、常见指令简表

        保留字表:

保留字意义重要程度
FROM定义本镜像的基镜像★★★★★
ARG对FORM语句的参数部分定义变量★★★ 
MAINTAINER维护人员名称★★
RUN在构造过程的shell指令前加RUN号★★★★★
WORKDIR指定宿主机工作目录★★★★
ADD拷贝文件,如果是包文件,解压成目录★★★★★
COPY拷贝文件★★★★★
VOLUME数据卷定义★★★
CMD该镜像通过docker run加载成容器时,运行哪个进程★★★★★
ENTERPOINT与CMD相同,可以加参数★★★★★
EXPOSE镜像内守护进程的端口暴露★★★★
USER指定镜像使用的用户权限★★
ENV环境宏变量定义★★★

五、DockerFile指令详述

5.1 FROM语句

5.1.1  概念    

  • FROM是第一构造语句,是定义基镜像的。(相当于:pull镜像+run镜像)
  • 如果dockerfile只构造一个镜像,FROM语句是唯一的。
  • 如果在一个dockerfile构造多个镜像,可以多次出现,每个FROM相当于另起一个dockerfile。
  • 如果前边构造出的镜像是后面构造的基镜像。FROM也可以多次出现。
  •  ARG语句是专门为FROM语句提供参数变量的,是唯一的可以在FROM语句之前出现语句。
  • 在FROM语句之后,实际上是容器操作。

        

2)FROM的语法

FROM [--platform=<platform>] <image> [AS <name>]
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

3)可选项说明 

以上两个格式都合法。分别举例如下:

  • FROM ubuntu              此处将ubuntu: latest拉取过来做为基
  • FROM ubuntu:16.04    此处将ubuntu:16.04 拉取过来做为基

自选项目

  •  [--platform=<platform>]  这是如果

        如果 FROM 引用多平台镜像,可选的 --platform 标志可用于指定图像的平台。例如,linux/amd64、linux/arm64 或 windows/amd64。

  • [AS <name>]

        是个阶段可选项,可以通过向FROM指令添加AS名称来为新的构建阶段指定名称。该名称可以在随后的FROM和COPY-FROM=<name>指令中使用,以引用在此阶段中构建的映像。

4)补充事项

  • ARG是Dockerfile中唯一可以在FROM之前的指令。请参阅了解ARG和FROM如何交互。
  • FROM可以在一个Dockerfile中多次出现,以创建多个映像或将一个构建阶段用作另一个构建的依赖项。只需在每个新的FROM指令之前记录提交输出的最后一个镜像ID。
  • 每个FROM指令都会清除先前指令创建的任何状态。

5.2  ARG指令

  • ARG定义一个参量。
  • ARG定义参量为可以用于FROM语句。
  • 通过在docker build语句加 --build-arg <varname>=<value>选项将参量带入Dockerfile中。

5.2.1 ARG语法:

ARG <name>[=<default value>]

        ARG 指令定义了一个变量,用户可以在构建时使用 --build-arg <varname>=<value> 标志使用 docker build 命令将其传递给构建器。在 Dockerfile 中,构建会输出警告。

[Warning] One or more build-args [foo] were not consumed.

        一个 Dockerfile 可能包含一个或多个 ARG 指令。例如,以下是一个有效的 Dockerfile:

FROM busybox
ARG user1
ARG buildno

5.2.2 参考 ARG和FROM 交互

FROM 指令支持由出现在第一个 FROM 之前的任何 ARG 指令声明的变量。

ARG  CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD  /code/run-app

FROM extras:${CODE_VERSION}
CMD  /code/run-extras

        在 FROM 之前声明的 ARG 在构建阶段之外,因此它不能在 FROM 之后的任何指令中使用。构建阶段:

ARG VERSION=latest
FROM busybox:$VERSION
ARG VERSION
RUN echo $VERSION > image_version

 5.2.3 参数 ARG和build带入

        通过在docker build语句加 --build-arg <varname>=<value>选项将参量带入后,将刷新dockerfile定义的varname的值。 

示例:编写两句话的dockerfile有

ARG us=sss
RUN echo $us

        采用编译指令:docker build -t myImage:1.0 .

输出sss

         采用编译指令:docker build --build-arg=yyy -t myImage:1.0 .

输出yyy

5.3 MAITAINER

        维护者标记,现已弃用,目前用LABEL替换。LABEL优点是:新制造的镜像中、他的容器中,都可以看到作者。

  • 语法:
MAINTAINER <name>

        MAINTAINER 指令设置生成图像的 Author 字段。LABEL 指令是一个更灵活的版本,您应该使用它,因为它可以设置您需要的任何元数据,并且可以轻松查看,例如使用 docker inspect要设置与 MAINTAINER 字段对应的标签,您可以使用:

LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"

        这将在 docker inspect 中与其他标签一起可见。

5.4  RUN指令

  • RUN是制作镜像过程中shell指令的执行环节。
  • 指令将在当前镜像之上的新层中执行任何命令并提交结果。也就是每个RUN语句就加一层。

5.4.1 语法格式:

  • RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows)
  • RUN ["executable", "param1", "param2"] (exec form)

5.4.2 注意点:

  • exec 形式可以避免 shell 字符串修改,并使用不包含指定 shell 可执行文件的基本映像运行命令。
  • 可以使用 SHELL 命令更改 shell 形式的默认 shell。
  • 在 shell 形式中,您可以使用(反斜杠)将单个 RUN 指令继续到下一行。例如,考虑这两行:
RUN /bin/bash -c 'source $HOME/.bashrc && \
echo $HOME'

        上面可以合并成下列行:

RUN /bin/bash -c 'source $HOME/.bashrc && echo $HOME'

 5.4.3 RUN的exec格式

        要使用除“/bin/sh”之外的其他 shell,请使用传入所需 shell 的 exec 形式。

RUN ["/bin/bash", "-c", "echo hello"]

5.5 ENV 环境参量宏替换

        环境变量(用 ENV 语句声明),可以在某些指令中由 Dockerfile 解释的变量。类似于编译中的宏替换。

        使用环境变量时,在用 $variable_name 或 ${variable_name} ,编译时用值替换之。

        ${variable_name} 语法还支持一些标准的 bash 修饰符,如下所示:

  •         ${variable:-word} :表示如果variable被赋值,那么结果将是哪个值;如果variable未赋值,结果不是空,而是默认值word。
  •         ${variable:+word} 表示如果variable被赋值了,则结果为word,否则如未赋值结果为空字符串。

        在所有情况下,该词可以是任何字符串,包括其他环境变量。

        通过在变量前添加 \ 可以进行转义:例如,\$foo 或 \${foo} 将分别转换为 $foo 和 ${foo} 文字。

        4 示例(解析后的表示形式显示在 # 之后): 

FROM busybox
ENV FOO=/bar
WORKDIR ${FOO}   # WORKDIR /bar
ADD . $FOO       # ADD . /bar
COPY \$FOO /quux # COPY $FOO /quux

5.6 WORKDIR指令

        该指令指出image当前工作目录是哪个(注意不是指宿主机上的路径)。

        WORKDIR 指令为 Dockerfile 中跟在它后面的任何 RUN、CMD、ENTRYPOINT、COPY 和 ADD 指令设置工作目录。

5.6.1 语法:

WORKDIR /path/to/workdir

5.6.2 WORKDIR指令在一个Dockerfile中可以多次使用

如果提供相对路径,则相对于上一条WORKDIR指令的路径。

WORKDIR /a    绝对路径
WORKDIR b     相对路径
WORKDIR c     相对路径
RUN pwd

        此 Dockerfile 中最后一个 pwd 命令的输出将是 /a/b/c。

5.6.3 隐式表示  

        WORKDIR 指令可以解析先前使用 ENV 设置的环境变量。您只能使用在 Dockerfile 中显式设置的环境变量。

ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd

        这个 Dockerfile 中最后一个 pwd 命令的输出将是 /path/$DIRNAME

        如果未指定,则默认工作目录为 /。实际上,如果您不是从头开始构建 Dockerfile (FROM scratch),则 WORKDIR 可能由您使用的基础映像设置。

        因此,为避免在未知目录中进行意外操作,最好明确设置您的 WORKDIR。

 5.7 USER指令

  • 设置镜像操作的人员和组。
  • 这和后边的权限管理相关。

5.7.1 语法

USER <user>[:<group>]
USER <UID>[:<GID>]

5.7.2 注意事项 

        USER 指令设置用户名(或 UID)和可选的用户组(或 GID)以用作当前阶段剩余部分的默认用户和组。指定的用户用于 RUN 指令,并在运行时运行相关的 ENTRYPOINT 和 CMD 命令。

请注意,为用户指定群组时,用户将只有指定的群组成员资格。

警告

当用户没有主要组时,镜像(或下一条指令)将与根组一起运行。在 Windows 上,如果用户不是内置帐户,则必须先创建它。

FROM microsoft/windowsservercore
# Create Windows user in the container
RUN net user /add patrick
# Set it for subsequent commands
USER patrick

5.8 COPY指令

        是指文件从宿主机拷贝到制作中容器的过程。

5.8.1 COPY 的两种格式 

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

5.8.2 COPY 的解释

  • COPY 指令从 <src> 复制新文件或目录,并将它们添加到容器的文件系统路径 <dest> 中。
  • 采用两种格式的原因是:有些路径是在win10是有空格的,包含空格的路径需要后一种形式。
  • [--chown=<user>:<group>]是对操作追加操作权限。
  • --chown 仅在用于构建 Linux 容器的 Dockerfile 上受支持,在 Windows 容器上不起作用。将用户名和组名转换为 ID 限制此功能仅适用于基于 Linux 操作系统的容器。
  • 可以指定多个 <src> 资源,但文件和目录的路径将被解释为相对于构建上下文的源。
  • 每个 <src> 可能包含通配符。

5.8.3 通配符举例

  •  添加以“hom”开头的所有文件:
    COPY hom* /mydir/
  • 在下面的示例中,? 被替换为任何单个字符,例如“home.txt”。
    COPY hom?.txt /mydir/
  • <dest> 是绝对路径,或相对于 WORKDIR 的路径,源将被复制到目标容器内。
  • 下面的示例使用相对路径,并将“test.txt”添加到 <WORKDIR>/relativeDir/:
COPY test.txt relativeDir/

        而此示例使用绝对路径,并将“test.txt”添加到 /absoluteDir/

COPY test.txt /absoluteDir/

        当复制包含特殊字符(如[和])的文件或目录时,需要按照Golang规则对那些路径进行转义,防止它们被当作匹配模式。.txt,使用如下;

COPY arr[[]0].txt /mydir/

        所有新文件和目录都使用 0 的 UID 和 GID 创建,除非可选的 --chown 标志指定给定的用户名、组名或 UID/GID 组合以请求复制内容的特定所有权。标志允许用户名和组名字符串或直接整数 UID 和 GID 的任意组合。提供不带组名的用户名或不带 GID 的 UID 将使用与 GID 相同的数字 UID。/etc/passwd 和 /etc/group 文件将用于从名称执行转换分别为整数 UID 或 GID。

5.8.4 权限举例

COPY --chown=55:mygroup files* /somedir/
COPY --chown=bin files* /somedir/
COPY --chown=1 files* /somedir/
COPY --chown=10:11 files* /somedir/

        如果容器根文件系统不包含 /etc/passwd 或 /etc/group 文件,并且在 --chown 标志中使用了用户名或组名,则构建将在 COPY 操作中失败。

5.9 ADD指令

  •  ADD基本实现COPY指令。
  • ADD不仅拷贝文件,而且将.tar等文件解压成镜像内目录和文件。
  •  ADD 指令从 <src> 复制新文件、目录或远程文件 URL,并将它们添加到镜像的文件系统路径 <dest> 中。

5.9.1 ADD有两个格式 

ADD [--chown=<user>:<group>] [--checksum=<checksum>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]

( 包含空格的路径需要后一种形式)

注意

--chown 仅在用于构建 Linux 容器的 Dockerfile 上受支持,在 Windows 容器上不起作用。将用户名和组名转换为 ID 限制此功能仅适用于基于 Linux 操作系统的容器。

        可以指定多个 <src> 资源,但如果它们是文件或目录,它们的路径将被解释为相对于构建上下文的源。

5.9.2 通配符使用

添加以“hom”开头的所有文件:

ADD hom* /mydir/

在下面的示例中,? 被替换为任何单个字符,例如“home.txt”。

ADD hom?.txt /mydir/

5.9.3 关于路径

         <dest> 是绝对路径,或相对于 WORKDIR 的路径,源将被复制到目标容器内。下面的示例使用相对路径,并将“test.txt”添加到 <WORKDIR>/relativeDir/:

ADD test.txt relativeDir/

        而此示例使用绝对路径,并将“test.txt”添加到 /absoluteDir/

ADD test.txt /absoluteDir/

        在添加包含特殊字符(如[和])的文件或目录时,需要按照Golang规则对这些路径进行转义,防止它们被视为匹配模式。例如添加名为arr[0]的文件.txt,使用以下内容;

ADD arr[[]0].txt /mydir/

5.9.4 关于带权限追加文件、目录

        所有新文件和目录都使用 0 的 UID 和 GID 创建,除非可选的 --chown 标志指定给定的用户名、组名或 UID/GID 组合以请求添加内容的特定所有权。标志允许用户名和组名字符串或直接整数 UID 和 GID 的任意组合。提供不带组名的用户名或不带 GID 的 UID 将使用与 GID 相同的数字 UID。/etc/passwd 和 /etc/group 文件将用于从名称执行转换分别为整数 UID 或 GID。

ADD --chown=55:mygroup files* /somedir/
ADD --chown=bin files* /somedir/
ADD --chown=1 files* /somedir/
ADD --chown=10:11 files* /somedir/

        如果容器根文件系统不包含 /etc/passwd 或 /etc/group 文件,并且在 --chown 标志中使用了用户名或组名,则构建将在 ADD 操作上失败。使用数字 ID 不需要查找和将不依赖于容器根文件系统内容。

5.10 EXPOSE语句

  • 是专门对网络访问提供端口暴露。
  • EXPOSE指令通知Docker容器在运行时监听指定的网络端口,可以指定端口监听TCP还是UDP,不指定协议默认为TCP。

5.10.1 语法 

EXPOSE <port> [<port>/<protocol>...]

5.10.2 端口发布       

        EXPOSE 指令实际上并没有发布端口。它的作用是构建镜像的人和运行容器的人之间的一种文档,关于哪些端口打算发布。在 docker run 上使用 -pflag 来发布并映射一个或多个端口,或 -P 标志以发布所有暴露的端口并将它们映射到高阶端口。

        默认情况下,EXPOSE 假定 TCP。

EXPOSE 80/udp

要在 TCP 和 UDP 上公开,请包括两行:

EXPOSE 80/tcp
EXPOSE 80/udp

        在这种情况下,如果您将 -P 与 docker run 一起使用,端口将为 TCP 公开一次,为 UDP 公开一次。请记住,-P 在主机上使用临时高阶主机端口,因此端口不会相同用于 TCP 和 UDP。

        无论 EXPOSE 设置如何,您都可以在运行时使用 -p 标志覆盖它们。

$ docker run -p 80:80/tcp -p 80:80/udp ...

        要在主机系统上设置端口重定向,请参阅使用 -P 标志。docker network 命令支持为容器之间的通信创建网络,而无需公开或发布特定端口,因为连接到网络的容器可以相互通信通过任何端口。有关详细信息,请参阅此功能的概述。

5.11 CMD指令

5.11.1 CMD指令的三个格式:

  • CMD ["executable","param1","param2"] (exec form, this is the preferred form)
  • CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
  • CMD command param1 param2 (shell form)

        一个Dockerfile中只能有一条CMD指令,如果列出多个CMD则只有最后一条CMD生效。CMD 的主要目的是为正在执行的容器提供默认值。

        如果使用 CMD 为 ENTRYPOINT 指令提供默认参数,则 CMD 和 ENTRYPOINT 指令都应使用 JSON 数组格式指定。

Note

exec 格式被解析为 JSON 数组,这意味着您必须在单词周围使用双引号 (“) 而不是单引号 (‘)。

        与 shell 形式不同,exec 形式不调用命令 shell。这意味着正常的 shell 处理不会发生。例如,CMD [ "echo", "$HOME" ] 不会对 $HOME 进行变量替换。want shell处理然后使用shell形式或直接执行shell,例如:CMD [“sh”,“-c”,“echo $HOME”]。对于shell形式,是shell在做环境变量扩展,而不是 docker。

5.11.2 CMD指令举例

        当以 shell 或 exec 格式使用时,CMD 指令设置运行图像时要执行的命令。如果您使用 CMD 的 shell 形式,那么 <command> 将在 /bin/sh -c 中执行:

FROM ubuntu
CMD echo "This is a test." | wc -

        如果你想在没有 shell 的情况下运行你的 <command> 那么你必须将命令表示为 JSON 数组并给出可执行文件的完整路径。这种数组形式是 CMD 的首选格式。任何附加参数必须单独表示为字符串在数组中:

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

        如果您希望您的容器每次都运行相同的可执行文件,那么您应该考虑将 ENTRYPOINT 与 CMD 结合使用。

        如果用户为 docker run 指定参数,那么他们将覆盖 CMD 中指定的默认值。

Note

        不要将 RUN 与 CMD 混淆。RUN 实际上运行一个命令并提交结果;CMD 在构建时不执行任何操作,而是为图像指定预期的命令。

5.12 VOLUME语句

        VOLUME 指令创建一个具有指定名称的挂载点,并将其标记为持有来自本机主机或其他容器的外部挂载卷。

5.12.1 语法格式

VOLUME ["/data"]

       多个参数,例如 VOLUME /var/log 或 VOLUME /var/log /var/db。有关更多信息/示例和通过 Docker 客户端安装说明,请参阅通过卷文档共享目录。

        docker run 命令使用基础映像中指定位置存在的任何数据初始化新创建的卷。例如,考虑以下 Dockerfile 片段:

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

        这个 Dockerfile 生成一个镜像像,使 docker run 在 /myvol 上创建一个新的挂载点,并将greeting文件复制到新创建的卷中。

5.12.2 关于指定卷的注意事项

        请记住以下有关 Dockerfile 中的卷的事项。

  • 基于 Windows 的容器上的卷:使用基于 Windows 的容器时,容器内卷的目的地必须是以下之一:
  • 一个不存在的或空的目录
  • C 以外的驱动器:
  • 从 Dockerfile 中更改卷:如果任何构建步骤在声明卷后更改卷中的数据,这些更改将被丢弃。
  • JSON 格式:列表被解析为 JSON 数组。您必须用双引号 (") 而不是单引号 (') 将单词括起来。
  • 主机目录在容器运行时声明:主机目录(挂载点)本质上是依赖于主机的。这是为了保持镜像的可移植性,因为给定的主机目录不能保证在所有平台上都可用因此,您不能从 Dockerfile 中挂载主机目录。VOLUME 指令不支持指定主机目录参数。
PS E:\myproject> docker build -t cmd .

Sending build context to Docker daemon 3.072 kB
Step 1/2 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/2 : COPY testfile.txt c:\RUN dir c:
GetFileAttributesEx c:RUN: The system cannot find the file specified.
PS E:\myproject>

5.13 ENTRYPOINT指令

  • ENTRYPOINT和CMD有共同点,那就是都为镜像所派生的容器指定首个执行进程。
  • ENTRYPOINT 允许您配置将作为可执行文件运行的容器。
  • 只有 Dockerfile 中的最后一条 ENTRYPOINT 指令才会起作用。

5.13.1 ENTRYPOINT的两种格式:

1)exec 格式:

ENTRYPOINT ["executable", "param1", "param2"]

2)shell 格式:

ENTRYPOINT command param1 param2


5.13.2 举例说明

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

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

        docker run <image> 的命令行参数将附加在 exec 表单 ENTRYPOINT 中的所有元素之后,并将覆盖使用 CMD 指定的所有元素。这允许将参数传递到入口点,即 docker run <image> -d会将 -d 参数传递给入口点。

        您可以使用 docker run --entrypoint 标志覆盖 ENTRYPOINT 指令。

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

5.13.3 举例说明

        Exec形式的 ENTRYPOINT 示例

        您可以使用 ENTRYPOINT 的 exec 形式设置相当稳定的默认命令和参数,然后使用任一形式的 CMD 设置更可能更改的其他默认值。

FROM ubuntu
ENTRYPOINT ["top", "-b"]
CMD ["-c"]

        当您运行容器时,您可以看到 top 是唯一的进程:

$ docker run -it --rm --name test  top -H

top - 08:25:00 up  7:27,  0 users,  load average: 0.00, 0.01, 0.05
Threads:   1 total,   1 running,   0 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:   2056668 total,  1616832 used,   439836 free,    99352 buffers
KiB Swap:  1441840 total,        0 used,  1441840 free.  1324440 cached Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
    1 root      20   0   19744   2336   2080 R  0.0  0.1   0:00.04 top

要进一步检查结果,您可以使用 docker exec:

$ docker exec -it test ps aux

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  2.6  0.1  19752  2352 ?        Ss+  08:24   0:00 top -b -H
root         7  0.0  0.1  15572  2164 ?        R+   08:25   0:00 ps aux

您可以使用 docker stop test 优雅地请求 top 关闭。

以下 Dockerfile 显示使用 ENTRYPOINT 在前台运行 Apache(即作为 PID 1):

FROM debian:stable
RUN apt-get update && apt-get install -y --force-yes apache2
EXPOSE 80 443
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

        如果您需要为单个可执行文件编写启动脚本,您可以使用 exec 和 gosu 命令确保最终可执行文件接收 Unix 信号:

#!/usr/bin/env bash
set -e

if [ "$1" = 'postgres' ]; then
    chown -R postgres "$PGDATA"

    if [ -z "$(ls -A "$PGDATA")" ]; then
        gosu postgres initdb
    fi

    exec gosu postgres "$@"
fi

exec "$@"

        最后,如果您需要在关闭时做一些额外的清理(或与其他容器通信),或者协调多个可执行文件,您可能需要确保 ENTRYPOINT 脚本接收 Unix 信号,传递它们,然后做更多的工作:

#!/bin/sh
# Note: I've written this using sh so it works in the busybox container too

# USE the trap if you need to also do manual cleanup after the service is stopped,
#     or need to start multiple services in the one container
trap "echo TRAPed signal" HUP INT QUIT TERM

# start service in background here
/usr/sbin/apachectl start

echo "[hit enter key to exit] or run 'docker stop <container>'"
read

# stop service and clean up here
echo "stopping apache"
/usr/sbin/apachectl stop

echo "exited $0"

5.14  关于.dockerignore 文件

        在 docker CLI 将上下文发送到 docker 守护程序之前,它会在上下文的根目录中查找名为 .dockerignore 的文件。如果此文件存在,CLI 会修改上下文以排除与其中的模式匹配的文件和目录。帮助以避免不必要地向守护进程发送大的或敏感的文件和目录,并可能使用 ADD 或 COPY 将它们添加到图像中。

        CLI 将 .dockerignore 文件解释为以换行符分隔的模式列表,类似于 Unix shell 的文件 glob。为了匹配的目的,上下文的根被认为是工作目录和根目录。例如,模式 /foo/bar 和 foo/barboth 都排除了 PATH 的 foo 子目录或位于 URL 的 git 存储库的根目录中名为 bar 的文件或目录。两者都不排除任何其他内容。

        如果 .dockerignore 文件中的一行在第 1 列中以# 开头,则该行将被视为注释并在被 CLI 解释之前被忽略。

        这是一个示例 .dockerignore 文件:

# comment
*/temp*
*/*/temp*
temp?

        此文件导致以下构建行为:

RuleBehavior
# comment忽略.

*/temp*

排除根的任何直接子目录中名称以 temp 开头的文件和目录。例如,排除普通文件 /somedir/temporary.txt,目录 /somedir/temp。

*/*/temp*

从根以下两级的任何子目录中排除以 temp 开头的文件和目录。

temp?

排除根目录中名称为 temp 一个字符扩展名的文件和目录。

六、后记

        本篇对官方文档进行一次瘦身,对于一般的Image生成已经足够。但是对于更“大腕”级别的应用,恐怕依然需要参考官网。本文的另一个特色,是首先给出hello-world的制作过程,后边指令都可以在hello-world基础上实验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349941.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springcloud-配置中心config

一、添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId&…

【大数据】HADOOP-YARN容量调度器多队列配置详解实战

简介 Capacity调度器具有以下的几个特性&#xff1a; 层次化的队列设计&#xff0c;这种层次化的队列设计保证了子队列可以使用父队列设置的全部资源。这样通过层次化的管理&#xff0c;更容易合理分配和限制资源的使用。容量保证&#xff0c;队列上都会设置一个资源的占比&a…

数据分析与SAS学习笔记4

INPUT语句&#xff1a;格式修饰符&#xff1a; “:” 修饰符。表示从下一个非空格列读入数据&#xff0c;直到:1 遇到再下一个空格列&#xff1b; 2 读到预先定义的变量长度&#xff1b; 3 数据行结束。哪个先出现就在哪儿结束。 “&” 修饰符。表示从下一个非空格列读入…

分享我从功能测试转型到测试开发的真实故事

由于这段时间我面试了很多家公司&#xff0c;也经历了之前公司的不愉快。所以我想写一篇文章来分享一下自己的面试体会。希望能对我在之后的工作或者面试中有一些帮助&#xff0c;也希望能帮助到正在找工作的你。 找工作 我们总是草率地进入一个自己不了解的公司工作&#xf…

【C语言】web后端 CGI

web后端 CGI 一、cgi的学习 cgi通用网关接口 是web服务器主机提供信息服务的标准接口。通过CGI接口&#xff0c;web服务器就能获取客户端提交的信息&#xff0c;转交给服务器端端CGI程序进行处理&#xff0c;最后返回结果给客户端。 服务器和CGI程序之间通过 stdin/stdout 标准…

Python学习-----函数3.0(嵌套函数、闭包、装饰器)

目录 1.函数嵌套 2.闭包 3.装饰器 这一节&#xff0c;我会详细Python中讲解函数的进阶内容&#xff0c;包括嵌套函数、闭包和装饰器。一起来学习吧&#xff01;&#xff01;&#xff01; 1.函数嵌套 概念&#xff1a;函数里面再定义一个函数 作用&#xff1a;当我们在一个多…

Jenkins 基于Kubernetes 弹性构建池

流程&#xff1a;创建Jenkins Agent&#xff1b;获取Jenkins Agent的参数&#xff1b;渲染yaml模板&#xff1b;调用K8s API在固定的NS中创建一个Pod&#xff1b;运行Jenkins pipeline到agent&#xff1b;创建Agentimport hudson.model.Node.Mode import hudson.slaves.* impor…

学Python不会不知道NumPy计算包吧,带你五分钟看懂NumPy计算包

从今天我们就开始进入 Python 数据分析工具的教程。 前段时间数据分析和Python都讲了一点点&#xff0c;但是Python的数据库&#xff0c;讲的少了点&#xff0c;所以接下来就讲讲这些重要的常用数据库吧&#xff01;&#xff01;&#xff01; Python 数据分析绝对绕不过的四个…

数据库常用命令

文章目录1. 数据库操作命令1.进入数据库2.查看数据库列表信息3.查看数据库中的数据表信息2.SQL语句命令1. 创建数据表2. 基本查询语句3. SQL排序4. SQL分组统计5. 分页查询6. 多表查询7.自关联查询8.子查询1. 数据库操作命令 1.进入数据库 mysql -uroot -p2.查看数据库列表信…

PDF怎么转换成Word?两种PDF免费转Word方法推荐

不知道你们有没有发现&#xff0c;我们在网上下载的很多资料都是PDF格式的&#xff0c;尽管PDF文件也可以通过专门的PDF编辑器来编辑&#xff0c;但是PDF文档作为版式文档&#xff0c;编辑起来还是存在很多局限性&#xff0c;所有当我们需要大量编辑修改文档的时候&#xff0c;…

网络编程套接字之TCP

文章目录一、TCP流套接字编程ServerSocketSocketTCP长短连接二、TCP回显服务器客户端服务器客户端并发服务器UDP与TCP一、TCP流套接字编程 我们来一起学习一下TCP socket api的使用&#xff0c;这个api与我们之前学习的IO流操作紧密相关&#xff0c;如果对IO流还不太熟悉的&am…

Springboot 我随手封装了一个万能的导出excel工具,传什么都能导出

前言 如题&#xff0c;这个小玩意&#xff0c;就是不限制你查的是哪张表&#xff0c;用的是什么类。 我直接一把梭&#xff0c;嘎嘎给你一顿导出。 我知道&#xff0c;这是很多人都想过的&#xff0c; 至少我就收到很多人问过我这个类似的问题。 我也跟他们说了&#xff0c;但…

python冒号的用法总结

一维数组 1. 单个冒号的情况 1.1 写完整的情况下 单个冒号的情况下&#xff0c;对数组的遍历操作是从前向后操作。如&#xff1a;arr[a:b] &#xff0c;冒号前的a含义是从a开始遍历&#xff0c;冒号后的b含义是到b截止&#xff08;不包括b&#xff09;。 arr [1, 2, 3, 4,…

Qt扫盲-QMake 语言概述

QMake 语言概述一、概述二、变量三、替换函数四、测试函数一、概述 这里主要就是记录一下如何使用 qmake Manual&#xff0c;里面关于我对 qmake的理解&#xff0c;以及如何配置这个 qt 工程文件&#xff0c;通过配置工程文件&#xff0c;来构建出&#xff0c;APP&#xff0c;…

如何在Github上配置ssh key的密钥

Step0 : 解释说明 git使用SSH配置&#xff0c; 初始需要以下三个步骤 使用秘钥生成工具生成rsa秘钥和公钥将rsa公钥添加到代码托管平台将rsa秘钥添加到ssh-agent中&#xff0c;为ssh client指定使用的秘钥文件 Step 1: 核验本地主机是否已经存在ssh密钥。&#xff08;若id_rs…

ChatGPT之文章生成

文章目录介绍激励设计Prompt Design故障调整Troubleshooting分类Classification提高分类器的效率生成对话内容转化翻译转化总结实际问答插入文本编辑模式介绍 ChatGPT功能很强大&#xff0c;它可以根据你给出的模板和文本进行文本补全&#xff0c;最好的探索方式就是使用我们给…

数据预处理(无量纲化、缺失值、分类特征、连续特征)

文章目录1. 无量纲化1.1 sklearn.preprocessing.MinMaxScaler1.2 sklearn.preprocessing.StandardScaler2. 缺失值3. 分类型特征4. 连续型特征数据挖掘的五大流程包括&#xff1a;获取数据数据预处理特征工程建模上线 其中&#xff0c;数据预处理中常用的方法包括数据标准化和归…

3分钟学会图新地球图源制作详细教程

图新地球图源制作 1.资源准备 &#xff08;1&#xff09; 准备一份图新地球支持的lrc格式的图源; &#xff08;2&#xff09; 安装图新地球 &#xff08;LSV&#xff09;软件和奥维omap软件 。 2.操作步骤 (1) 用记事本打开lrc格式的文件(图①)&#xff0c;同时用奥维软件…

Unity 多语言 轻量高效的多语言工具集 LanguageManager

效果展示 支持excel导入自动化 组件化 更方便 也提供直接获取多语言的接口 没有挂 LanguageText的对象也可以获取多语言文本内容 支持 Format接口 可以传递N个参数进来组装多语言 支持首次系统语言自测 支持语言切换后本地自动保存配置 支持实时切换 同步刷新所有UI 容错处…

Maven:在Intellij idea的使用

MavenIntellij idea配置MavenIntellij idea创建Maven项目Java项目的创建Web项目的创建Intellij idea执行Maven命令JavaWeb项目转为Maven项目遇到的问题解决了解到Maven的基础知识后&#xff0c;接下来&#xff0c;简单介绍Maven在Intellij idea的使用&#xff08; 以 IntelliJ …