diff --git a/docker/docker file.md b/docker/docker file.md index cbae0fb..3083184 100644 --- a/docker/docker file.md +++ b/docker/docker file.md @@ -1,3 +1,41 @@ +- [Dockerfile](#dockerfile) + - [format](#format) + - [parser directive](#parser-directive) + - [syntax](#syntax) + - [escape](#escape) + - [ENV](#env) + - [.dockerignore file](#dockerignore-file) + - [FROM](#from) + - [ARG和FROM的交互](#arg和from的交互) + - [RUN](#run) + - [RUN --mount](#run---mount) + - [Mount Types](#mount-types) + - [RUN --mount=type=bind](#run---mounttypebind) + - [RUN --network](#run---network) + - [CMD](#cmd) + - [LABEL](#label) + - [EXPOSE](#expose) + - [ENV](#env-1) + - [ADD](#add) + - [ADD --chown](#add---chown) + - [ADD \ \](#add-git-ref-dir) + - [COPY](#copy) + - [COPY --from](#copy---from) + - [ENTRYPOINT](#entrypoint) + - [ENTRYPOINT和CMD指令的交互](#entrypoint和cmd指令的交互) + - [VOLUME](#volume) + - [VOLUME指令要点](#volume指令要点) + - [USER](#user) + - [WORKDIR](#workdir) + - [ARG](#arg) + - [default value](#default-value) + - [Scope](#scope) + - [ENV和ARG使用](#env和arg使用) + - [预定义的ARG](#预定义的arg) + - [ONBUILD](#onbuild) + + + # Dockerfile Docker可以通过读取dockerfile中的指令自动构建image。 ## format @@ -359,7 +397,7 @@ COPY hom* /mydir/ 类似`ADD --chown`,`COPY`命令也支持`COPY --chown`的用法. ### COPY --from COPY支持`--from=`选项,可以将`source`设置为先前的build stage而不是build context。**如果找不到具有相同名称的build stage,则会采用具有相同名称的image**。 -### ENTRYPOINT +## ENTRYPOINT `ENTRYPOINT`命令具有两种格式: - ***exec***格式: ```dockerfile @@ -374,7 +412,119 @@ ENTRYPOINT允许像一个可执行程序一样配置容器。 ```dockerfile docker run -i -t --rm -p 80:80 nginx ``` -`docker run `命令之后的命令行参数将添加到***exec***形式ENTRYPOINT命令的所有元素之后,其允许参数被传递给entry point。 +`docker run `命令之后的命令行参数将添加到***exec***形式ENTRYPOINT命令的所有元素之后,**并且命令行参数会覆盖CMD指令中指定的元素。**其允许参数被传递给entry point。 例如,`docker run -d`将会把`-d`传递给entry point。 > 可以通过`docker run --entrypoint`命令来覆盖ENTRYPOINT指令。 +`shell`格式的ENTRYPOINT将阻止任何`CMD`或`run command line`参数被使用,但是`shell`形式的ENTRYPOINT会作为`/bin/sh -c`的一个子命令启动。 +> 如果ENTRYPOINT作为`/bin/sh -c`的一个子命令启动,意味着目标可执行文件并不是容器的`PID 1`,也不会接收Unix信号-可以执行文件不会从docker stop命令中接收到SIGTERM信号。 + +只有dockerfile中的最后一个ENTRYPOINT命令会起作用。 +如果想要在使用ENTRYPOINT `shell form`时保证`PID 1`进程是目标可执行文件,可以在ENTRYPOINT指令前加上`exec`,示例如下所示: +```dockerfile +FROM ubuntu +ENTRYPOINT exec top -b +``` +如果`shell form`不带`exec`,该命令将作为`/bin/sh -c`的子命令执行,`PID 1`进程为`sh`而不是`top`,调用`docker stop`时容器SIGTERM信号将会被发送给`sh`,然后`top`进程会在超时之后接收到一个SIGKILL信号,并无法干净的退出。 +### ENTRYPOINT和CMD指令的交互 +`ENTRYPOINT`指令和`CMD`指令都用于指定容器启动时的命令,它们遵循如下规则: +- dockerfile至少应该指定一条ENTRYPOINT或CMD指令 +- 当想要将容器像可执行文件一样运行(可以在`docker run`命令后添加传递给`ENTRYPOINT`指令的参数时),应该使用`ENTRYPOINT`指令 +- 当为`docker run`命令指定了额外参数时,`CMD`指令中为`ENTRYPOINT`指令指定的默认参数将会被命令行参数覆盖 +## VOLUME +```dockerfile +VOLUME ["/data"] +``` +`VOLUMN`指令创建了一个具有指定名称的挂载点,并且将其标记为持有外部挂载volume。VOLUMNE指令的值可以通过json array的形式指定(`VOLUME ["/var/log/"]`),也可以通过纯字符串的形式来指定(`VOLUME /var/log`或`VOLUME /var/log /var/db`)。 +VOLUMN指令会使用基础image指定目录下的数据来初始化新创建的volume,示例如下: +```dockerfile +FROM ubuntu +RUN mkdir /myvol +RUN +Learn more about the "RUN " Dockerfile command. +echo "hello world" > /myvol/greeting +VOLUME /myvol +``` +在使用`docker run`指令执行上述dockerfile产生镜像时,会在/myvol创建一个挂载点,并且将greeting文件复制到新创建的volume中。 +### VOLUME指令要点 +- 如果在VOLUME指令创建volume之后,任何build step修改了volume路径下的数据,那些修改都会被丢弃 +## USER +```dockerfile +USER [:] +# or +USER [:] +``` +USER指令用于指定当前stage剩余steps的默认user和group。指定用户用于RUN指令和ENTRYPOINT,CMD命令的执行。 +## WORKDIR +```dockerfile +WORKDIR /path/to/workdir +``` +WORKDIR用于设置dockerfile中位于该命令之后步骤的工作目录。如果指定的工作目录不存在,那么会创建该工作目录。 +在dockerfile中,WORKDIR指令可以使用多次,如果提供了相对路径,相对路径会基于当前工作目录解析: +```dockerfile +WORKDIR /a +WORKDIR b +WORKDIR c +RUN pwd +``` +最终,pwd输出的路径是/a/b/c。 +WORKDIR指令可以解析环境变量,只可以解析显式在dockerfile中设置的环境变量: +```dockerfile +ENV DIRPATH=/path +WORKDIR $DIRPATH/$DIRNAME +RUN pwd +``` +输出值为`/path/$DIRNAME` +> 如果WORKDIR尚未被指定,那么WORKDIR的默认值是`/`。如果父镜像中设置了WORKDIR的值,那么dockerfile将使用父镜像的WORKDIR + +为了避免在非预期的目录中执行操作,最好显式在dockerfile中设置WORKDIR. +## ARG +```dockerfile +ARG [=] +``` +ARG指令可以定义一系列变量,定义的变量在build时可以通过`docker build --build-arg =`来设置值。 +如果在`--build-arg`中传递了dockfile中不存在的参数,会抛出警告,表示该变量没有被dockerfile消费。 +```dockerfile +FROM busybox +ARG user1 +ARG buildno +# ... +``` +### default value +可以为ARG指定一个默认值,示例如下所示: +```dockerfile +FROM busybox +ARG user1=someuser +ARG buildno=1 +# ... +``` +如果在build时没有传递值给ARG变量,那么会使用默认值。 +### Scope +一个ARG指令的作用域范围从定义该ARG行开始算起,一直到当前build stage结束。 +### ENV和ARG使用 +当ENV和ARG指令同时被定义时,ENV定义的变量总是会覆盖ARG指令定义的变量。 +### 预定义的ARG +dockerfile含有一组预定义的ARG变量,可以直接使用这些预定义的ARG变量而无需在dockerfile中添加ARG指令: +- HTTP_PROXY +- http_proxy +- HTTPS_PROXY +- https_proxy +- FTP_PROXY +- ftp_proxy +- NO_PROXY +- no_proxy +- ALL_PROXY +- all_proxy +```shell + docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com . +``` +## ONBUILD +```dockerfile +ONBUILD +``` +ONBUILD指令添加了一个触发器,当该镜像作为其他镜像的基础镜像时,ONBUILD指定的指令将会被执行。ONBUILD触发器的指令将会在下游build操作的context中被执行,就像ONBUILD包含的指令被直接插入到下游FROM指令之后。 +使用示例如下: +```dockerfile +ONBUILD ADD . /app/src +ONBUILD RUN /usr/local/bin/python-build --dir /app/src +``` \ No newline at end of file