本次内容是关于Dockerfile定制镜像的教程,希望能够帮到您!!
前提:如果想要创建一个Dockerfile文件,只需要输入以下命令即可
vim Dockerfile
文件名必须为Dockerfile
Dockerfile基础指令
如果想要快速的构建一个Dockerfile文件,有两个指令是必备的
- FROM
- RUN
FROM(指定基础镜像)
在Dockerfile中,我们需要一个基础镜像作为Dockerfile运行基础,并且要将基础镜像命令声明在文件第一行上.
如:我们需要在docker中运行一个SpringBoot项目,该项目的JDK版本为11,则我们需要在Dockerfile的第一行中声明我们这个服务的基础镜像.
FROM openjdk:11
.......
RUN(执行命令)
RUN指令是用来执行命令行命令的,也就是说,你可以在RUN命令后面添加任何linux命令.命令会在构建Dockerfile镜像时执行。
Shell格式
RUN 命令
FROM openjdk:11
RUN echo '<h1>Hello!</h1>'>/usr/share/nginx/html/index.html
exec格式
RUN ["可执行文件","参数1","参数2"]
FROM openjdk:11
RUN ["echo","hello"]
如果要执行数行命令 ,可以使用以下格式
FROM centos:7
RUN yum -y install vim \
&& yum -y install net-tools
构建镜像
在写完Dockerfile后需要将其构建为镜像
docker build -t centos:v1 .
# -t 是打标签,就是给我们的镜像取一个名字
# . 及其重要,如果你的当前目录是在Dockerfile文件所在目录,这个.就会自动寻找当前目录下的Dockerfile
. 非常重要,如果在当前文件目录下有要执行的Dockerfile文件,就可以用.来代替Dockerfile的路径
案例:
构建一个Dockerfile,以centos7为基础镜像,并在构建镜像时执行下载vim操作并创建一个文件夹testDKF
FROM centos:7
RUN yum -y install vim \
&& mkdir testDKF
构建Dockerfile镜像
docker build -t centos:v1 .
查看镜像是否构建成功
docker images
[root@registry testdkf]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos v1 29510943d5e1 3 minutes ago 442MB
构建完成镜像后,就可以快乐的运行镜像了!!😀😀😀
#这里最后一位是镜像id,各位根据自己的镜像ID来进行更改
[root@registry testdkf]# docker run -it 29510943d5e1 /bin/bash
#查看是否创建了testDKF文件夹
[root@12f76ba2029d /]# ll
小贴士(错误解决方案):
如果您在运行centos服务的时候,用的是 docker run -d 29510943d5e1 命令,docker ps -a 后发现容器还没启动就已经结束了,那么是以下问题构成的。
- docker容器运行必须要有一个前台进程,如果没有前台进程的话,容器就会自动退出
- 如果运行容器的命令中不包含一直挂起的命令,容器就会自动退出
#运行centos容器时让他一直ping本地,达到占用前台的目的,这样就不会自动退出容器了
[root@registry testdkf]# docker run -d sh -c "ping 127.0.0.1" 29510943d5e1
#sh :shell脚本
# -c :后面接命令
#注意:sh -c 命令 要放在语句最后面才行
Dockerfile进阶指令
除了FROM,RUN以外,还有很多指令可以去运用于Dockerfile中,接下来我会一个个为您解释
COPY复制文件
COPY命令将构建上下文目录(就是Dockerfile文件所在目录)中的文件或目录复制到镜像内的目标路径位置
#COPY 主机目录文件或文件夹 镜像内的目标路径
#将主机内的test.txt文件复制到镜像内的testDFK目录下
COPY test.txt /testDKF/
注意:COPY可以有多条,也就是说我们可以在一个Dockerfile中写多个COPY
COPY test1.txt /testDKF
COPY test2.txt /testDKF
COPY test3.txt /testDKF
ADD复制文件(高级版)(不推荐使用)
ADD命令和COPY命令功能一样,都是用于复制文件到镜像内
ADD命令和COPY命令的不同
ADD命令可以支持url文件下载,也就是说如果我们在第一个参数处放一个url,他就会去下载这个url的内容然后复制到指定路径中
案例:
我们开了一个springBoot服务,服务中有一个文件,我们可以用ADD命令将该文件下载下来并放到镜像中的testDKF目录中.
ADD http://localhost:8080/test.txt /testDKF/
注意:ADD的会使镜像构建速度变慢,所以建议使用COPY,如果有需要解压的文件可以使用ADD命令!
CMD容器启动命令
CMD命令会在容器启动时执行
CMD命令和RUN命令一样,也是有两种写法
- shell格式: CMD 命令
- exec格式: CMD ["可执行文件","参数1","参数2"]
FROM centos:7
CMD ["ping","127.0.0.1"]
运行文件并查看启动的容器,发现COMMAND栏出现了我们CMD中指定的命令
[root@registry testdkf]#docker run -d f248b2636ad3
[root@registry testdkf]#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4af254777d58 f248b2636ad3 "ping 127.0.0.1" 2 seconds ago Up 1 second
ENTRYPOINT入口点
ENTRYPOINT入口点和CMD一样,都是在容器启动时执行命令的。
ENTRYPOINT ["java","-jar","/app.jar"]
这样就可以在容器运行时执行命令了。
ENV设置环境变量
ENV可以设置全局环境变量,可以供后面的命令配置时调用
命令格式为: ENV key value 或者 ENV key=value
FROM centos:7
ENV name="Jack"
RUN echo $name
CMD ["ping","127.0.0.1"]
调用环境变量时需要使用“$变量名”来进行调用
ARG构建参数
ARG构建参数和ENV的效果一样,都是用于设置环境变量的
不同点是:ARG命令在镜像构建完后是不会保存这些环境变量的值的。
我们可以将服务名赋值给ARG的变量,然后再FROM的时候调用他们,这样就可以在不改变Dockerfile的情况下构建出不同的镜像了。
命令格式:ARG 参数名=参数值
ARG DOCKER_LIBRARY="library"
FROM ${DOCKER_LIBRARY}/alpine
#如果想要在FROM后面再次调用ARG变量,需要重新声明才能使用
ARG DOCKER_LIBRARY="library"
echo ${DOCKER_LIBRARY}
当ARG命令在FROM之前时,只有FROM才可以调用,如果FROM以后的命令想要调用ARG变量时,需要在FROM后面再次声明ARG变量,后面的命令才可以调用ARG变量
VOLUME定义匿名卷
命令格式:VOLUME 路径
VOLUME在Dockerfile中就是一个声明,告诉后面来使用Dockerfile的使用者,我这里需要将该目录进行数据卷挂载,也防止后期用户误删容器导致数据丢失
#声明镜像内需要挂载的一个匿名卷
VOLUME /testDKF
在运行镜像的时候进行数据卷挂载,将容器内的目录映射到主机目录,也就是说如果我们的服务有很多配置文件,那么我们可以将容器内配置文件进行映射,将其映射到主机内
docker run -d -v /ttt/:/testDKF 84cdf5febee3
#-v 挂载数据卷
# -v 主机目录路径:容器内挂载目录路径
docker exec -it 84cdf5febee3 /bin/bash
#写入文件到/testDKF目录下
echo "hello">/testDKF/test.txt
这时候我们查看宿主机的/ttt/目录发现我们容器内部的test.txt文件以及同步到我们的/ttt/文件目录中了.
EXPOSE声明端口
EXPOSE声明端口就是给后来的使用者一个提示,告诉你我们暴露出去的端口是什么端口
FROM nginx
#声明nginx端口暴露出去的端口
EXPOSE 80
WORKDIR指定工作目录
WORKDIR是指定RUN命令执行的目录,搭配RUN命令使用
FROM centos:7
RUN mkdir "/testDKF"
WORKDIR "/testDKF"
RUN echo "hello">> test1234.txt
CMD ["ping","127.0.0.1"]
这下我们的test1234.txt文件就会出现在我们的/testDKF目录下了,也可以在我们的宿主机上的/tttt/目录中查看到test1234.txt文件
USER指定当前用户
USER和WORKDIR一样,只是USER是切换用户,注意,要切换的用户必须存在。
FROM centos:7
RUN mkdir "testDKF" && useradd -p testuser testuser
USER testuser
VOLUME /testDKF
CMD ["ping","127.0.0.1"]
HEALTHCHECK健康检查
--interval=<间隔>
:两次健康检查的间隔,默认为 30 秒;--timeout=<时长>
:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;--retries=<次数>
:当连续失败指定次数后,则将容器状态视为unhealthy
,默认 3 次。
一般来说,健康检查可以检验一条命令是否执行正确
HEALTHCHECK --interval=5s --timeout=3s \
CMD curl -fs http://localhost/ || exit 1
0:成功 1:失败 2:保留
LABEL指令
LABEL指令就是声明这个Dockerfile的作者,时间以及发布时间
命令格式:LABEL key=value
LABEL AUTHOR="CC"
OBBUILD指令(为他人做嫁衣,大好人是你😀)
ONBUILD命令:在子Dockerfile文件继承父Dockerfile后,父Dockerfile执行ONBUILD指定的命令
父Dockerfile
FROM centos:7
RUN echo "我是父Dockerfile"
ONBUILD RUN echo "你继承了我的衣钵"
CMD ["ping","127.0.0.1"]
将父Dockerfile构建镜像
docker build -t centos:v2 .
子Dockerfile
#这里继承了父Dockerfile文件的内容
FROM centos:v2
RUN echo "我是子Dockerfile"
将子Dockerfile构建
[root@registry testdkf]#docker build -t centosSon:v2 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos:v2
# Executing 1 build trigger
---> Running in c0511967ce02
继承我的衣钵吧
Removing intermediate container c0511967ce02
---> 509df76baee0
Step 2/2 : RUN echo "我是子Dockerfile"
---> Running in f6ccdc4100dd
我是子Dockerfile
Removing intermediate container f6ccdc4100dd
---> 7340ddc5d85c
Successfully built 7340ddc5d85c
Successfully tagged centos:v3
发现在构建子Dockerfile的过程中出现了父Dockerfile中的ONBUILD命令后的内容!!
以上就是Dockerfile相关的内容,欢迎各位评论教导,如果觉得文章还不错或者有什么地方不懂的,欢迎留言提问点赞😊😊😊