【Docker 学习十】DockerFile

【Docker 学习十】DockerFile
鱼六秒体验一下
创建dockerfile01文件
先创建一个dockerfile文件,名字可以随便命令,但建议就用dockerfile
1 | vi /home/dockerfile_01 |
编写dockerfile01
1 | # 文件中的内容指令(都是大写)参数 |
构建镜像:docker build命令:
用法
1 | docker build -f Dockerfile文件所在位置 -t 镜像名称:tag【可以说自定义版本号】 当前路径 |
docker build命令
1 | docker build -f /home/dockerfile_01 -t yulium/centos:1.0 . |
启动自己写的容器
用法
1 | docker run -it 镜像ID /bin/bash |
运行容器
1 | docker run -it yulium/centos:1.0 /bin/bash |
查看数据卷
1 | [root@70c4952c9d31 /]#ls |

退出容器并查看Mounts
1 | docker inspect 70c49 |
1 | [ |
测试一下:宿主机和容器的文件是否同步了
首先,在自己的容器volume01目录下创建文件
创建container.txt文件
1 | [root@0e5c1292b3af /]# touch volume01/container.txt |
查看宿主机volume01目录路径
1 | # 退出容器之后,查看有没有同步了 |
切换路径后用ls查看
1 | ls |
初识Dockerfile
命令脚本 -> 构建镜像 -> 启动容器 -> 查看Dockerfile就是用来构建docker镜像的构建文件和命令脚本,它就是一个命令脚本的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
基于Dockerfile构建镜像可以使用docker build命令。docker build命令中使用 -f 可以指定具体的dockerfile文件
默认情况下使用Dockerfile(D大写),docker build命令中不用指定就可以构建
构建步骤:
- 编写一个
dockerfile文件1
docker build -f /home/docker-test-volume/dockerfile1 -t yulium/centos .
docker build构建成为一个镜像1
docker run -it --name docker01 yulium/centos
docker run运行镜像docker push发布镜像(DockerHub、阿里云镜像仓库)
很多官方镜像都像是基础包,很多功能都不具备,我们通常会自己搭建自己的镜像!
官方既然可以制作镜像,我们也一样可以做!
Dockerfile构建过程
基础知识
每个保留关键字(指令)都是必须大写字母
执行从上到下顺序执行
#表示注释每个指令都会创建提交一个新的镜像层,并提交
DockerFile是面向开发的,我们以后要发布项目,做镜像,就需要编写dockefile文件,这个文件十分简单!
Docker镜像逐渐成为企业的交互标准,必须要掌握!
步骤:开发,部署, 运维… 缺一不可!
DockerFile:构建文件,定义了一切的步骤,源代码
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品!
docker build -f /dockerfile文件路径 -t 名称标签
Docker容器:容器就是镜像运行起来提供服务器
dockerfile指令
以前的话我们就是使用别人的,现在我们知道了这些指令之后,我们可以来练习自己写一个镜像
| 参数 | 含义 |
|---|---|
| FROM | 基础镜像,一切从这里开始构建 |
| MAINTAINER | 镜像是谁写的,姓名+邮箱 |
| LABEL | 添加镜像的元数据,使用键值对的形式。 |
| RUN | 镜像构建的时候需要运行的命令 |
| CMD | 指定这个容器启动时运行的命令 例:CMD echo,只有最后一个会生效,可被替代(可以被覆盖) |
| ENTRYPOINT | 指定这个容器启动的时候要运行的命令,可以追加命令(不可被覆盖) |
| EXPOSE | 暴露的端口 |
| ENV | 构建的时候设置环境变量 |
| ADD | 将文件、目录或远程URL复制到镜像中 |
| COPY | 类似ADD,将我们的文件拷贝到镜像中 |
| VOLUME | 挂载的目录 |
| WORKDIR | 镜像的工作目录 |
| USER | 指定后续指令的用户上下文 |
| ARG | 定义在构建过程中传递给构建器的变量,可使用 “docker build” 命令设置 |
| ONBUILD | 当构建一个被继承的dockerfile的时候就会运行ONBUILD的指令。触发指令(了解即可) |
| STOPSIGNAL | 设置发送给容器以退出的系统调用信号 |
| HEALTHCHECK | 定义周期性检查容器健康状态的命令 |
| SHELL | 覆盖Docker中默认的shell,用于RUN、CMD和ENTRYPOINT指令 |

FROM
基础镜像,必须是可以下载下来的,定制的镜像都是基于FROM的镜像,
比如用于centos就是定制需要的基础镜像。
后续的操作都是基于centos镜像
1 | 格式: |
MAINTAINER
用于指定镜像的维护者信息
1 | 格式: |
LABEL
用于向镜像添加元数据metadata
指令用来给镜像添加一些元数据(metadata),
这些标签可以包含关于镜像的信息,如作者、版本、描述、维护者等
LABEL指令是可选的
但它在构建镜像时为镜像添加了有用的描述性信息,有助于更好地管理和组织镜像库
1 | 以键值对的形式,格式: |
如果要查看镜像的labels,可以使用docker inspect命令
1 | "Labels": { |
RUN
指定在构建正在创建的映像,比如安装软件,下载文件等
包含两种模式Shell和exec
1 | 格式: |
CMD
用于docker run执行docker镜像构建容器时使用
与RUN不同,它不会为Image创建新层,而只是运行命令,每个Dockerfile/Image只能有一个CMD
- 一个
Dockerfile中只能包含一个CMD指令 - 如果有多个
CMD,则只有最后一个CMD指令会生效1
2
3
4
5格式:
CMD <command>
示例:
CMD /bin/bash -c ls
CMD python ./app.py
命令
此命令会在容器启动且docker run没有指定其他命令时运行。下面是一个例子:
1 | CMD echo "Hello world" |
运行容器 docker run -it [image] 将输出:
1 | Hello world |
但当后面加上一个命令,比如 docker run -it [image] /bin/bash,CMD 会被忽略掉,命令bash 将被执行:
1 | root@10a32dc7d3d3:/# |
类似于RUN指令,用于运行程序,但二者运行的时间点不同:
CMD在docker run时运行RUN是在docker build构建镜像时运行的
作用:
为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束
CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖.
ENTRYPOINT
ENTRYPOINT是Dockerfile中的一个重要指令,用于配置容器启动时的默认执行命令。
它类似于CMD指令,但有一些关键的区别
ENTRYPOINT指令的格式与CMD指令类似,可以使用Shell格式或数组格式,但在使用时,需要注意以下几点:
ENTRYPOINT指令的命令会在容器启动时始终执行,无论在docker run命令中是否指定了其他命令。它不会被覆盖,而是作为容器的主要执行命令- 如果在
docker run命令中指定了其他命令,这些命令将作为ENTRYPOINT指令的参数进行传递.也就是说,ENTRYPOINT指令中的命令将成为执行时的前缀
注意:如果Dockerfile 中如果存在多个ENTRYPOINT 指令,仅最后一个生效
下面是一个使用ENTRYPOINT指令的简单示例:
1 | FROM centos:latest |
如果我们构建该镜像并运行容器,不提供其他参数,那么容器启动后将输出"Hello":
1 | $ docker build -t my_image . |
如果我们在运行容器时提供了其他参数,那么这些参数将作为ENTRYPOINT指令中命令的参数:
1 | $ docker run my_image "World" |
将Dockerfile修改为:
1 | ENTRYPOINT ["/bin/echo", "Hello"] |
当容器通过docker run -it [image] 启动时,输出为:
1 | Hello world |
而如果通过docker run -it [image] yuliums 启动,输出依旧为:
1 | Hello yuliums |
Dockerfile中RUN,CMD和ENTRYPOINT都能够用于执行命令,下面是三者的主要用途:
RUN命令执行命令并创建新的镜像层,通常用于安装软件包CMD命令设置容器启动后默认执行的命令及其参数,但CMD设置的命令能够被docker run命令后面的命令行参数替换ENTRYPOINT配置容器启动时的执行命令(不会被忽略,一定会被执行,即使运行 docker run时指定了其他命令)
EXPOSE
用于声明容器在运行时监听的网络端口
作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射
- 在运行时使用随机端口映射时,也就是
docker run -p时,会自动随机映射EXPOSE的端口 - 可以是一个或者多个端口,也可以指定多个
EXPOSE上面的例子中,我们声明了容器将1
2
3
4格式:
EXPOSE <端口1> [<端口2>/<protocol>...]
示例:
EXPOSE 80监听80端口,而[<port>/<protocol>…]则表示可选的协议类型,例如TCP或UDP等
但是需要注意的是,EXPOSE并不会实际上打开该端口,也不会进行端口映射,
在使用docker run命令启动容器时,如果需要通过主机访问容器的80端口,还需要使用-p选项来进行端口映射。
例子:1
$ docker run -p 8080:80 my_image
ENV
用于设置环境变量
它允许在镜像构建过程中设置环境变量,这些环境变量将在容器运行时可用
1 | 格式: |
实例:可以使用多个ENV指令来设置多个环境变量
1 | FROM centos |
我们使用了两个ENV指令来设置两个环境变量:MY_NAME和APP_HOME
在镜像构建过程中,这些环境变量会被设置为指定的值
然后,在容器启动时,CMD指令中的命令将使用$MY_NAME环境变量的值输出问候语
在运行容器时,你可以通过docker run命令的-e选项来覆盖环境变量的值
1 | $ docker run -e MY_NAME="Alice" my_image |
上述命令将覆盖默认的MY_NAME环境变量值,容器将输出"Hello, Alice"。
ADD
用于将文件、目录或远程URL复制到镜像中
它类似于COPY指令,但在功能上更强大
1 | 格式: |
除了复制文件和目录,ADD指令还支持自动解压缩
如果source是一个压缩文件(例如.tar、.tar.gz、.tgz、.zip等)
那么ADD指令会自动解压缩该文件到destination指定的目录
实例:
复制本地文件到镜像中
1 | ADD app.py /app/ |
复制本地目录到镜像中
1 | ADD src/ /app/ |
从远程URL下载文件并复制到镜像中
1 | ADD https://example.com/file.tar.gz /tmp/ |
解压缩压缩文件并复制到镜像中
1 | ADD app.tar.gz /app/ |
COPY
COPY用于将本地文件或目录复制到镜像中
它不支持自动解压缩功能,与ADD指令相比,功能更简单明确
1 | 格式: |
复制本地文件到镜像中
1 | COPY app.py /app/ |
复制本地目录到镜像中
1 | ADD src/ /app/ |
VOLUME
用于声明容器中的挂载点(数据卷)
在启动容器docker run的时候,我们可以通过-v参数修改挂载点。
可以在一个Dockerfile中使用多个VOLUME指令来声明多个挂载点
1 | 格式: |
在运行容器时,可以使用-v选项或--mount选项来将主机的目录或数据卷映射到容器的挂载点。
例如:
1 | $ docker run -v /host/data:/app/data -v /host/logs:/app/logs my_image |
WORKDIR
用于设置工作目录,也称为当前工作目录
在容器启动时,进程的当前工作目录将被设置为WORKDIR指令所指定的目录必须是提前创建好的
1 | 格式: |
USER
用于指定在容器中运行镜像时要使用的普通用户
这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)
1 | 格式: |
默认情况下,Docker容器在启动时以root用户身份运行,这意味着容器内的进程具有最高权限.
然而,为了加强安全性,避免潜在的安全风险,最好以非特权用户的身份运行容器中的应用程序
实例
1 | FROM centos |
ARG
无论何种编程语言或脚本中,都不可避免的会应用到变量
用于定义变量,仅在建造当前镜像的过程中包括CMD和ENTRYPOINT有效,而要是镜像被创建了和运行容器之后,是作用失效了
语法
1 | 格式: |
如果你在Dockerfile中使用了ARG但并未给定初始值,则在运行docker build(编译)的时候未指定该ARG变量,则会失败。
若ARG指令具有默认值,并且在构建时没有传递值,则构建器将使用默认值
虽然其在容器启动后不再生效,但是不建议使用构建时变量来传递诸如github密钥、用户凭据等机密信息。
因为使用docker history命令,镜像的任何用户都可以看到构建时的变量值。
ARG 变量应用
可以使用ARG和ENV指令为RUN指令指定参数。
使用ENV指令定义的环境变量会覆盖ARG指令定义的同名变量
1 | FROM ubuntu |
实战测试
创建一个自己的centos
1 | root@localhost:~# cd /homet |
通过这个文件构建镜像
1 | docker build -f mydockerfile(dockerfile 文件路径) -t 镜像名:[tag] |
1 | root@localhost:/home/dockerfile# docker build -f mydockerfile -t yulium/centos:0.1 . |
如果报错信息
1 | dokcer给Centos配置时出现ERROR: failed to solve: process "/bin/sh -c yum -y install vim" did not complete s |
原因:是因为Docker默认拉取的是centos最新版,此时需要我们指定一下拉取的版本就比如:
1 | docker pull docker pull centos:7.9.2009 |
解决问题:
在我们的Dockerfile文件中编写
1 | #基于centos镜像创建 |
查看镜像
1 | docker images |
运行容器
1 | docker run -it 3bc65dff503e |
1 | [root@6d868b72593b local]# pwd |
1 | [root@6d868b72593b local]# ifconfig |
1 | eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 |
1 | [root@6d868b72593b local]# exit |
列出本地进行的变更历史
1 | docker history 3bc |
1 | IMAGE CREATED CREATED BY SIZE COMMENT |

