Dockerfile命令参数的具体使用

 更新时间:2024年06月10日 09:53:20   作者:记忆机器  
Dockerfile是一个文本文件,包含用户构建镜像的所需要的全部命令,本文主要介绍了Dockerfile命令参数的具体使用,具有一定的参考价值,感兴趣的可以了解一下

Docker通过读取Dockerfile文件的命令生成镜像。Dockerfile是一个文本文件,包含用户构建镜像的所需要的全部命令。执行docker build后 ,docker通过一系列命令行操作自动构建镜像。本文描述Dockerfile中的命令。

Dockerfile的用法

docker build命令使用Dockerfile文件和构建镜像的上下文环境。上下文环境可以是一个本地目录,也可以是一个git仓库url。上下文环境的识别是递归的,因此指定一个本地目录的同时所有子目录会自动包含进去,指定git url时仓库的所有子模块也会被自动包含。下面命令表示使用当前目录(.)做为上下文环境。

docker build .

构建镜像由docker守护进程执行,不是客户端执行。构建进程首先将整个上下文环境整个发送给docker守护进程。所以最好指定的上下文环境目录只包含构建镜像所需要的文件和Dockerfile文件就好了。(不建议使用 / 根目录作为上下文环境,否则会导致将整个本地磁盘的文件发给docker守护进程)。

上下文中不需要的内容可以添加到.dockerignore文件中,docker客户端不会将 .dockerignore文件声明的文件发送给docker daemon

默认情况下Dockerfile文件名就是“Dockerfile”,并且放在上下文环境的一级目录下。也可以用 -f 参数指定其他位置

 docker build -f /path/to/a/Dockerfile .

用 -t 指定镜像的仓库名称和tag

docker build -t shykes/myapp .

同一个镜像可以指定给多个仓库,用多个 -t

docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

Docker使用构建缓存加速构建的过程,build过程中显示CACHED

docker build -t svendowideit/ambassador .
 [internal] load build definition from Dockerfile                       0.1s
 => transferring dockerfile: 286B                                       0.0s
 [internal] load .dockerignore                                          0.1s
 => transferring context: 2B                                            0.0s
 [internal] load metadata for docker.io/library/alpine:3.2              0.4s
 CACHED [1/2] FROM docker.io/library/alpine:3.2@sha256:e9a2035f9d0d7ce  0.0s
 CACHED [2/2] RUN apk add --no-cache socat                              0.0s
 exporting to image                                                     0.0s
 => exporting layers                                                    0.0s
 => writing image sha256:1affb80ca37018ac12067fa2af38cc5bcc2a8f09963de  0.0s
 => naming to docker.io/svendowideit/ambassador                         0.0s

缓存基于你上次构建的过程。--cache-from 允许指定外部缓存。

转义符声明

格式

# escape=\ (backslash)

或者

# escape=` (backtick)

非必填项,必须放在第一行,以 # 开头

默认的转义符是 \ ,命令太长一行写不完可以这样写

RUN echo "import os" >>  /root/.jupyter/jupyter_server_config.py \
        && echo "c.ServerApp.token = ''" >> /root/.jupyter/jupyter_server_config.py \
        && echo "c.ServerApp.password = ''" >> /root/.jupyter/jupyter_server_config.py \

指定escape为其他字符,在windows系统上比较好用,因为windows上 \ 是文件路径分隔符,使用 其他字符可以避免不必要的麻烦。

# escape=`

FROM microsoft/nanoserver
COPY testfile.txt c:\
RUN dir c:\

注意:只能放在第一行,通常后面跟一个空行,在FROM之前声明,否则就会认为是注释而不生效。Dockerfile中除了这个声明之外,其他 # 开头的都认为是注释。

FROM

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

指定基础镜像,之后的构建都是基于这个基础镜像生成。一个Dockerfile中可以有多个FROM,用于生成多个镜像。

--platform 可选参数,用于指定构建平台,例如linux/amd64, linux/arm64, windows/amd64

ARG指令是唯一一个可以在FROM之前声明的指令。

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

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

RUN

RUN <command>

shell格式,执行shell命令,默认是linux 的 /bin/sh -c,  Windows 的cmd /S /C

下面两个命令效果是一样的

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

也可使用下面的格式

RUN ["executable", "param1", "param2"]

例如

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

命令参数以json格式传入

CMD

三种形式

  • CMD ["executable","param1","param2"]       exec格式,最多使用
  • CMD ["param1","param2"]                            作为ENTRYPOINT命令的默认参数
  • CMD command param1 param2                   shell格式

Dockerfile中只能有一个CMD,如果写了多个,只有最后一个会生效。

CMD的主要目的是给容器运行提供默认的命令。容器运行也可以用ENTRYPOINT,此时CMD作为ENTRYPOINT的参数,两者都要用json格式。

exec格式不会调用shell,CMD [ "echo", "$HOME" ] 是不对的,要么为sehll 格式: CMD echo $HOME,要么用: CMD [ "sh", "-c", "echo $HOME" ]。

如果用shell,命令以 /bin/sh -c执行

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

如果不用shell,必须以json格式,指定命令的全路径,这种方式比较常用

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

如果用户执行 docker run时指定其他命令,CMD将会被覆盖。

不要将RUN和CMD混淆。RUN是打镜像过程中真正会执行,提交到执行结果中。CMD在打镜像时并不会执行,只是指定一个命令给镜像,真正执行是在镜像启动时。

LABEL

LABEL <key>=<value> <key>=<value> <key>=<value> ...

LABEL给镜像添加元数据信息。格式为key value对,一个镜像可以包含多个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."

LABEL可以从基础镜像继承,同一个label,最新的赋值会覆盖以前的。

通过docker image inspect  --format=''  myimage可以查看镜像的labels

docker image inspect --format='' myimage

结果: 

{
  "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"
}

MAINTAINER (deprecated)

指定镜像作者, 新版本不再推荐使用,官方建议用LABEL代替。例如

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

 EXPOSE

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

 告知Docker容器将会监听哪个端口,指定指定TCP或者UDP,默认是TCP。

EXPOSE不会真的发布这个端口,它其实是构建镜像的人给运行镜像的人提供的说明,真正暴露端口是在docker run的时候,通过 -p 或者-P 参数指定,将主机端口映射到容器端口。

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

容器间的网络通信可以使用docker network相关指令进行,而不用暴露到主机。

ENV

ENV <key>=<value> ...

设置环境变量,允许在同一个ENV后面设置多个环境变量

ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
    MY_CAT=fluffy

如果某个环境变量只想在打镜像的时候使用,而不赋值到最终的镜像,可以在单条指令中指定

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...

或者使用ARG,也不会赋值到最终的镜像中

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update &amp;&amp; apt-get install -y ...

 另外一种格式是不用=,这种格式一次只能定义一个变量

ENV MY_VAR my-value

ADD

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

 --chown 可选参数,只支持linux容器

src可以是上下文环境中的文件或者URL,src中可以使用通配符,例如

ADD hom* /mydir/

将添加所有hom开头的文件到 /mydir/中。

dest 如果是相对路径,就是 WORKDIR的相对路径

添加  “test.txt” 到 <WORKDIR>/relativeDir/ :

ADD test.txt relativeDir/

添加 “test.txt” 到 /absoluteDir/ :

ADD test.txt /absoluteDir/

注意几点:

  • <src> 路径必须是上下文环境中的文件
  • 如果<src>是url, <dest>末尾不以反斜杠结尾,文件被下载后被重命名为<dest>的值
  • 如果<src>是url并且<dest>以反斜杠结尾,文件下载为 /<dest>/<filename>
  • 如果<src>是目录,目录下所有文件都会拷贝,包括文件元信息。注意目录本身不会被拷贝,只拷贝目录里的内容
  • 如果<src>是压缩包,拷贝时会自动解压。URL中的压缩包不会解压。
  • <dest> 如果不以反斜杠结尾,会被识别为文件,拷贝的源文件会被重命名为<dest>,如果以反斜杠结尾就认为是目录,原文件会拷贝到<dest>目录下
  • <dest>中包含的路径如果不存在会被自动创建

COPY

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

拷贝文件的功能和ADD一样,不能自动解压压缩包,不能拷贝URL

有个可选参数--from=<name> 可以把之前构造的步骤作为原文件位置(FROM .. AS <name>)

COPY和ADD命令中,源文件如果被修改,从COPY或者ADD起,后面的命令缓存都会失效

ENTRYPOINT

exec 格式

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

 shell格式

ENTRYPOINT command param1 param2

docker run <image> 时传入的的参数会传给ENTRYPOINT,并且会覆盖CMD,例如docker run <image> -d 命令的-d参数会传给entry point。 docker run --entrypoint  会覆盖ENTRYPOINT命令。

shell格式的entrypoint不接受CMD或者run 传递的参数。

Dockerfile中只有最后一个ENTRYPOINT会生效。

CMD和ENTRYPOINT的关系

  • Dockerfile中至少应该包含CMD和ENTRYPOINT中的一个
  • CMD应该被用作ENTRYPOINT的默认参数,运行时可以被覆盖

下面的表格显示不同CMD和ENTRYPOINT组合后最终执行的命令

VOLUME

VOLUME ["/data"]
VOLUME /data

创建一个可以从本地机器挂载到容器的目录

例如

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

注意:

  • 使用Windows-based容器时,挂载的必须是一个空目录,并且不能是C盘
  • volume声明的目录,之后在Dockerfile中对这个目录做的修改都会无效
  • json格式声明必须用双引号,不能是单引号
  • 挂载的主机目录只能在运行时指定

USER

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

指定构建镜像运行时的用户和用户组(可选)

如果是windows镜像,必须先创建用户

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

WORKDIR

WORKDIR /path/to/workdir

指定所有RUN 、CMD、ENTRYPOINT、ADD命令的工作目录

可以指定多次,如果是相对目录,最后的值为前一个WORKDIR的先对目录,例如

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

输出为 /a/b/c

可以使用环境变量定义,例如

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

输出为/path/$DIRNAME

ARG

ARG <name>[=<default value>]

指定一个打镜像过程中的环境变量,docker build --build-arg <varname>=<value>

FROM busybox
ARG user1
ARG buildno
# ...

指定默认值

FROM busybox
ARG user1=someuser
ARG buildno=1
# ...

ARG的作用范围

ARG是从开始声明的那一行开始生效,而不是使用的那一行开始,例如

FROM busybox
USER ${user:-some_user}
ARG user
USER $user
# ...

执行

docker build --build-arg user=what_user .

第二行的USER值为some_user,第四行的USER值为what_user

一个构造阶段声明的ARG只在该阶段生效,如果多个阶段都需要,则每个阶段都要声明,如下

FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS

FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS

预定义的ARG

  • HTTP_PROXY
  • http_proxy
  • HTTPS_PROXY
  • https_proxy
  • FTP_PROXY
  • ftp_proxy
  • NO_PROXY
  • no_proxy

使用

 docker build --build-arg HTTPS_PROXY=https://my-proxy.example.com .

OBBUILD

ONBUILD <INSTRUCTION>

STOPSIGNAL

STOPSIGNAL signal

HEALTHCHECK

HEALTHCHECK [OPTIONS] CMD command

HEALTHCHECK NONE

到此这篇关于Dockerfile命令参数的具体使用的文章就介绍到这了,更多相关Dockerfile命令参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

SHELL

SHELL ["executable", "parameters"]

到此这篇关于Dockerfile命令参数的具体使用的文章就介绍到这了,更多相关Dockerfile命令参数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何使用 Dockerfile 创建一个简单容器

    如何使用 Dockerfile 创建一个简单容器

    这篇文章主要介绍了如何使用 Dockerfile 创建一个简单容器,Dockerfile 是用于指导 docker 创建自定义 image 的一系列指令,是用于创建 image 的蓝图,下文更多详细介绍需要的小伙伴可以参考一下
    2022-04-04
  • docker+daocloud实现前端项目自动构建部署

    docker+daocloud实现前端项目自动构建部署

    这篇文章主要介绍了docker+daocloud实现前端项目自动构建部署,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • 远程docker服务器携带证书连接的实现方法

    远程docker服务器携带证书连接的实现方法

    本文主要介绍了远程docker服务器携带证书连接的实现方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 本地文件如何上传至docker容器

    本地文件如何上传至docker容器

    这篇文章主要介绍了本地文件如何上传至docker容器问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • 详解docker进行数据挂载的三种模式

    详解docker进行数据挂载的三种模式

    Docker 提供了三种方式将数据从宿主机挂载到 Docker容器中: volumes、bind mounts、tmpfs ,这篇文章主要介绍了docker进行数据挂载的三种模式,需要的朋友可以参考下
    2022-05-05
  • docker部署code-server的方法

    docker部署code-server的方法

    这篇文章主要介绍了docker部署code-server的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • 解决docker CMD/ENTRYPOINT执行sh脚本报: not found/run.sh:

    解决docker CMD/ENTRYPOINT执行sh脚本报: not found/run.sh:

    这篇文章主要介绍了解决docker CMD/ENTRYPOINT执行sh脚本报: not found/run.sh:的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 使用Docker快速部署ES单机方式

    使用Docker快速部署ES单机方式

    这篇文章主要介绍了使用Docker快速部署ES单机方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Docker创建镜像两种方法详解

    Docker创建镜像两种方法详解

    这篇文章主要介绍了 Docker创建镜像两种方法详解的相关资料,Docker创建镜像:一是使用docker commit命令,二是使用docker build命令和Dockerfile文件,需要的朋友可以参考下
    2016-12-12
  • 在Ubuntu15.04上安装Docker的步骤以及基本用法

    在Ubuntu15.04上安装Docker的步骤以及基本用法

    Docker是一种轻量型的的类虚拟机的平台,在开发项目上还是很有优势的,这仅是我的一种直观理解。所以这篇文章主要给大家介绍了在Ubuntu15.04上安装Docker的步骤以及基本用法,有需要的朋友们可以参考借鉴。
    2016-10-10

最新评论