dockerfile语法

简介: dockerfile语法

20210328000023147.png

一、FROM 语法


scratch -- 从头开始

尽量来使用官方提供的image。

20201104153354658.png

二、label语法


meta信息,类似于代码的注释。

20201104153612559.png

三、run语法


没run一次image上会有新的一层。因此有必要使用&&合并执行,避免layer 过多看起来很混乱。

四、workdir 语法


使用workdir不要使用run cd来替代

workdir尽量使用绝对路径。增强dockerfile的可移植性。

五、add 和copy 语法


  • 区别:add 还具有解压缩的功能,例如add test.tat.gz /
  • workdir 和add的结合
  • 添加远程文件/目录使用curl 或者 wget

copy文件夹时候的坑

https://www.jianshu.com/p/9b7da9aacd8a

六、ENV语法


定义常量,增加可维护性,和shell中定义变量一个意思。

七、volume 和expose 语法


八、run、cmd 和entrypoint


例子:

shell 格式的docker file build的image

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-shell .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Running in 00b2f71e6d9f
Removing intermediate container 00b2f71e6d9f
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT echo "hello $name"
 ---> Running in cfc67b613f7a
Removing intermediate container cfc67b613f7a
 ---> 865aaaacd1ee
Successfully built 865aaaacd1ee
Successfully tagged ninesun0318/centos-entrypoint-shell:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker image ls
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-entrypoint-shell   latest              865aaaacd1ee        17 seconds ago      215MB
centos                                latest              0d120b6ccaa8        2 months ago        215MB
hello-world                           latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run 865aaaacd1ee
hello Docker

很完美这个dockerfile没有问题。

exec格式的docker file build的image

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo", "hello $name"]
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-exec .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Using cache
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT ["/bin/echo", "hello $name"]
 ---> Running in 61c84954936b
Removing intermediate container 61c84954936b
 ---> 2292313abbf0
Successfully built 2292313abbf0
Successfully tagged ninesun0318/centos-entrypoint-exec:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker image ls
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-entrypoint-exec    latest              2292313abbf0        5 seconds ago       215MB
ninesun0318/centos-entrypoint-shell   latest              865aaaacd1ee        8 minutes ago       215MB
centos                                latest              0d120b6ccaa8        2 months ago        215MB
hello-world                           latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run ninesun0318/centos-entrypoint-exec
hello $name
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 

奇怪exec 并没有把name 这个ENV打印出来。为何?

只有shell 中才会执行name才会被解释为变量,exec 就是简单的执行。

如何修改呢?

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 

重新build 然后run

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-exec-new .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Using cache
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
 ---> Running in 5ee34add9195
Removing intermediate container 5ee34add9195
 ---> cf961663ddc1
Successfully built cf961663ddc1
Successfully tagged ninesun0318/centos-entrypoint-exec-new:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run ninesun0318/centos-entrypoint-exec-new
hello Docker
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Ddo
more: stat of Ddo failed: No such file or directory

这个问题得到了解决。

 

例子说明:entrypoint 一定会被执行,cmd 会被覆盖。

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker images
REPOSITORY                               TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-cmd-shell             latest              d4ba5c0ae032        4 minutes ago       215MB
ninesun0318/centos-entrypoint-cmd        latest              d4ba5c0ae032        4 minutes ago       215MB
ninesun0318/centos-entrypoint-exec-new   latest              cf961663ddc1        12 minutes ago      215MB
ninesun0318/centos-entrypoint-shell      latest              865aaaacd1ee        24 minutes ago      215MB
centos                                   latest              0d120b6ccaa8        2 months ago        215MB
hello-world                              latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run -it ninesun0318/centos-entrypoint-shell /bin/bash
hello Docker
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run -it ninesun0318/centos-cmd-shell /bin/bash
[root@d8c93ad6de43 /]# 

ARG和ENV的区别


  • ARG 是构建时变量
  • ENV是运行时变量

1、ARG

ARG指令定义了一个变量,用户可以在构建时使用--build-arg = 传递,docker build命令会将其传递给构建器。--build-arg 指定参数会覆盖Dockerfile 中指定的同名参数

如果用户指定了 未在Dockerfile中定义的构建参数 ,则构建会输出 警告 。

ARG只在构建期有效,运行期无效

不建议使用构建时变量来传递诸如github密钥,用户凭据等机密。因为构建时变量值使用docker

history是可见的。

ARG变量定义从Dockerfile中定义的行开始生效。

使用ENV指令定义的环境变量始终会覆盖同名的ARG指令。

2、ENV

  • 在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。
  • 引号和反斜杠可用于在值中包含空格。
  • ENV 可以使用key value的写法,但是这种不建议使用了,后续版本可能会删除
ENV MY_MSG hello
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
#多行写法如下
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
MY_CAT=fluffy
  • docker run --env 可以修改这些值
  • 容器运行时ENV值可以生效
  • ENV在image阶段就会被解析并持久化(docker inspect image查看),参照下面示例
FROM alpine
ENV arg=1111111
ENV runcmd=$arg
RUN echo $runcmd
CMD echo $runcmd
#ENV的固化问题: 改变arg,会不会改变 echo的值,会改变哪些值,如何修改这些值?
  • 测试案例
FROM alpine
ARG arg1=22222
ENV arg2=1111111
ENV runcmd=$arg1
RUN echo $arg1 $arg2 $runcmd
CMD echo $arg1 $arg2 $runcmd

ENTRYPOINT和CMD的区别


目录
相关文章
|
10月前
|
Ubuntu Docker 容器
深入理解Dockerfile:构建镜像的详细解释与常用命令(下)
Docker 是一种流行的容器化平台,可将应用程序和其依赖项打包到一个独立的、可移植的容器中。Dockerfile 是构建 Docker 镜像的文本文件,它包含了一系列的指令和配置,用于定义镜像的构建过程。本文将深入解释 Dockerfile 的工作原理,并介绍常用的 Dockerfile 指令和构建命令,以帮助读者更好地理解和使用 Docker。
195 0
|
3月前
|
NoSQL Java Linux
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
《docker高级篇(大厂进阶):2.DockerFile解析》包括:是什么、DockerFile构建过程解析、DockerFile常用保留字指令、案例、小总结
297 76
|
4月前
|
JavaScript 数据库 Docker
一个有用的docker entrypoint脚本的范例
通过这个 Entrypoint 脚本,您可以确保在 Docker 容器启动时执行必要的初始化步骤,并且容器可以根据不同的运行时环境进行相应的配置和操作。这个范例展示了如何编写一个灵活且功能强大的 Entrypoint 脚本,使您的 Docker 容器更加可靠和易于管理。
69 3
|
5月前
|
应用服务中间件 nginx Docker
Dockerfile语法详解
Dockerfile语法详解
56 0
|
7月前
|
Ubuntu Java Linux
Dockerfile语法,自定义镜像
Dockerfile语法,自定义镜像
71 1
|
8月前
|
Linux 应用服务中间件 开发工具
Dockerfile编写
Dockerfile编写
51 3
|
10月前
|
Java 网络安全 开发者
【Docker】5、Dockerfile 自定义镜像(镜像结构、Dockerfile 语法、把 Java 项目弄成镜像)
【Docker】5、Dockerfile 自定义镜像(镜像结构、Dockerfile 语法、把 Java 项目弄成镜像)
143 0
|
10月前
|
应用服务中间件 nginx Docker
docker系列:dockerfile及其用法解析
docker系列:dockerfile及其用法解析
283 0
|
10月前
|
应用服务中间件 nginx Docker
深入理解Dockerfile:构建镜像的详细解释与常用命令(上)
Docker 是一种流行的容器化平台,可将应用程序和其依赖项打包到一个独立的、可移植的容器中。Dockerfile 是构建 Docker 镜像的文本文件,它包含了一系列的指令和配置,用于定义镜像的构建过程。本文将深入解释 Dockerfile 的工作原理,并介绍常用的 Dockerfile 指令和构建命令,以帮助读者更好地理解和使用 Docker。
1921 0
|
10月前
|
Linux Docker 容器
Docker Dockerfile 语法与指令
Docker Dockerfile 语法与指令
114 0