dockerfile语法

目录

一、FROM 语法

二、label语法

三、run语法

四、workdir 语法

五、add 和copy 语法

六、ENV语法

七、volume 和expose 语法

八、run、cmd 和entrypoint


一、FROM 语法

scratch -- 从头开始

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

二、label语法

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

三、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的区别 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyySophia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值