DockerFile使用
2023-05-21 本文已影响0人
轻轻敲醒沉睡的心灵
前面我们说了使用docker commit
命令来构建简单的镜像文件,但是有的镜像文件需要设置环境变量,安装很多东西,当然用前面的命令也能完成,但是Docker提供了更好的方式给我们,那就是Dockerfile
。
Dockerfile
是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。所有的操作都在这个文件中,更清晰明了的展现给我们。关键是,很长时间以后,我们忘记这个镜像的时候,回头来看看这个文件,能知道干了啥。
Dockerfile
涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等。
我用的docker是比较新的:
1. Dockerfile
- Dockerfile使用比较简单:
编写Dockerfile文件 --> docker build命令构建镜像 --> docker run依镜像运行容器实例
-
Dockerfile 是Docker官方提供的,文档地址:
https://docs.docker.com/engine/reference/builder/
。介绍了所有的命令和使用,可以自己看看了解。 -
在 编写 Dockerfile文件时,有几点需要注意
- 每条保留字指令都必须为
大写字母
且后面要跟随至少一个参数 - 指令按照从上到下,顺序执行
-
#
表示注释 - 每条指令都会创建一个新的镜像层并对镜像进行提交
- 每条保留字指令都必须为
-
Dockerfile执行的大致流程
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似
docker commit
的操作提交一个新的镜像层 - docker再基于刚提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
2. Dockerfile常用保留字指令
参考tomcat
的Dockerfile文件:https://github.com/docker-library/tomcat
,随便选一个版本都可以看。
-
FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from -
LABEL
用key=value
的键值对来展示镜像的信息的,维护者名字、邮箱、版本、描述等信息都可以。这些内容可以用docker image inspect
查看。MAINTAINER
已经启用了,在build时候会报错的,别用了,用这个替代。 -
ENV
用来在构建镜像过程中设置环境变量。这些环境变量可以在后续的其他指令中使用:ENV MY_PATH /usr/local/test # 使用 WORKDIR $MY_PATH
-
RUN
RUN
是在 docker build时运行的命令,有2种格式:- RUN <命令行命令>
# 等同于在终端操作的shell命令 RUN yum -y install vim
- exec格式:RUN ["可执行文件", "参数1", "参数2"]
# 等价于:nginx -c ./conf/nginx.conf RUN ["nginx", "-c", "./conf/nginx.conf"]
-
EXPOSE
当前容器对外暴露出的端口 -
WORKDIR
指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点 -
USER
指定该镜像以什么样的用户去执行,如果都不指定,默认是root
-
ADD
将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包 -
COPY
类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。2种格式:COPY src dest
-
COPY ["src", "dest"]
<src源路径>:源文件或者源目录;·<dest目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
-
VOLUME
容器数据卷,用于数据保存和持久化工作 -
CMD
指定容器启动后的要干的事情。需要注意几点:-
CMD
和RUN
一样,也有2种命令格式,格式也和RUN
一样 - Dockerfile 中可以有多个
CMD
指令,但只有最后一个生效 -
CMD
指令是在docker run 时运行 -
CMD
指令会被 docker run 之后的参数替换:tomcat的Dockerfile文件最后 有:CMD ["catalina.sh", "run"]
,是启动tomcat的,如果我们docker run时这样:docker run -it -p 8080:8080 tomcat9 /bin/bash
添加了自己的命令,那么当镜像启动时,里面的tomcat是没启动的,因为没执行CMD中的启动命令。
-
-
ENTRYPOINT
也是用来指定一个容器启动时要运行的命令。类似于CMD
指令,但是ENTRYPOINT
不会被docker run后面的命令覆盖, 而且docker run后面的命令行参数会被当作参数送给ENTRYPOINT
指令指定的程序。
有几点需要注意:- 如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效
- 在执行docker run的时候可以指定 ENTRYPOINT 运行所需的参数
- 当
ENTRYPOINT
和CMD
一起用时,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成:ENTRYPOINT "<CMD>"
。例如:
此时ENTRYPOINT ["nginx", "-c"] CMD ["/usr/local/nginx/conf/nginx.conf"]
CMD
被称作变参,如果docker run时不传参数,那么容器启动后,执行:nginx -c /usr/local/nginx/conf/nginx.conf
。如果docker run时指定了新的配置文件(docker run nginx:1.22 -c /etc/nginx/new.conf
),那么容器启动后,执行:nginx -c /etc/nginx/new.conf
3. Dockerfile自定义jdk8镜像
- 提前准备好文件:
文件
注意Dockerfile首字母D大写
- 提前准备好文件:
- 编辑Dockerfile文件
nano Dockerfile
# 写入以下内容
FROM centos:7
LABEL author="zrb" version="1.2"
LABEL description="centos with vim、network、jdk8"
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim编辑器
#RUN apt update
#RUN apt install vim
#RUN apt install net-tools
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u361-linux-x64.tar.gz /usr/local/java/
#配置java环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_361
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
- 构建镜像
构建命令:docker build -t myjdk8:1.1 .
注意:myjdk8是自定义的镜像名字,1.1是自定义的版本号。后面还有 空格 和.
build
- 构建镜像
-
启动容器测试
测试
-
想要用Dockerfile构建自己的jar包,参考下面文章:
Dockerfile构建微服务镜像:Docker实用-微服务Jar包