Docker学习:Dockerfile八大核心命令 | Dockerfile的使用 | ADD和COPY的区别

前言 

本讲是从Docker系列讲解课程,单独抽离出来的一个小节,重点介绍:Dockerfle基础命令和 Dockerfile的使用,提升自己的同时,希望对你也有所帮助。 

概述

1.Dockerfile是什么

它是一个没有后缀名的文本文档,里面是组合镜像的一些命令,Docker build命令构建镜像时,通过读取Dockerfile中的指令的顺序(自上到下)自动生成镜像。

的存在就好比自动驾驶技术中的导航功能(解放了驾驶员的双手)。
只需定义出发地、目的地,当然也可以定义更为详细行程路线。 

2.Dockerfile怎么使用

语法: docker build -t  -f Dockerfile目录  机构/镜像名<:tags> 
注:Dockerfile如果是在当前目录,可不用-f指定-t 构建镜像前自动检测dockerfile语法

3.Dockerfile内容怎么定义

FROM tomcat:latest 用于设置基准镜像(在哪个镜像基础上,进一步扩展)
MAINTAINER succ.com 维护者(镜像所属团体)
WORKDIR /usr/local/tomcat/webapps 用于切换工作目录(如果不存在会自动创建)
ADD docker-web ./docker-web 将宿主机当前目录下的文件复制到容器内指定目录下


下面依次介绍8大核心命令释义用法示例,它们都是在Dockerfile中编写的,都是大写

 vim Dockerfile  #这个文件没有后缀

一、FROM 指定基准镜像

指定当前镜像,以哪个镜像的哪个版本为依托,继续构建新的镜像。

语法 

FROM <image>              #仅指定镜像名称,不指定版本号(默认是latest版本
FROM <image>:<tag>  #指定镜像名称+版本号
FROM <image>@<digest>  #指定镜像名称+校验序列号 

注:#docker images --digests  获取镜像digests,当镜像内容发生变化时,digest也会随之变化。

FROM nginx
FROM nginx:1.18.0-alpine
FROM node:12.18.4-alpine@sha256:757574c5a2102627de54971a0083d4ecd24eb48fdf06b234d063f19f7bbc22fb

注意事项

如无特殊需求,我们一般会选择一个较为稳定,且体积比较小的alpine版本或者simp版本。

如何查找指定版本镜像,点击这里

二、MAINTAINER& LABEL 描述性/说明信息

作用:增强镜像的阅读性,不会对功能造成影响,建议详细描述!

MAINTAINER  指明镜像的归属者维护团体/机构名称/域名仅此一份

LABLE 更为详细的一些描述信息 (可有多份,且可以自定义) 

#这里写了多份,仅为展示效果,实际只能有一份
MAINTAINER china.succ
MAINTAINER mayun
MAINTAINER mayun@qq.com
LABEL version = "1.0"
LABEL description="succ.edu"
LABEL createdate ="2022-05-01"

三、WORKDIR 设置工作目录

WORKDIR 设置的,目录需要是绝对路径,如果不存在,会自动创建。

在Dockerfile最外层首次出现,则是指明通过docker exec -it 进入容器内部后,默认进入的工作目录(无需再用cd命令切换)。

如果Dockerfile中命令比较多,需要来回切换工作目录,则可以随时再次定义新的WORKDIR

WORKDIR /usr/local
WORKDIR /usr/local/newdir #如果不存在会被自动创建,尽量使用绝对路径

四、ADD & COPY 将宿主机的文件上传到镜像中

区别和作用

add除了复制,还具备添加远程文件功能(文件以http://开头),类似于linux的wget

add是增强版的copy,add自带解压,copy不带解压。两者支持目录中有空格

注意事项

1、ADD指令不支持认证,从远程获取资源如果需要认证(交互),则只能使用RUN wget或RUN curl替代。

2、如果不是需要解压,优先使用COPY命令,效率更高、更节省资源。 

ADD hello  /         #把hello从宿主机复制到容器内部的根路径
ADD test.tar.gz  /   #把压缩包从宿主机添加到容器的根目录后,自动解压
ADD hello .          #把hello文件复制到当前workdir工作目录的根目录
COPY test.txt /etc/nginx   #仅从宿主机复制文件到容器内部的指定目录
ADD demo.tar.gz /usr/share/nginx/html   #复制文件,并自动解压到指定目录

命令解析: ADD  (宿主机目录+)文件 空格  (容器内目录+)文件

宿主目录,默认是执行docker build时所在的宿主机目录 ;空格 ;示例中,后面的/是指容器内部跟目录,而 . 是容器内部的当前目录(默认是WORKDIR的目录

五、ENV 设置环境常量

简单的说,它就是一个全局常量,被设置后,进入容器内部,在任意位置都可以访问这个常量的值,比如# echo $var_bl

好比本地设置了JAVA_HOME环境变量一样,在CMD窗口任意目录,都可以打印/获取该常量。 

ENV WORKPATH /tmp
ENV http_proxy ""
ENV JAVA_HOME /usr/local/openjdk8
ENV test=mayun-xiaoma
ENV mycat=mimi

RUN $JAVA_HOME/bin/java-jar test.jar

尽量使用环境常量,可提高程序维护性,如果JAVA_HOME需要调整为其他JDK版本,那么只需要调整一处位置即可,比如把/usr/local/openjdk8调整为jdk9。

注意:这些环境常量可以通过docker run命令的--env 或-e参数来进行修改

六、RUN & CMD & ENTRYPOINT 运行指令

三者都是执行命令,但是它们的执行时机是不同的

RUN 仅在Build构建时执行的命令
CMD 用来设置容器启动后默认执行的命令(参数),它可被docker run后面的命令参数替换;
ENTRYPOINT 容器run启动时执行的命令

1.RUN 生成镜像时需要执行的命令 

#示例,演示run命令的两种不同写法
RUN yum install -y vim #Shell命令格式 
RUN ["yum "," install" ,"-y","vim"] #Exec命令格式

Dockerfile中的RUN命令,只有在docker build 命令构建镜像时会自动运行,docker run的时候,并不会运行(注意,部分精简版的镜像,本身只提供最基础的linux命令比如vi,不自带vim)。

扩展:

1.shell运行方式

使用Shell执行时,当前shell是父进程,生成一个子shell进程。
在子shell中执行脚本。脚本执行完毕,退出子shell,回到当前shell。
子进程的退出,不会对父进程造成任何影响。

2.exec运行方式官方推荐

使用Exec方式,会用Exec进程替换当前进程,并且保持PID不变。执行完毕,直接退出,不会退回之前的进程环境

2.CMD用来设置容器启动后默认执行的命令(参数)

作用:可以单独使用,但不一定会被执行,也可作为其他命令的补充参数使用

dockerfile 中如果存在多个CMD指令,仅能保证最后一个生效。

在dockerfile 文件中,RUN后面可以包含CMD命令,此时它前面的CMD可能会被忽略。

CMD echo "YYDS"
ENTRYPOINT echo "Hello world"
ENTRYPOINT ["ps"]
CMD ["-ef"]   #注:-ef 查看进程的完整格式,它不是一个单独的命令,而是ps后面跟的参数

注意:docker run命令末尾,可以添加参数覆盖Dockerfile中CMD的默认参数,更为灵活。 

下面run命令带的参数-aux,优先级比较高,会覆盖上面CMD ["-ef"],相当于把它替换为CMD ["-aux"]

docker run nginx:run -aux 

3.ENTRYPOINT 容器启动需要执行的命令

与cmd类似,也是容器启动时需要执行的命令(注意:需提前给Dockerfile脚本,赋予执行权限 chmod +x Dockerfile),但是不会被启动容器时指定的命令覆盖,只会将指定的命令当做参数传递给Dockerfile中的entrypoint。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序,从而覆盖其他 ENTRYPOINT 指令指定的程序;

语法格式:
ENTRYPOINT <command>ENTRYPOINT ["<executeable>","<param1>","<param2>",...]

RUN ["echo","image building!!"]
CMD ["-c"]   
ENTRYPOINT ["top","-b"] 

最后一个enterpoint一定会被执行,cmd就不同了,不一定会被执行。 

4.小结 

1.CMD命令,在Dockerfile中,可以单独使用,但不一定会被执行,也可以作为enterpoint命令的一部分,作为参数使用。 

2.ENTRYPOINT如果在Dockerfile中有多个,则仅最后一个会被运行。

3.如果在Dockerfile中即使用了ENTRYPOINT,也使用了CMD,两者会被合并执行,CMD可作为前者的默认参数使用

七、USER 指定运行容器时的用户名或 UID

Dockerfile指定USER用户后, 后续的命令 RUN、CMD、ENTRYPOINT 都将使用该用户

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

##Dockerfile内容
FROM nginx:1.18.0-alpine
USER root
docker build . -t nginx:user  #构建镜像
docker images   查看镜像列表
docker inspect nginx:user | grep User

八、EXPOSE声明对外暴露的端口

EXPOSE参数Dockerfile中是可以不写docker run -p时依然可以指定暴露端口),

为了规范化Dockerfile,让读者对其外暴露的端口一目了然,建议还是要写。

#docker run -d -p 8000:8080   

8080 就是容器内对外暴露的端口,-p 极具灵活性。 

#测试EXPOSE
FROM nginx:1.18.0-alpine
COPY 8080.conf /etc/nginx/conf.d
COPY index.html /usr/share/nginx
EXPOSE 8080

-p常见的有五种方式

1.宿主机随机端口,映射容器所有端口

#docker run -itd -P nginx /bin/bash 注意:这里是大写的P

2.宿主机随机端口,映射容器的指定端口

#docker run -itd -p 80 nginx /bin/bash 注:这个80是容器内的80端口

3.宿主机指定端口,映射容器指定端口(常用)

#docker run -itd -p 80:80 nginx /bin/bash
#docker run -itd -p 8080:80 nginx /bin/bash
#docker run -itd -p 443:443 nginx /bin/bash
#docker run -itd -p 80:80 -p 443:443 nginx /bin/bash
#docker run -itd -p 80:80 -p 443:443 --restart=always   nginx

4.宿主机指定指定IP+端口、映射到容器指定端口

#docker run -itd -p 172.0.0.10:8080:80 nginx /bin/bash 

5.宿主机指定IP+随机端口,映射容器指定端口

#docker run -itd -p 172.0.0.10::80 nginx /bin/bash 

如想对-p或-P有更更如的了解,点击进入 

九、总结

通过vim Dockerfile,把内容编辑好了,怎么用呢?

首先,需要docker bulid -t -f Dockerfile路径,来构建镜像

然后,用docker run 来运行容器(镜像是死的,只读的,容器是活的,它建立在镜像之上

最后,可以通过docker exec -it 进入容器内部

docker build .  -t nginx:env  #构建镜像

docker run -t --rm --name nginx-env nginx:env  #启动容器
docker run -it --rm --name nginx-env nginx:env /bin/sh  #启动容器,并进入容器内部

docker exec -it nginx:env  /bin/bash  #直接进入容器内部
echo $mycat #打印环境变量
mimi
exit 退#出容器,返回宿主机

注:--rm参数说明

Docker容器退出时,默认容器内部的文件系统仍然被保留,以方便调试并保留用户数据。

因此,可以通过--rm命令,让容器在退出(被关闭)时,自动清除挂载的卷,以便清除数据。 

还有两个次常用的命令,将会在后续,docker的高级应用K8s里陆续介绍。
VOLUME:容器数据卷(点击进入尝鲜
ONBUILD:当构建一个被继承的dockerFile时的运行命令,父镜像在被子镜像继承后,父镜像的onbuild被触发  

尾言

本讲内容是从 Docker入门到进阶里面抽离出来的内容,从而使原文更加有序、重点突出。希望对大家有所帮助,如果觉得还不错,动动小手,点赞表示支持一下吧。

附注

你还可能对以下内容感兴趣

1、如何获取Docker的最新版本 | 如何获取Tomcat/JDK/Nginx指定版本镜像

2、Docker学习必会的核心命令(pull、run、ps、images、build、exec)

3、配置阿里云镜像加速器,提高镜像下载速度

4、DockeFile的优化

5、Docker镜像分层 | 容器和镜像的关系

6、外部浏览器访问容器 | 容器访问容器 | 访问容器的常用5种方式 | -p -P 详解

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
COPYADD命令Dockerfile中都用于将文件从主机复制到容器中,但它们之间有一些区别COPY命令是比较简单和基础的文件复制命令,它的语法如下: ``` COPY <源路径> <目标路径> ``` 它将主机上的文件或目录从源路径复制到容器中的目标路径。一般来说,源路径可以是主机上的相对路径或绝对路径,而目标路径是容器内的路径。COPY命令只复制源路径中的文件或目录,不会进行任何解压缩或其他操作。 相比之下,ADD命令COPY命令的基础上提供了更多的功能。ADD命令的语法如下: ``` ADD <源路径> <目标路径> ``` 与COPY命令类似,它也将主机上的文件或目录从源路径复制到容器中的目标路径。但是,ADD命令有以下几个特性: 1. ADD命令支持自动解压缩功能。如果源文件是一个压缩包(如.tar、.tar.gz、.tar.bz2等),ADD命令会自动解压缩并将文件复制到目标路径。 2. ADD命令支持URL作为源路径。你可以直接指定一个URL作为源路径,Docker引擎会自动下载该URL指向的文件,并将其复制到目标路径。 尽管ADD命令提供了更多的功能,但在一般情况下,推荐使用COPY命令来复制文件。这是因为COPY命令更简单、更明确,而且不引入可能的副作用。只有在确实需要自动解压缩或从URL下载文件时,才考虑使用ADD命令。 希望这个解释对你有所帮助!如果你有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值