🍂Dockerfile自定义构建镜像+Docker插件实现远程部署springboot应用

Dockerfile构建镜像

Dockerfile构建镜像的流程

  • 首先 ,docker为CS架构(客户端-服务端),在虚拟机使用docker build, docker引擎会将Dockerfile的上下文目录(即Dockerfile所在的目录)的所有数据打包发送给docker服务端。
  • 接着,服务端开始运行dockerfile的内容,每执行dockerfile的一行代码,就会生成一个中间镜像层,当执行下一行代码时,就会生成一个在上一层基础上进行修改的中间镜像层,每一层都是在上一层的基础上进行修改而生成的,这也是为什么构建过程有"层叠"的概念。
  • 最后,当执行到最后一行,最后一次创建的中间镜像层就会成为最终镜像。它代表了 Dockerfile 中所有指令的执行结果和镜像的最终状态。
  • 注意:这些产生的中间镜像层(包括最终镜像)会被缓存到Docker本地镜像仓库里,如果不想要这些缓存,比如说想构建一个同名但是全新(可以理解dockerfile的代码发生变化)的镜像,就要在dockerbuild后加一个参数-no-cache,加了会忽略本地镜像缓存。

Dockerfile命令

FROM

  • Dockerfile的第一条指令必须为From,如果创建多个镜像在同一个dockerfile,就可以用多个FROM,一个FROM代表一个镜像。
  • 语法格式:
css 复制代码
FROM 镜像名称
# 或者
FROM 镜像名称:版本号

MAINTAINER

  • 用于指定维护者信息,也可以叫作者信息
  • 语法格式:
less 复制代码
MAINTAINER 维护者信息(eg:yourName  yourQQ@qq.com)

RUN

  • RUN 指令将在当前镜像基础上执行指定命令,并提交为新的中间镜像层,当命令较长时可以使用 \ 来换行
  • 语法格式:
bash 复制代码
RUN 执行的命令
#举例
RUN  echo 'Asia/Shanghai' >/etc/timezone

VOLUME

  • 基于镜像创建的容器添加数据卷,通过挂载将外部的目录或者其他容器的数据卷映射到该路径上,从而实现对数据的持久化
  • 语法格式:
bash 复制代码
VOLUME 外部路径:容器路径
#举例
VOLUME /tmp  
  • 举例中只写了一个路径的话就代表容器路径,会创建一个匿名卷挂载到容器的tmp目录,这样,容器中对 /tmp 目录的读写操作将直接映射到匿名卷上。
  • 默认情况下,Docker 会将匿名卷存储在位于宿主机的 /var/lib/docker/volumes/ 目录下。每个匿名卷都会以一个随机生成的唯一名称来标识,并在该目录下创建对应的子目录。

ADD

  • 将dockerfile所在目录中指定的文件复制到镜像的指定目录中
  • 同时可以识别远程URL,会自动下载URL对应的压缩包(不推荐使用)
  • 如果指定的文件是压缩包(如 .tar, .gz, .zip 等),会自动解压缩文件复制到镜像的指定目录中(单纯复制压缩包使用COPY指令)
  • 语法格式:
bash 复制代码
#格式1
ADD 外部文件路径  容器路径
#格式2(复制压缩包并重命名)
ADD 压缩包名字  重命名压缩包名字
#格式3(会自动解压缩)
ADD 压缩包名字  容器路径
#举例复制并重命名
ADD target/pms-boot.jar app.jar
#举例解压缩的情况
ADD my.zip  /data
  • 如果容器路径是一个具体的文件名而非目录名,那么外部文件会复制到镜像并重命名为该具体的文件名
  • 就是pms-boot.jar 复制过去后会重命名为app.jar ,该app.jar在镜像根目录。

COPY

  • 将dockerfile所在目录中指定文件复制到镜像的指定目录中
  • 语法格式
arduino 复制代码
#shell格式
COPY 源路径 目标路径

ENTRYPOINT

  • 指定容器启动时执行的命令
  • 与CMD类似
  • 不会被docker run的命令覆盖,但是docker run后面加 --entrypoint参数就可以被覆盖
  • docker run后面有参数的话会传给entrypoint
  • 可以是Shell格式,也可以是exec格式
  • 语法格式
bash 复制代码
ENTRYPOINT 命令
#举例shell格式
ENTRYPOINT java -jar /app.jar
#举例exec格式
ENTRYPOINT ["java","-jar","/app.jar"]
#举例docker run 传参
ENTRYPOINT echo "hello"
docker run 镜像:版本 "world"
最后容器会执行 echo "hello" "world" 输出是"hello world"

CMD

  • 指定容器启动后默认执行的命令和参数
  • CMD 在 Dockerfile 中可以有多个,但只有最后一个 CMD 会生效。多个ENTRYPOINT的话每个都会执行的。
  • docker run后面如果有命令会覆盖dockerfile中CMD的命令
  • 语法格式
objectivec 复制代码
#shell格式(不能传参)
CMD  命令
#exec格式(有两种)
CMD ["可执行文件","参数1","参数2",...]
CMD ["参数1","参数2"](作为ENTRYPOINT的默认参数)
  • 可以与ENTRYPOINT结合使用:
    • 如果 ENTRYPOINT 使用了 shell 模式,CMD 指令会被忽略(是结合的情况下会被忽略,如果cmd有可执行文件的话还是会执行)。
    • 如果 ENTRYPOINT 使用了 exec 模式,CMD 也应该使用 exec 模式,CMD指定的内容会被追加到ENTRYPOINT末尾当参数。
scss 复制代码
#举例1
ENTRYPOINT ["echo","hello"]
CMD ["world"]
最终会输出"hello world"
#举例2(当cmd的可执行文件跟entrypoint一样时就会传参,不一样就各自执行)
ENTRYPOINT["echo","hello"]
CMD ["echo","world"]
最终会输出"hello world"
#举例3
ENTRYPOINT["echo","hello"]
CMD ["world"]
dokcer run 镜像:版本 "china"
最终会输出"hello china"

WORKDIR

  • 指定容器工作目录,容器内没有指定的路径时会创建该路径

  • 语法格式

    WORKDIR 容器路径

  • 直接看个例子就明白了

bash 复制代码
WORKDIR /app
RUN touch file1.txt
WORKDIR subdir
RUN touch file2.txt
WORKDIR /data
RUN touch file3.txt
  • 首先设置了工作目录为 /app,然后在 /app 目录下创建了一个文件 file1.txt。
  • 接着 WORKDIR subdir 命令将当前的工作目录更改为 /app/subdir,然后在该目录下创建了文件 file2.txt。
  • 最后,WORKDIR /data 将工作目录更改为 /data,并在该目录下创建了文件 file3.txt。

USER

  • 指定镜像会以什么样的用户去运行,不指定默认容器会使用root用户来运行。
  • 注意:如果使用不存在的 用户或用户id,Docker 构建过程将会报错。
  • 语法格式
bash 复制代码
USER 用户名/用户id

ENV

  • 设置环境变量,这个环境变量在构建过程中和运行过程中都是有效的。比如说配置JDK环境
  • 语法格式
ini 复制代码
#格式1
ENV key=value
#格式2
ENV key value
#格式3(允许在多行上设置环境变量。使用 \ 进行换行)
ENV <key>=<value>  \
<key>=<value> \

#举例
ENV JAVA_HOME /usr/local/jdk1.8.0_121

ONBUILD

  • 在构建镜像的过程中设置一个触发器。这个触发器将在其他镜像继承(通过 FROM)当前镜像并构建新镜像时触发。
  • 语法格式
bash 复制代码
ONBUILD 命令
#举例
ONBUILD COPY . /app
ONBUILD RUN make /app
    • 这个例子ONBUILD 指令设置了两个触发器。当其他镜像继承(通过 FROM)当前镜像并构建新镜像时,将会按顺序执行这两个触发器。
    • 在继承当前镜像的新镜像的构建过程中,首先会复制当前工作目录中的所有文件到新镜像的 /app 目录中,然后通过 make 命令在 /app 目录中运行构建。

EXPOSE

  • 声明(暴露的意思)运行时容器提供服务端口,仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射。,它并不会实际上打开或监听端口。
  • 要容器内的服务可以让外部访问,您需要将容器内部的端口映射到主机上。这可以通过 Docker 命令行的 -p 或者 -P 参数来实现。
  • 语法格式:
erlang 复制代码
EXPOSE 端口1 端口2 ...

实战dockerfile自定义镜像

定义dockefile

bash 复制代码
FROM openjdk:8-jre
MAINTAINER whisper yourQQ@qq.com

RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone

# /tmp 目录作为容器数据卷目录,SpringBoot内嵌Tomcat容器默认使用/tmp作为工作目录,任何向 /tmp 中写入的信息不会记录进容器存储层,从而保证容器存储层的无状态化
# 在宿主机的/var/lib/docker目录下创建一个临时文件并把它链接到容器中的/tmp目录
VOLUME /tmp
#app.jar是自己命名的
ADD target/whisper-gateway.jar app.jar

ENTRYPOINT ["java","-Xmx128m","-Djava.security.egd=file:/dev/./urandom","-Dcsp.sentinel.app.type=1","-jar","/app.jar"]

EXPOSE 9999
  • 基础镜像选openjdk:8-jre(如果您的项目需要进行编译和打包操作,建议选择jdk。如果您只需运行已编译好的 Java 代码,可以选择jre)
  • 容器建立时运行cp指令,设置容器时区为当前时区
    • /usr/share/zoneinfo/Asia/Shanghai:操作系统中自带的时区文件
    • /etc/localtime :是容器自带的文件,/etc/localtime 文件是随着容器启动在容器内部创建的,它是通过复制来自主机操作系统的对应时区文件来初始化的。
  • 创建一个匿名卷挂载到容器的tmp目录,这样容器中对 /tmp 目录的读写操作将直接映射到匿名卷上。
  • 复制jar到镜像并重命名为app.jar
  • ENTRYPOINT
    • java:运行 Java 程序
    • -Xmx128m:设置 Java 虚拟机的最大堆内存为 128MB
    • -Djava.security.egd=file:/dev/./urandom:设置随机数生成器的算法为 /dev/./urandom,以提高随机性和性能
    • -Dcsp.sentinel.app.type=1:设置 Sentinel 应用程序的类型为 1。
    • -jar:指定要运行的 JAR 文件
    • /app.jar:指定要运行的 JAR 文件的路径。
  • 暴露端口9999

应用部署

下载Docker插件
配置pom.xml文件
  • 添加 spring-boot-maven-plugin 依赖
  • 指定 finalName 不带版本号的话,打包出的 jar 包名称就没有版本号
xml 复制代码
<build>
   <finalName>${project.artifactId}</finalName>
   <plugins>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <version>${spring-boot.version}</version>

         <configuration>

            <excludes>
               <!-- 打包忽略lombok(作用于编译阶段)-->
               <exclude>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
               </exclude>
            </excludes>

         </configuration>
      </plugin>
   </plugins>
</build>
Run/Debug Configurations 配置
  • Name:填写容器名
  • Server:选择你的docker容器(点击右边三个点)
  • Dockerfile:你的dockerfile文件路径
  • image tag:镜像名字:版本
  • container name:容器名字,当你用docker start 后面的容器名就是这个
  • Run option: 类似docker run 后面加的参数.
  • Before launch:程序执行前执行脚本
启动
相关推荐
Han.miracle几秒前
Spring WebMVC入门实战:从概念到连接建立全解析
java·spring boot·spring·springmvc
从零开始学习人工智能2 分钟前
《8076 能通 9003 却超时?一次 Docker 容器跨网段排障小记》
运维·docker·容器
Savvy..2 分钟前
RabbitMQ
java·rabbitmq·java-rabbitmq
TT哇3 分钟前
Spring Boot 项目中关于文件上传与访问的配置方案
java·spring boot·后端
程序员阿周4 分钟前
boost、websocketpp、curl 编译(Windows)
后端
踏浪无痕4 分钟前
信不信?一天让你从Java工程师变成Go开发者
后端·go
熊出没5 分钟前
Docker 实操命令大全
docker
浪里行舟5 分钟前
使用亚马逊云科技 Elemental MediaConvert 实现 HLS 标准加密
后端
峥嵘life6 分钟前
Android16 EDLA 认证测试BTS过程介绍
android·java·linux
韩立学长6 分钟前
Springboot考研自习室预约管理系统1wdeuxh6(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端