dockerfile 几组易混命令找茬

简介: dockerfile 几组易混命令找茬


背景

在docker在使用中,发现其命令中有几组有趣的命令,总是成对出现的,功能看似差不多,但是又有一丝丝差别,今天介绍几种,来波找茬!

1.COPY vs ADD

COPY、ADD主体功能类似:从指定位置src拷贝文件到Docker镜像dest。

COPY <src>... <dest>

ADD <src>... <dest>

COPY只允许从Docker Engine主机上拷贝文件到Docker镜像文件;

ADD也能完成以上工作,但是ADD支持另外两种src:

文件源可以是URL

可以从src直接解压tar文件到目的地

ADD http://foo.com/bar.go /tmp/main.go

从指定地址下载文件,添加到镜像文件系统的/tmp/main.go位置

ADD http://foo.com/bar.go /tmp/

因为以/结尾,将会引用url中的文件名添加到指定的目录下

ADD /foo.tar.gz /tmp/

自动解压主机文件到指定目录

*特别注意

URL下载和自动解压功能不能同时生效:任何通过URL下载的压缩包文件不会自动解压

如果拷贝本地文件到镜像,通常使用COPY,因为含义更明确

ADD支持URL文件、自动解压到指定目录,这2个特性也很棒

2.ARG vs ENV

ARG、ENV也让人很疑惑的,都是Dockerfile中定义变量的指令。

ARG用于镜像构建阶段,ENV用于将来运行的容器。

生成镜像后,ARG值不可用,正在运行的容器将无法访问ARG变量值。

ARG  VAR_NAME 5

构建镜像时,可提供--build-arg VAR_NAME=6 修改ARG值。

ENV主要是为容器环境变量提供默认值,正在运行的容器可访问环境变量(这是将配置传递给应用的好方法):

ENV VAR_NAME_2 6

启动容器时,可通过docker run -e "VAR_NAME_2=7"或docker-compose.yml提供新的环境变量值来覆盖Dockerfile中设置的ENV值。

一个小技巧:构建镜像时不能使用命令行参数重写ENV,但是你可以使用ARG动态为ENV设置默认值:

You can set VAR_A while building the image or leave it at the default

ARG VAR_A 5

VAR_B gets the (overridden) value of VAR_A

ENV VAR_B $VAR_A

3.RUN vs ENTRYPOINT vs CMD

RUN 在新层中执行命令并产生新镜像,主要用于安装新软件包。

ENTRYPOINT 执行程序的启动命令,当您想将容器作为可执行文件运行时使用。

CMD和ENTRYPOINT 都可以提供程序的启动命令;CMD另一个作用是为执行中的容器提供默认值

CMD ["executable","param1","param2"] (可执行形式,最常见)
CMD command param1 param2 (脚本形式)
CMD echo "Hello world"
run -it <image> 输出 Hello world

但是当容器以命令启动,docker run -it <image> /bin/bash, CMD会被忽略,bash解析器将会运行:

root@98e4bed87725:/#

CMD ["param1","param2"] 
 (作为ENTRYPOINT指令默认值,此时必须提供ENTRYPOINT指令,且ENTRYPOINT也必须以Json Array形式)

ENTRYPOINT [“/bin/echo”, “Hello”]

CMD [“world”]

run -it <image> 将会输出 Hello world

run -it <image> earth将会输出 Hello earth

打算构建一个可执行的且常驻的镜像,最好选用ENTRYPOINT;

如果需要提供默认命令参数(可在容器运行时从命令行覆盖),请选择CMD。


总结:

cmd和entripoint的区别就是 cmd不可以覆盖,entripoiint可以被覆盖和追加.

这个覆盖是 docker run时后面加的 命令 和 cmd/entripoint的shell命令是否覆盖

4.-p 和-P

这2个命令不是在dockerfile中的,是在运行程序的时候,都可以做docker端口映射,在docker run启动一个容器时,有时候用-p 8080:8080 或者直接-P 不加端口号,这里有什么区别?

-P的使用

-P将容器内部开放的网络端口随机映射到宿主机的一个端口上;、

-p的使用

-p指定要映射的端口,一个指定端口上只可以绑定一个容器。

使用方式有以下几种:

1) IP:HOSTPORT:CONTAINERPORT:指定ip、指定宿主机port、指定容器port

  • 适用于映射到指定地址的指定端口,例如将容器的5000端口映射到指定地址127.0.0.1的5000端口上:

-p 8081:8080 是把容器的8080和映射到宿主机的8081上

docker run -it -d -p 127.0.0.1:8081:8080 tomat /bin/bash

2) IP::CONTAINERPORT:指定ip、未指定宿主机port(随机)、指定容器port

适用于映射到指定地址的任意端口

将容器的9000端口映射到127.0.0.1的任意端口上:

docker run -it -d -p 127.0.0.1::9000  tomcat   /bin/bash

3)HOSTPORT:CONTAINERPORT :未指定ip、指定宿主机port、指定容器port

适用于将容器指定端口指定映射到宿主机的一个端口上(映射所有接口地址),将容器的80端口映射到宿主机的8000端口上:

docker run -itd -p 8000:80 nginx /bin/bash

特别说明

查看端口映射配置

可以使用

docker port CONTAINER_ID

5.dockerfile中的volume和 docker run -v

dockerfile中的volumn只是容器中的对外映射目录,会在宿主机上随机生成一个目录。

docker run -v 可以指定 主机目录:容器目录

相关文章
|
2月前
|
分布式计算 Java 测试技术
肝Spark源码的若干骚操作
肝Spark源码的若干骚操作
23 0
|
2月前
|
搜索推荐
代码分享|GPL平台没有基因注释什么办?别慌,基因ID注释万能公式!
本文介绍了处理无基因注释的GEO数据集的方法。当遇到GPL平台无基因注释时,可以通过以下步骤解决:1) 查看数据集补充文件中是否已有注释矩阵;2) 使用搜索引擎或官网查找相关资源;3) 如数据集较新,尝试联系平台官方;4) 利用已有经验进行转换。文中通过多个GSE示例详细解释了如何处理不同情况,并提醒读者注意检查数据集中可能隐藏的注释信息。作者提供了转换ID的代码,并在公众号“多线程核糖体”分享了相关资源。
209 0
|
Java 程序员 开发者
只用一行代码,你能玩出什么花样?
只用一行代码,你能玩出什么花样?
77 1
|
数据库 Windows
机房收费系统—一堆小问题3
机房收费系统—一堆小问题3
46 0
|
数据库连接 数据库 数据安全/隐私保护
机房收费系统—— 一堆小问题1
机房收费系统—— 一堆小问题1
49 0
|
存储 缓存 Kubernetes
必看的dockerfile禁忌与建议!
必看的dockerfile禁忌与建议!
uiu
|
SQL 分布式计算 资源调度
【两万字总结】Spark安装部署与入门(一)
【两万字总结】Spark安装部署与入门(一)
uiu
1191 0
【两万字总结】Spark安装部署与入门(一)
uiu
|
存储 缓存 分布式计算
【两万字总结】Spark安装部署与入门(二)
【两万字总结】Spark安装部署与入门(二)
uiu
218 0
【两万字总结】Spark安装部署与入门(二)
|
Shell C++ Docker
dockerfile 几组易混命令找茬
dockerfile 几组易混命令找茬
dockerfile 几组易混命令找茬
|
存储 机器学习/深度学习 算法
大逆不道,从天界偷下来的算法修仙秘籍竟然传到你手上~~(结尾有彩蛋)
这有可能是你见过最离谱的标题 这有可能是你没见过的技术文章模式 我不知道我的选择是否正确,但是我的想法就是: 不再让技术冷冰冰,让所有人学习中获得快乐!
229 1