前言
什么是Dockerfile
Dockerfile可以认为是Docker镜像的描述文件,是由一系列命令和参数构成的脚本。主要作用是用来构建docker镜像的构建文件。
以下是本篇文章正文内容,如果某些知识点错误 请指正!谢谢
1.Dockerfile
1.1 Dockerfile的架构图
1.2 Dockerfile解析过程
1.3 Dockerfile的保留命令
官方说明:https://docs.docker.com/engine/reference/builder/
保留字 | 作用 |
---|---|
FROM | 当前镜像是基于哪个镜像的 第一个指令必须是FROM |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 构建镜像时需要运行的指令 |
EXPOSE | 当前容器对外暴露出的端口号 |
WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar包 |
COPY | 类似于ADD,拷贝文件和目录到镜像中 将从构建上下文目录中<原路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker |
ENTRYPOINT | 指定一个容器启动时要运行的命令 ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及其参数 |
1.3.1 FROM 命令
-
基于那个镜像进行构建新的镜像,在构建时会自动从docker hub拉取base镜像 必须作为Dockerfile的第一个指令出现
-
语法:
FROM <image> FROM <image>[:<tag>] 使用版本不写就默认为latest FROM <image>[@<digest>] 使用摘要
1.3.2 MAINTAINER 命令
-
镜像维护者的姓名和邮箱地址[废弃]
-
语法:
MAINTAINER <name>
1.3.3 RUN 命令
-
RUN指令将在当前映像之上的新层中执行任何命令并提交结果。生成的提交映像将用于Dockerfile中的下一步
-
语法:
RUN <command> (shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows) RUN echo hello RUN ["executable", "param1", "param2"] (exec form) RUN ["/bin/bash", "-c", "echo hello"] 例如: #创建镜像以centOS7为基础 FROM centos:7 #往改镜像里边添加vim命令 RUN yum install -y vim #还可以是json格式的同上一个作用 RUN ["yum", "install", "-y", "vim"]
1.3.4 EXPOSE 命令
-
用来指定构建的镜像在运行为容器时对外暴露的端口
-
语法:
#如果没有显示指定则默认暴露都是tcp EXPOSE 80/tcp EXPOSE 80/udp 例如: #容器对外暴漏8080,日后你才能用你的端口去映射这个8080,如果不暴漏就不能有-p映射了(-p 8081:8080 -p8085:8080) EXPOSE 8080
1.3.5 CMD 命令
-
用来为启动的容器指定执行的命令。
-
注意: Dockerfile中只能有一条CMD指令。如果列出多个命令,则只有最后一个命令才会生效。
-
语法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form) CMD ["param1","param2"] (as default parameters to ENTRYPOINT) CMD command param1 param2 (shell form) 例如: # 查看某个文件 CMD ls /xxx # 固定命令则在ENTRYPOINT中指定,也就是说 /xx 是一个参数、一个变量 根据用户输入的参数去动态显示,一般和ENTRYPOINT结合使用 CMD /xx # json格式查看某个文件 CMD ["ls","xxx"]
1.3.6 WORKDIR 命令
-
用来为Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续Dockerfile指令中使用,它也将被创建。
-
语法:
Dockerfile文件内容: FROM centos:7 WORKDIR /a WORKDIR b WORKDIR c #进入 使用此文件构建的镜像 生成的容器的默认目录就为: [root@5d6f802d496e c] pwd /a/b/c #注意:WORKDIR指令可以在Dockerfile中多次使用。如果提供了相对路径,则该路径将与先前WORKDIR指令的路径相对
1.3.7 ENV 命令
-
用来为构建镜像设置环境变量。这个值将出现在构建阶段中所有后续指令的环境中(相当于将公共的抽离出来了)。
-
语法:
ENV <key> <value> ENV <key>=<value> ...
1.3.8 ADD 命令
-
用来从context上下文复制新文件、目录或远程文件url,并将它们添加到位于指定路径的映像文件系统中。
-
语法:
ADD hom* /mydir/ 通配符添加多个文件 ADD hom?.txt /mydir/ 通配符添加 ADD test.txt relativeDir/ 可以指定相对路径 ADD test.txt /absoluteDir/ 也可以指定绝对路径 ADD url relativeDir/ 将指定url的地址的文件下载至镜像中的指定目录
1.3.9 COPY 命令
-
用来将context目录中指定文件复制到镜像的指定目录中
-
语法:
COPY src dest src:需要copy的文件 dest:copy到容器的指定目录
1.3.10 VOLUME 命令
-
docker run 命令的-v标识创建的挂载点只能对创建的容器有效
-
通过doakerfile的 VOLUME指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点
-
通俗讲:通过 VOLUME 指令创建的挂载点,在通过该镜像创建容器的时候无法指定主机上对应的目录,因为它是自动生成的
例如: VOLUME ["/data"] # 然后通过docker inspect 查看通过该dockerfile创建的镜像生成的容器,可以看到如下信息: "Mounts": [ { "Name": "d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21", "Source": "/var/lib/docker/volumes/d411f6b8f17f4418629d4e5a1ab69679dee369b39e13bb68bed77aa4a0d12d21/_data", "Destination": "/data", "Driver": "local", "Mode": "", "RW": true }, #Dockerfile文件中使用VOLUME指令指定了挂载点,那么在通过该镜像文件创建的容器的时候,它会自动的将指定的挂载点挂载到主机中(自动创建的)
1.3.11 ENTRYPOINT命令
-
用来指定容器启动时执行命令和CMD类似
-
语法:
["executable", "param1", "param2"] JSON格式 ENTRYPOINT command param1 param2 例: [root@localhost dockerfile]# docker run -d -p xxxx:xxxx -entrypoint=固定命令 --name 名字 镜像名字:版本 要执行的命令参数
ENTRYPOINT指令,往往用于设置容器启动后的第一个命令,这对一个容器来说往往是固定的。
CMD指令,往往用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是变化的。
通常这两个指令联合使用,ENTRYPOINT用于指定固定命令,而CMD设置默认参数(这个参数是可变的,根据用户输入的参数而决定)
1.4 dockerfile命令实践,定制一个基于 centOS 7 的镜像
# Dockerfile 文件
# 定制的镜像是以centos7为基础的
FROM centos:7
# 用于执行创建vim命令的命令行
Run yum install -y vim
// 容器先对外暴漏8080,日后你才能用你的端口去映射这个8080,如果不暴漏就不能有-p映射了
EXPOSE 8080
# 指定进入容器时的目录为 /data/a/b/tomcat
WORKDIR /data
WORKDIR a
WORKDIR b
WORKDIR tomcat
# 创建环境变量,/data/a/b为公共的,后续都要用到(抽离出来,达到复用)
ENV BASE_DIR /data/a/b
# 创建容器时将指定的文件解压到指定的目录 这里使用了上边定义的环境变量BASE_DIR:/data/a/b/tomcat
ADD apache-tomcat-8.5.61.tar.gz $BASE_DIR
# 将解压完的文件移动到tomcat目录下
RUN mv apache-tomcat-8.5.61 tomcat
# 创建容器时候指定目录/data/a/b/tomcat/webapps为挂载点
VOLUME $BASE_DIR/tomcat/webapps
# 容器创建完毕执行的命令:执行ls命令查看/data/a/b/tomcat目录下的文件,如果想覆盖 必须在执行run创建容器时,添加--entrypoint ls然后在写目录才能覆盖
# ENTRYPOINT ls $BASE_DIR/tomcat
# cmd可以有多个,但是最终以最后一个为主,还有一点 如果在执行run创建容器的时候,添加了参数(echo "I love docker"),那么cmd的ls查看命令将会被覆盖
CMD ls $BASE_DIR/tomcat
1.5 测试(代码):将ENTRYPOINT和CMD结合来使用(必须使用json格式)
############################### Dockerfile 文件的编写
# 一般来说 ENTRYPOINT和CMD结合来使用
ENTRYPOINT ["ls"]
# 如果日后将cmd中的值覆盖了,就会传给ENTRYPOINT
CMD ["/data/bb"]
############################### 两种形式执行命令:
# 1.如果默认不指定参数,容器内会默认运行此命令:ls /data/bb
[root@localhost dockerfile]# docker run 镜像名:版本
#运行结果:
/data/bb:
tomcat
# 2.如果指定参数,容器内会默认运行此命令:ls /data/bb/tomcat
[root@localhost dockerfile]# docker run 镜像名:版本 data/bb/tomcat
#运行结果:
/data/bb/tomcat:
xxx.md
xx
xxxx
x.txt
x
x
x.txt
xx.md
总结:ENTRYPOINT用来写固定的命令,CMD用来传参,将来可以将java项目的固定命令(java -jar)写在ENTRYPOINT中(ENTRYPOINT[“java”, “-jar”] ),而jar包名字可以当作参数传进来(CMD[“xxx.jar”])。
2.Dockerfile实操
1.准备springboot项目,准备完毕测试成功,然后将该项目打包成jar包
2.将可运行项目的jar包放入linux虚拟机中
2.1 构建springboot项目部署
2.1.1 编写Dockerfile
# 基于 openjdk:8-jre 为基础镜像进行构建
FROM openjdk:8-jre
# 进入这个容器的目录指定为/app
WORKDIR /app
# 将jar包放入/app目录下,并重新命名为app.jar
ADD demo-0.0.1-SNAPSHOT.jar app.jar
# 该项目使用的是8081端口,所有需要向外暴漏8081端口,日后才能通过映射的端口去访问这个暴漏的端口
EXPOSE 8081
# ENTRYPOINT 和 CMD 结合使用,ENTRYPOINT固定命令,CMD根据参数的不同 运行不同的jar包(动态参数)
ENTRYPOINT ["java","-jar"]
CMD ["app.jar"]
# 相当于 java -jar xxx.jar
2.1.2 构建镜像
[root@localhost demo]# docker build -t demo:01 .
2.1.3 运行镜像
[root@localhost demo]# docker run -d -p 8081:8081 --name demo demo:01
2.1.4 查看项目部署是否成功
通过 ip -a 查询虚拟机ip地址
http://虚拟机ip地址:8081/hello
2.1.4.1 查看虚拟机IP地址
2.1.4.2 查看springBoot项目接口
2.1.4.3 成功访问hello接口
2.1.4.4 查看项目日志
2.2 IDEA SFTP远程连接部署项目(相对操作简单)
还有一种使用IDEA SFTP远程连接直接可以项目的jar包放入linux虚拟机中、编写Dockerfile文件(还自带提示,前提是安装了Dockerfile插件)
2.2.1 创建一个springBoot的项目,创建时只需勾选web依赖(目录结构如下)
2.2.2 安装Docker插件
2.2.2 进行SFTP连接虚拟机或者是自己的个人服务器
2.2.3 将springboot项目生成jar包
打开IDEA左下角的Terminal 执行如下命令
mvn package
target文件夹下生成 jar和jar.original 两个文件,说明打包成功!!
注意打包项目出现Process terminated 就看以下解决方案!!!
注意:如果出现以下情况
将VM Options中的值如果是 architectCatalog=internal 就加上 -D ,-DarchitectCatalog=internal;反之久去掉-D
在IDEA中编写Dockerfile文件
直接将构建镜像的两个文件拉入上下文目录