DockerFile详解——世上最全

文章目录
①. DockerFile是什么?
②. DockerFile构建过程解析
③. 保留字指令
①. FROM 基于哪个镜像
②. LABEL 镜像的说明信息
③. RUN
④. CMD、ENTRYPOINT 指定启动容器、镜像的默认入口
⑤. ARG 指定镜像内使用的参数
⑥. ENV 指定环境变量
⑦. ADD 、COPY 复制文件
⑧. WORKDIR 配置工作目录
⑨. VOLUME 创建数据卷挂载点
⑩. USER 指定运行容器时的用户名或UID
①. DockerFile是什么?
①. Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。

②. 构建三步骤(编写Dockerfile文件 | docker build | docker run)

③. 是什么样的?

 

④. 一般而言,Dockerfile可以分为四部分
基础镜像信息 维护者信息 镜像操作指令 启动时执行指令
# 这是我的第一个dockerfile镜像
FROM alpine
# 给镜像加注释信息
LABEL maintainer="TANGZHI " \
age=24
# 运行的指令、安装了软件、修改了文件,默认使用id=0的用户,也就是root,这个基础系统的root
# 代表镜像构建过程中的命令
RUN echo hellodockerfile
# 镜像启动要运行很长命令
# 1.准备一个sh文件 大多情况下
# 2.直接在CMD位置写即可
# 容器启动会执行的命令
CMD sleep 10;echo success②. DockerFile构建过程解析
①. Dockerfile内容基础知识
每条保留字指令都必须为大写字母且后面要跟随至少一个参数
指令按照从上到下,顺序执行
#表示注释
每条指令都会创建一个新的镜像层,并对镜像进行提交
②. 从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段 掌握
Dockerfile是软件的原材料
Docker镜像是软件的交付品
Docker容器则可以认为是软件的运行态

③. 保留字指令
指令 解释
FROM 基础镜像,当前新镜像是基于哪个镜像的。必须为第一个命令
MAINTAINER 镜像维护者的姓名和邮箱地址,现在推荐用LABEL maintainer=xxx 来替代
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露出的端口
WORKDIR 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
ENV 用来在构建镜像过程中设置环境变量
ADD 带copy并且由解压功能
COPY 类似ADD,拷贝文件和目录到镜像中
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT 指定一个容器启动时要运行的命令,使用docker run 之后的参数会进行一个叠加的操作
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
LABEL 用于为镜像添加元数据
ARG 指定镜像内使用的参数(如版本号信息等),可以在build的时候,使用–build- args改变 v
USER 指定运行容器时的用户名或UID
OBBUILD 配置当创建的镜像作为其他镜像的基础镜像是,所指定的创建操作指令
STOPSIGNAL 容器退出的信号值
HEALTHCHECK 健康检查
SHELL 指定使用shell时的默认shell类型


①. FROM 基于哪个镜像
①. 基础镜像,当前新镜像是基于哪个镜像的。必须为第一个命令

②. busybox:是一个集成了一百多个最常用Linux命令和工具的软件

③. Alpine:操作系统是一个面向安全的轻型Linux发行版经典最小镜像,基于busybox,功能比 Busybox完善(linux工具里的瑞士军刀)

④. slim:docker hub中有些镜像有slim标识,都是瘦身了的镜像

⑤. scratch:空镜像

②. LABEL 镜像的说明信息
标注镜像的一些说明信息
LABEL maintainer="TANGZHI " \
age=24③. RUN
①. RUN指令有两种形式,一种是shell,另外一个是exec形式

②. 在shell形式中,您可以使用\(反斜杠)将一条RUN指令继续到下一行
FROM alpine
LABEL maintainer="tangzhi"
ARG prams=helloword
RUN echo $prams &&\
echo tangzhi
RUN echo "123456"
RUN echo 123456789
# 这种方式取不到环境变量
RUN ["echo","$prams"]
# 下面这种写法和RUN echo 123456789等价
RUN ["/bin/sh","-c","echo $prams"][root@i-id8g0yu9 ~]# docker build -t mydockerfile4 -f dockerfile57 .
Sending build context to Docker daemon 3.119MB
Step 1/8 : FROM alpine
---> 6dbb9cc54074
Step 2/8 : LABEL maintainer="tangzhi"
---> Using cache
---> 3b6b777a2b23
Step 3/8 : ARG prams=helloword
---> Using cache
---> 80bcc56f3aee
Step 4/8 : RUN echo $prams &&echo tangzhi
---> Running in 9e1c545b68c9
helloword
tangzhi
Removing intermediate container 9e1c545b68c9
---> 93f7704f978b
Step 5/8 : RUN echo "123456"
---> Running in ae14d2044897
123456
Removing intermediate container ae14d2044897
---> 32ed2861f3e5
Step 6/8 : RUN echo 123456789
---> Running in 84db90a766c4
123456789
Removing intermediate container 84db90a766c4
---> d3fd8aeaec1f
Step 7/8 : RUN ["echo","$prams"]
---> Running in 99dddaaba442
$prams
Removing intermediate container 99dddaaba442
---> 31ed024c8569
Step 8/8 : RUN ["/bin/sh","-c","echo $prams"]
---> Running in 4fdfca35b59f
helloword
Removing intermediate container 4fdfca35b59f
---> a7457f8b7933
Successfully built a7457f8b7933
Successfully tagged mydockerfile4:latest
[root@i-id8g0yu9 ~]# ④. CMD、ENTRYPOINT 指定启动容器、镜像的默认入口
①. ENTRYPOINT或者CMD作为唯一入口,只能写一个,最后一个生效
#最终都是以ping tangzhi.com为准
CMD ping baidu.com
CMD ping tangzhi.com②. [“echo”,"${param}"] 不是bash -c的方式,取不出环境变量性[]
echo $param 等价于 ["/bin/sh","-c",“多长的命令都写在这里 echo ${param}”]
# CMD ["ping","baidu.com"]
# CMD ["useradd","-u","1000","-g","2000"]
# CMD ["ping","${url}"] 取不出变量
# CMD ping ${url} ③. 官方都是建议使用[ ]方式(CMD ["/bin/sh","-c",“ping ${url}”]),变化的写CMD,固定不变的写ENTRYPO INT(未来他是容器启动的唯一入口)
# 一旦传递了cmd1,CMD指定的所有参数都会被覆盖
# 在控制台输入 docker run imageName 6 tangzhi.com
# ping 5 -c baidu.com
CMD [ "5","baidu.com" ]
ENTRYPOINT [ "ping","-c" ]④. 我们使用ENTRYPOINT ping baidu.com的形式输出,那么组合CMD怎么写都没用,容器启动都是以ENT RYPOINT的完整命令为准
# 最终都是以ping baidu.com为准
ENTRYPOINT ping baidu.com
CMD ping tangzhi.com⑤. ARG 指定镜像内使用的参数
①. 定义以后的剩下环节生效(不包括运行环节),取值$param 不能使用在CMD或者ENTRYPO INT中

②. ARG指令定义了一个变量,用户可以在构建时使用–build-arg = 传递,docker build命令会将其传递给构建器。- -build-arg 指定参数会覆盖Dockerfile 中指定的同名参数
docker build --build-arg param=“xiaozhi” --build-arg message=“hellodockerbuild” --no-cache -t mydockerfile:v1 -f dockerfile3 .

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

④. ARG不像ENV 不能并排写

⑤. dockerfile文件如下:

# 可以在任意位置使用,并在以后使用
ARG version=3.13.4
# 这是我的第一个dockerfile镜像
FROM alpine:$version
# 给镜像加注释信息
LABEL maintainer="TANGZHI " \
age=24
# 运行的指令、安装了软件、修改了文件,默认使用id=0的用户,也就是root,这个基础系统的root
# 代表镜像构建过程中的命令
RUN echo hellodockerfile
RUN echo $param
# 定义以后的剩下环节生效(不包括运行环节),取值$param 不能使用在CMD或者ENTRYPOINT中
# 可以在构建期间进行变化,比如我们使用如下的命令
# docker build --build-arg param="xiaozhi" --build-arg message="hellodockerbuild" --no-cache -t mydockerfile:v1 -f dockerfile3 .
# ARG不像ENV 不能并排写
ARG param=helloparam
ARG message=hellodocker
# 构建时期会运行的指令(根据dockerfile创建一个镜像的整个过程时期)
RUN echo 1111
RUN echo $param
RUN echo $message
# 运行时期,我们会运行的指令(根据之前创建的镜像启动一个容器,容器启动默认运行的命令)
# docker run | docker start
# CMD和ENTRYPOINT 都是指定运行时的指令
# 当我们使用docker run -it 去执行的时候,发现只有1111输出
CMD ["/bin/sh","-c","echo 1111;echo $param"][root@i-id8g0yu9 ~]# docker build --build-arg param="xiaozhi" --build-arg message="hellodockerbuild" --no-cache -t mydockerfile3:v1 -f dockerfile3 .
Sending build context to Docker daemon 17.92kB
Step 1/11 : ARG version=3.13.4
Step 2/11 : FROM alpine:$version
---> 49f356fa4513
Step 3/11 : LABEL maintainer="TANGZHI " age=24
---> Running in 382d67fbac27
Removing intermediate container 382d67fbac27
---> bfa9c16b967a
Step 4/11 : RUN echo hellodockerfile
---> Running in 5cc88771ed37
hellodockerfile
Removing intermediate container 5cc88771ed37
---> 337c6e0404bd
Step 5/11 : RUN echo $param
---> Running in b88d4af5b1fa

Removing intermediate container b88d4af5b1fa
---> e129628435dd
Step 6/11 : ARG param=helloparam
---> Running in 5f10ed5dfa16
Removing intermediate container 5f10ed5dfa16
---> 9904bb5f44df
Step 7/11 : ARG message=hellodocker
---> Running in 50f117576dfa
Removing intermediate container 50f117576dfa
---> e6c1c8a36097
Step 8/11 : RUN echo 1111
---> Running in 1ae844ed29a6
1111
Removing intermediate container 1ae844ed29a6
---> 5947099a85ec
Step 9/11 : RUN echo $param
---> Running in c543d2f3ea4c
xiaozhi
Removing intermediate container c543d2f3ea4c
---> 8353cd041e74
Step 10/11 : RUN echo $message
---> Running in d58ac7513eac
hellodockerbuild
Removing intermediate container d58ac7513eac
---> 07f41021c095
Step 11/11 : CMD ["/bin/sh","-c","echo 1111;echo $param"]
---> Running in 5cacc787c157
Removing intermediate container 5cacc787c157
---> e9ed761f20bf
Successfully built e9ed761f20bf
Successfully tagged mydockerfile3:v1
[root@i-id8g0yu9 ~]# docker run -it mydockerfile3:v1 #注意这里没有输入echo $param
1111

[root@i-id8g0yu9 ~]#⑥. ENV 指定环境变量
①. 构建期+运行期都可以生效,但是只能在运行期进行修改

②. 构建期不能修改ENV的值(docker build)

③. 运行期docker run -it -e message=runENV

# 这是我的第一个dockerfile镜像
FROM alpine
# 给镜像加注释信息
LABEL maintainer="TANGZHI " \
age=24
ARG message=helloARG
# 构建期+运行期都可以生效,但是只能在运行期进行修改
# 构建期不能修改ENV的值(docker build)
# 运行期docker run -it -e message=runENV
ENV message=helloENV
# 构建时期会运行的指令(根据dockerfile创建一个镜像的整个过程时期)
RUN echo $message
# 运行时期,我们会运行的指令(根据之前创建的镜像启动一个容器,容器启动默认运行的命令)
CMD ["/bin/sh","-c","echo 1111;echo app_$message"][root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfilearg:v1 -f dockerfileArg .
Sending build context to Docker daemon 20.99kB
Step 1/6 : FROM alpine
latest: Pulling from library/alpine
540db60ca938: Pull complete
Digest: sha256:69e70a79f2d41ab5d637de98c1e0b055206ba40a8145e7bddb55ccc04e13cf8f
Status: Downloaded newer image for alpine:latest
---> 6dbb9cc54074
Step 2/6 : LABEL maintainer="TANGZHI " age=24
---> Running in f4c6286d7edc
Removing intermediate container f4c6286d7edc
---> 214a711d0c39
Step 3/6 : ARG message=helloARG
---> Running in a4e068cdd1a2
Removing intermediate container a4e068cdd1a2
---> d502358f547c
Step 4/6 : ENV message=helloENV
---> Running in 20fde633a7c2
Removing intermediate container 20fde633a7c2
---> 26bcd7c0386d
Step 5/6 : RUN echo $message
---> Running in 74d50778b66b
helloENV # 如果有ENV和ARY同时定义一个同名变量,我们使用的是ENV
Removing intermediate container 74d50778b66b
---> 6867c5ca1d40
Step 6/6 : CMD ["/bin/sh","-c","echo 1111;echo app_$message"]
---> Running in 1980007e51e0
Removing intermediate container 1980007e51e0
---> a5015b515b34
Successfully built a5015b515b34
Successfully tagged dockerfilearg:v1
[root@i-id8g0yu9 ~]# docker run -it -e message=runENV dockerfilearg:v1
1111
app_runENV
[root@i-id8g0yu9 ~]# ④. ENV在image阶段就会被解析并持久化(docker inspect image查看)参照下面示例
msg1=msg2没问题,如果我运行期间修改了msg1=66666的值,请问msg1、msg2输出什么?
结果输出 66666 hello
这是因为env坏境的信息会固化,直接在镜像配置里面就已经写死,msg1=hello msg2=hello,而-e只能修改当前env本身
# 这是我的第一个dockerfile镜像
FROM alpine
# 给镜像加注释信息
LABEL maintainer="TANGZHI " \
age=24
# msg1=msg2没问题,如果我运行期间修改了msg1=66666的值,请问msg1、msg2输出什么?
# 结果输出 66666 hello
# 这是因为env坏境的信息会固化,直接在镜像配置里面就已经写死,msg1=hello msg2=hello,而-e只能修改当前env本身
ENV msg1=hello
ENV msg2=$msg1
# 构建时期会运行的指令(根据dockerfile创建一个镜像的整个过程时期)
RUN echo $msg1
RUN echo $msg2
# 运行时期,我们会运行的指令(根据之前创建的镜像启动一个容器,容器启动默认运行的命令)
CMD ["/bin/sh","-c","echo $msg1;echo $msg2"][root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfilearg2:v1 -f dockerfileArg2 .
Sending build context to Docker daemon 22.53kB
Step 1/7 : FROM alpine
---> 6dbb9cc54074
Step 2/7 : LABEL maintainer="TANGZHI " age=24
---> Running in 6f6be6d001e0
Removing intermediate container 6f6be6d001e0
---> d3cef1d085a5
Step 3/7 : ENV msg1=hello
---> Running in dd2be1e7c37c
Removing intermediate container dd2be1e7c37c
---> 034e061f70cc
Step 4/7 : ENV msg2=$msg1
---> Running in 77908fc091f6
Removing intermediate container 77908fc091f6
---> 5c5499ac0a19
Step 5/7 : RUN echo $msg1
---> Running in 212c8ea2dcb2
hello
Removing intermediate container 212c8ea2dcb2
---> 5db13711e330
Step 6/7 : RUN echo $msg2
---> Running in 5e21ac6410e1
hello
Removing intermediate container 5e21ac6410e1
---> 4765e9d7d753
Step 7/7 : CMD ["/bin/sh","-c","echo $msg1;echo $msg2"]
---> Running in 67cb73e39262
Removing intermediate container 67cb73e39262
---> bf71cc3088ea
Successfully built bf71cc3088ea
Successfully tagged dockerfilearg2:v1
[root@i-id8g0yu9 ~]# docker run -it -e msg1=66666 dockerfilearg2:v1
66666
hello
[root@i-id8g0yu9 ~]# ⑦. ADD 、COPY 复制文件
①. ADD和COPY的功能是一样的,ADD多了自动下载远程文件和解压的功能
# 这是我的第一个dockerfile镜像
FROM alpine
# 把上下文context指定的内容复制到镜像中,如果是压缩包,自动解压,如果是远程文件,自动下载
# 把当前内容复制到alpine小系统里面
ADD https://download.redis.io/releases/redis-6.2.1.tar.gz /dest/
RUN ls -l
# RUN 指令上下并没有上下文关系
RUN cd /dest
# 当前还是列举的跟目录
RUN ls -l
RUN cd /dest && ls -l[root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfileadd:v1 -f dockerfileADD .
Sending build context to Docker daemon 27.65kB
Step 1/6 : FROM alpine
---> 6dbb9cc54074
Step 2/6 : ADD https://download.redis.io/releases/redis-6.2.1.tar.gz /dest/
Downloading [==================================================>] 2.438MB/2.438MB

---> 80aaa61dc520
Step 3/6 : RUN ls -l
---> Running in 1acdb19a9af4
total 8
drwxr-xr-x 2 root root 4096 Apr 14 10:25 bin
drwxr-xr-x 2 root root 32 Apr 18 12:53 dest
drwxr-xr-x 5 root root 340 Apr 18 12:53 dev
drwxr-xr-x 1 root root 66 Apr 18 12:53 etc
drwxr-xr-x 2 root root 6 Apr 14 10:25 home
drwxr-xr-x 7 root root 247 Apr 14 10:25 lib
drwxr-xr-x 5 root root 44 Apr 14 10:25 media
drwxr-xr-x 2 root root 6 Apr 14 10:25 mnt
drwxr-xr-x 2 root root 6 Apr 14 10:25 opt
dr-xr-xr-x 114 root root 0 Apr 18 12:53 proc
drwx------ 2 root root 6 Apr 14 10:25 root
drwxr-xr-x 2 root root 6 Apr 14 10:25 run
drwxr-xr-x 2 root root 4096 Apr 14 10:25 sbin
drwxr-xr-x 2 root root 6 Apr 14 10:25 srv
dr-xr-xr-x 13 root root 0 Apr 18 12:53 sys
drwxrwxrwt 2 root root 6 Apr 14 10:25 tmp
drwxr-xr-x 7 root root 66 Apr 14 10:25 usr
drwxr-xr-x 12 root root 137 Apr 14 10:25 var
Removing intermediate container 1acdb19a9af4
---> aff230b986d5
Step 4/6 : RUN cd /dest
---> Running in e154c1af02e8
Removing intermediate container e154c1af02e8
---> ef4756ff7262
Step 5/6 : RUN ls -l
---> Running in 32c3f351c176
total 8
drwxr-xr-x 2 root root 4096 Apr 14 10:25 bin
drwxr-xr-x 2 root root 32 Apr 18 12:53 dest
drwxr-xr-x 5 root root 340 Apr 18 12:53 dev
drwxr-xr-x 1 root root 66 Apr 18 12:53 etc
drwxr-xr-x 2 root root 6 Apr 14 10:25 home
drwxr-xr-x 7 root root 247 Apr 14 10:25 lib
drwxr-xr-x 5 root root 44 Apr 14 10:25 media
drwxr-xr-x 2 root root 6 Apr 14 10:25 mnt
drwxr-xr-x 2 root root 6 Apr 14 10:25 opt
dr-xr-xr-x 113 root root 0 Apr 18 12:53 proc
drwx------ 2 root root 6 Apr 14 10:25 root
drwxr-xr-x 2 root root 6 Apr 14 10:25 run
drwxr-xr-x 2 root root 4096 Apr 14 10:25 sbin
drwxr-xr-x 2 root root 6 Apr 14 10:25 srv
dr-xr-xr-x 13 root root 0 Apr 18 12:53 sys
drwxrwxrwt 2 root root 6 Apr 14 10:25 tmp
drwxr-xr-x 7 root root 66 Apr 14 10:25 usr
drwxr-xr-x 12 root root 137 Apr 14 10:25 var
Removing intermediate container 32c3f351c176
---> c45f1cca41d7
Step 6/6 : RUN cd /dest && ls -l
---> Running in c82e471ef25e
total 2384
-rw------- 1 root root 2438367 Mar 2 06:35 redis-6.2.1.tar.gz
Removing intermediate container c82e471ef25e
---> 5ac189b07621
Successfully built 5ac189b07621
Successfully tagged dockerfileadd:v1
[root@i-id8g0yu9 ~]# ②. 这里能使用docker build -t demo:test .的方式构建,是由于这个Dockerfile的文件在当前目录下,如果不在,那么需要将. 变成指定的文件夹
# 这是我的第一个dockerfile镜像
FROM alpine
# 把上下文context指定的内容复制到镜像中,如果是压缩包,自动解压,如果是远程文件,自动下载
# 把当前内容复制到alpine小系统里面
ADD https://download.redis.io/releases/redis-6.2.1.tar.gz /dest/
# 本地linux系统的内容文件添加进去[宿主机--镜像内]
# docker build -t demo:test .: .代表当前dockerfile指定的上下文坏境
# 通过执行我们可以看到,redis进行了自动解压的处理
ADD *.tar.gz /app/
# RUN 指令上下并没有上下文关系
RUN cd /dest && ls -l
RUN cd /app && ls -l[root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfileadd2:v1 -f dockerfileADD2 .
Sending build context to Docker daemon 2.468MB
Step 1/5 : FROM alpine
---> 6dbb9cc54074
Step 2/5 : ADD https://download.redis.io/releases/redis-6.2.1.tar.gz /dest/
Downloading [==================================================>] 2.438MB/2.438MB

---> b7598fcec68b
Step 3/5 : ADD *.tar.gz /app/
---> 9b222d9290b5
Step 4/5 : RUN cd /dest && ls -l
---> Running in 4a32a2a9866b
total 2384
-rw------- 1 root root 2438367 Mar 2 06:35 redis-6.2.1.tar.gz
Removing intermediate container 4a32a2a9866b
---> f72d59644485
Step 5/5 : RUN cd /app && ls -l
---> Running in 48fe6f35756f
total 4
drwxrwxr-x 7 root root 4096 Mar 2 06:14 redis-6.2.1
Removing intermediate container 48fe6f35756f
---> 762a609e68e9
Successfully built 762a609e68e9
Successfully tagged dockerfileadd2:v1⑧. WORKDIR 配置工作目录
①. 根目录,WORKDIR指令可在Dockerfile中多次使用。 如果提供了相对路径,则它将相对于上一个WORK DIR指令的路径(如下面的/app/abc是根目录)
FROM alpine

RUN pwd && ls -l
# 为以下所有命令运行指令了基础目录
# /app/abc
WORKDIR /app
# 当我们使用docker exec 进入容器控制台,会发现根目录是 /app/abc
WORKDIR abc
# 复制到当前目录下
COPY *.txt ./
RUN pwd && ls -l
CMD ping baidu.com[root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfileworkdir:v1 -f dockerfileWORKDIR .
Sending build context to Docker daemon 2.472MB
Step 1/7 : FROM alpine
---> 6dbb9cc54074
Step 2/7 : RUN pwd && ls -l
---> Running in 7ef554287c6f
/
total 8
drwxr-xr-x 2 root root 4096 Apr 14 10:25 bin
drwxr-xr-x 5 root root 340 Apr 18 13:54 dev
drwxr-xr-x 1 root root 66 Apr 18 13:54 etc
drwxr-xr-x 2 root root 6 Apr 14 10:25 home
drwxr-xr-x 7 root root 247 Apr 14 10:25 lib
drwxr-xr-x 5 root root 44 Apr 14 10:25 media
drwxr-xr-x 2 root root 6 Apr 14 10:25 mnt
drwxr-xr-x 2 root root 6 Apr 14 10:25 opt
dr-xr-xr-x 111 root root 0 Apr 18 13:54 proc
drwx------ 2 root root 6 Apr 14 10:25 root
drwxr-xr-x 2 root root 6 Apr 14 10:25 run
drwxr-xr-x 2 root root 4096 Apr 14 10:25 sbin
drwxr-xr-x 2 root root 6 Apr 14 10:25 srv
dr-xr-xr-x 13 root root 0 Apr 18 12:58 sys
drwxrwxrwt 2 root root 6 Apr 14 10:25 tmp
drwxr-xr-x 7 root root 66 Apr 14 10:25 usr
drwxr-xr-x 12 root root 137 Apr 14 10:25 var
Removing intermediate container 7ef554287c6f
---> 27e092e104fb
Step 3/7 : WORKDIR /app
---> Running in ee015d4b2a18
Removing intermediate container ee015d4b2a18
---> 4419d4f77345
Step 4/7 : WORKDIR abc
---> Running in bc8172263488
Removing intermediate container bc8172263488
---> e29383588c07
Step 5/7 : COPY *.txt ./
---> 715b2d4db2d9
Step 6/7 : RUN pwd && ls -l
---> Running in 5e5c8d7ab9b8
/app/abc
total 4
-rw-r--r-- 1 root root 5 Apr 18 13:46 a.txt
Removing intermediate container 5e5c8d7ab9b8
---> d196ffbdf968
Step 7/7 : CMD ping baidu.com
---> Running in e0b6b78b1eec
Removing intermediate container e0b6b78b1eec
---> a1be08fec3d1
Successfully built a1be08fec3d1
Successfully tagged dockerfileworkdir:v1
[root@i-id8g0yu9 ~]# docker run -d --name myworkdir dockerfileworkdir:v1
b4d8744b6a920fa5eea4b2388ede0e04489905a8449d0c2e40ef8d3d298cfecb
[root@i-id8g0yu9 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4d8744b6a92 dockerfileworkdir:v1 "/bin/sh -c 'ping ba…" 3 seconds ago Up 3 seconds myworkdir
[root@i-id8g0yu9 ~]# docker exec -it b4d8744b6a92 /bin/sh
/app/abc #⑨. VOLUME 创建数据卷挂载点
①. 把容器的某些文件夹映射到主机外部

②. 写法:这个一般写在最后
VOLUME ["/var/log/"] #可以是JSON数组
VOLUME /var/log #可以直接写
VOLUME /var/log /var/db #可以空格分割多个

③. 注意:用VOLUME声明了卷,那么以后对于卷内容的修改会被丢弃,所以一定在volume声明之前修改内容

FROM alpine

RUN mkdir /hello && mkdir /app
RUN echo 1111 > /hello/a.txt
RUN echo 2222 > /app/b.txt
# 挂在容器内的指定文件夹,如果不存在则创建
# 指定了volume,即使启动容器没有指定-v参数,我们也会自动进行匿名卷挂载
# 这里的 hello app 都是容器里面的文件夹,请你在使用镜像启动容器的时候,自动给宿主机上挂载
VOLUME [ "/hello","/app"]

# 用VOLUME声明了卷,那么以后对于卷内容的修改会被丢弃,所以一定在volume声明之前修改内容
RUN echo 6666 > /hello/a.txt
RUN echo 8888 > /app/b.txt
CMD ping baidu.com [root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfileworkvolume:v1 -f dockerfileVOLUME .
Sending build context to Docker daemon 2.474MB
Step 1/8 : FROM alpine
---> 6dbb9cc54074
Step 2/8 : RUN mkdir /hello && mkdir /app
---> Running in 36ed19f5446d
Removing intermediate container 36ed19f5446d
---> 42af237e9a7e
Step 3/8 : RUN echo 1111 > /hello/a.txt
---> Running in 662511d7ddb7
Removing intermediate container 662511d7ddb7
---> f744129965ae
Step 4/8 : RUN echo 2222 > /app/b.txt
---> Running in a8321f4f8d98
Removing intermediate container a8321f4f8d98
---> 1d03ca553eb7
Step 5/8 : VOLUME [ "/hello","/app"]
---> Running in 1d4ec1c1e8f7
Removing intermediate container 1d4ec1c1e8f7
---> 4e76b09577d3
Step 6/8 : RUN echo 6666 > /hello/a.txt
---> Running in 912d739bb4d4
Removing intermediate container 912d739bb4d4
---> da35323435dd
Step 7/8 : RUN echo 8888 > /app/b.txt
---> Running in bab5aceb4f7a
Removing intermediate container bab5aceb4f7a
---> 73c45738db48
Step 8/8 : CMD ping baidu.com
---> Running in 05bedb917269
Removing intermediate container 05bedb917269
---> a01440e2a675
Successfully built a01440e2a675
Successfully tagged dockerfileworkvolume:v1
[root@i-id8g0yu9 ~]# docker run -d dockerfileworkvolume:v1
56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc
[root@i-id8g0yu9 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56ef53c95a6c dockerfileworkvolume:v1 "/bin/sh -c 'ping ba…" 4 seconds ago Up 3 seconds stupefied_ptolemy
b4d8744b6a92 dockerfileworkdir:v1 "/bin/sh -c 'ping ba…" 49 minutes ago Up 49 minutes myworkdir
[root@i-id8g0yu9 ~]# docker inspect 56ef53c95a6c
[
{
"Id": "56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc",
"Created": "2021-04-18T14:45:15.782034507Z",
"Path": "/bin/sh",
"Args": [
"-c",
"ping baidu.com"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 8131,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-04-18T14:45:16.143344962Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:a01440e2a675dab49c9fb9c788e890c81913e7f15de3a4071fec51a5a5475aea",
"ResolvConfPath": "/var/lib/docker/containers/56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc/hostname",
"HostsPath": "/var/lib/docker/containers/56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc/hosts",
"LogPath": "/var/lib/docker/containers/56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc/56ef53c95a6c7f96a8cf308be8393ee53fb70a4802f7c43e4519cf5fab438abc-json.log",
"Name": "/stupefied_ptolemy",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/bca4693743c24765c88e89c05892e9b8f3f0b39918c5a400d58c9b9db5ec450c-init/diff:/var/lib/docker/overlay2/8623d3705ceea6e0f9349ac0645977e1fa8c45cc9ea6337115098c03d259a200/diff:/var/lib/docker/overlay2/960ab6c1f64fd999f44c90be57256371c1e5dd43f115e1d2ff11037408a8ffc8/diff:/var/lib/docker/overlay2/871b7ffab75435d24006f3f7bff690c903328b273764a7e4ab1922bece5b8ad7/diff:/var/lib/docker/overlay2/43d78cac3804ed1dc62283f315a185e8136796e5779d9ee8717fa9a2d99d6edd/diff",
"MergedDir": "/var/lib/docker/overlay2/bca4693743c24765c88e89c05892e9b8f3f0b39918c5a400d58c9b9db5ec450c/merged",
"UpperDir": "/var/lib/docker/overlay2/bca4693743c24765c88e89c05892e9b8f3f0b39918c5a400d58c9b9db5ec450c/diff",
"WorkDir": "/var/lib/docker/overlay2/bca4693743c24765c88e89c05892e9b8f3f0b39918c5a400d58c9b9db5ec450c/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "65adbd1e4997c8df05a05b30ab1a2c3df970e19b0dd38f579f428ec8442810b9",
"Source": "/var/lib/docker/volumes/65adbd1e4997c8df05a05b30ab1a2c3df970e19b0dd38f579f428ec8442810b9/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "1c3739d31bd487d847d0101ac2d48bbdb661cc9cbe97799de86181c2f50d98db",
"Source": "/var/lib/docker/volumes/1c3739d31bd487d847d0101ac2d48bbdb661cc9cbe97799de86181c2f50d98db/_data",
"Destination": "/hello",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "56ef53c95a6c",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
],
"Cmd": [
"/bin/sh",
"-c",
"ping baidu.com"
],
"Image": "dockerfileworkvolume:v1",
"Volumes": {
"/app": {},
"/hello": {}
},
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "d4490ef3887d03e22812b820c963c82a8edfe45c5f3141676a03df8d7aecfc51",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/d4490ef3887d",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "671b069ea364448c75dbbb4d9365c60b46abf392bdcca26bc9713cf9051baa2e",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:03",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "24c026c0a26cfb78a82f033887c3669c4ccaf63060e02fefe51e958cb5037c32",
"EndpointID": "671b069ea364448c75dbbb4d9365c60b46abf392bdcca26bc9713cf9051baa2e",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:03",
"DriverOpts": null
}
}
}
}
]
[root@i-id8g0yu9 ~]# cd /var/lib/docker/volumes/65adbd1e4997c8df05a05b30ab1a2c3df970e19b0dd38f579f428ec8442810b9/_data
[root@i-id8g0yu9 _data]# ls
b.txt
[root@i-id8g0yu9 _data]# cat b.txt # 注意这里还有追加6666或者8888
2222
[root@i-id8g0yu9 _data]# ⑩. USER 指定运行容器时的用户名或UID
# 这是我的第一个dockerfile镜像
FROM alpine
# 相当于给当前容器开一个用户,以后的命令可以用这个用户运行 有可能没有执行权限
# 容器中的ROOT虽然不是lunux宿主机的真实root,但是可以改掉这个镜像的所有
USER 1000:1000
# 不自动解压
# 以linux主机的用户为准,默认是root用户,如果我们不指定权限将复制失败
COPY --chown=1000:1000 *.txt /a.txt
# RUN 指令上下并没有上下文关系
RUN ls -l[root@i-id8g0yu9 ~]# docker build --no-cache -t dockerfileworkuser:v1 -f dockerfileUSER .
Sending build context to Docker daemon 2.473MB
Step 1/4 : FROM alpine
---> 6dbb9cc54074
Step 2/4 : USER 1000:1000
---> Running in 7d4fd2b2a54c
Removing intermediate container 7d4fd2b2a54c
---> 2561ad4ce2c2
Step 3/4 : COPY --chown=1000:1000 *.txt /a.txt
---> a21c8da0fb0c
Step 4/4 : RUN ls -l
---> Running in c9cbef9eac65
total 12
-rw-r--r-- 1 1000 1000 5 Apr 18 13:46 a.txt
drwxr-xr-x 2 root root 4096 Apr 14 10:25 bin
drwxr-xr-x 5 root root 340 Apr 18 14:22 dev
drwxr-xr-x 1 root root 66 Apr 18 14:22 etc
drwxr-xr-x 2 root root 6 Apr 14 10:25 home
drwxr-xr-x 7 root root 247 Apr 14 10:25 lib
drwxr-xr-x 5 root root 44 Apr 14 10:25 media
drwxr-xr-x 2 root root 6 Apr 14 10:25 mnt
drwxr-xr-x 2 root root 6 Apr 14 10:25 opt
dr-xr-xr-x 115 root root 0 Apr 18 14:22 proc
drwx------ 2 root root 6 Apr 14 10:25 root
drwxr-xr-x 2 root root 6 Apr 14 10:25 run
drwxr-xr-x 2 root root 4096 Apr 14 10:25 sbin
drwxr-xr-x 2 root root 6 Apr 14 10:25 srv
dr-xr-xr-x 13 root root 0 Apr 18 12:58 sys
drwxrwxrwt 2 root root 6 Apr 14 10:25 tmp
drwxr-xr-x 7 root root 66 Apr 14 10:25 usr
drwxr-xr-x 12 root root 137 Apr 14 10:25 var
Removing intermediate container c9cbef9eac65
---> db89e3d275a2
Successfully built db89e3d275a2
Successfully tagged dockerfileworkuser:v1
[root@i-id8g0yu9 ~]#
————————————————
版权声明:本文为CSDN博主「所得皆惊喜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/TZ845195485/article/details/115799569

posted @ 2021-07-20 17:10  tangy1  阅读(2532)  评论(0编辑  收藏  举报