前言

首先来了解下什么是Dockerfile

Dockerfile是一个包含命令和指令的脚本文件,用于构建Docker镜像。它包含了构建镜像的全部指令,可以使得从头开始构建一个完整的Docker镜像变得十分容易。

以下是Dockerfile的使用方法:

  1. 创建Dockerfile文件:在项目目录中使用文本编辑器创建Dockerfile文件并编写相应的指令。
  2. 编写Dockerfile指令:使用Dockerfile指令来构建镜像,例如FROMRUNCOPYCMD等等。
  3. 构建镜像:使用docker build命令构建镜像。例如:docker build -t imagename .
  4. 运行容器:使用docker run命令运行容器。例如:docker run -d -p 8080:8080 imagename
  5. 打包和分享镜像:可以使用docker savedocker load命令来打包和分享镜像。

以上是对dockerfile的一般理解和使用方法。

前提

  • 一个正常可打包的Spring Bootweb项目
  • 一个可用的云端镜像仓库
  • 一个可以本地连接使用的docker

正文

创建Dockerfile

首先在项目的根目录里创建Dockerfile文件,通过这个文件我们可以将我们的jar包打包进Docker镜像,随着镜像启动的同时,将我们的jar包也启动

# 该镜像需要依赖的基础镜像
FROM openjdk:8u322-oracle
# 将当前目录下的jar包复制到docker容器的/目录下
ADD target/my-demo.jar /my-demo.jar
# 运行过程中创建一个my-demo.jar文件
RUN bash -c 'touch /my-demo.jar'
# 声明服务运行在10316端口
EXPOSE 10318

# 指定docker容器启动时运行jar包
ENTRYPOINT ["java","-jar","/my-demo.jar","-Dfile.encoding=utf-8"]
# 指定维护者的名字
MAINTAINER xinwei

以上的操作是使用jdk8版本的程序,如果使用其他如jdk17版本,可以直接改变jdk的镜像版本即可。

这样我们就可以利用命令docker build -t my-demo .将程序打包在本地里,随着容器启动,容器内的jar包也会启动。但是这只是在我们的本地打包成docker镜像,如果手动迁移镜像到云服务器上,或者项目运行的服务器和镜像服务器不是同一台机器,手动操作就很繁琐了,故此继续改造maven,使得maven可以直接打包成镜像并上传到仓库。

改造Maven

首先介绍一个打包docker镜像的maven插件——Docker Maven Plugin,这时一个旨在为Java应用程序的开发人员提供方便和高效的Docker容器化过程的插,它允许Maven用户使用标准Maven构建方式来创建和构建Docker镜像,并支持将配置文件和资源文件打包到Docker镜像中,以便于部署和运行Java应用程序。

Docker Maven Plugin提供了一系列目标和插件,包括:

  1. docker:build:用于构建Docker镜像的目标。
  2. docker:startdocker:stop:用于启动和停止Docker容器的目标。
  3. docker:push:用于将Docker镜像推送到远程仓库的目标。
  4. dockerfile:build:使用自定义Dockerfile文件构建Docker镜像的目标。
  5. dockerfile:tag:用于将Docker镜像标记为指定的标签的目标。
  6. dockerfile:push:将Docker镜像推送到指定的Docker仓库的目标。

Docker Maven Plugin还提供了一些其他功能,如能够自动化地在Docker容器中运行Java应用程序,并提供了一些命令行参数和配置选项,以帮助开发人员定制和管理Docker镜像和容器。
github地址:fabric8io/docker-maven-plugin: Maven plugin for running and creating Docker images (github.com)

将其改造在pom文件里:

<!--重启时重新打包-->
    <build>
        <finalName>${project.artifactId}</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <!--开启过滤,用指定的参数替换directory下的文件中的参数-->
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.9.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot-maven-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.40.1</version>
                <configuration>
                    <!-- Docker 推送镜像仓库地址-->
                    <pushRegistry>swr.cn-south-1.xxxxcloud.com</pushRegistry>
                    <images>
                        <image>
                            <!--由于推送到私有镜像仓库,镜像名需要添加仓库地址-->
                            <name>swr.cn-south-1.xxxxcloud.com/${jenkins.service.name}/${project.name}</name>
                            <!--定义镜像构建行为-->
                            <build>
                                <dockerFileDir>${project.basedir}</dockerFileDir>
                                <tags>
                                    <tag>latest</tag>
                                    <tag>%T</tag>
                                </tags>
                            </build>
                        </image>
                    </images>
                </configuration>
            </plugin>
        </plugins>
    </build>

其中,

<tags>
            <tag>latest</tag>
            <tag>%T</tag>
       </tags>

这里的意思是同时打包2个镜像,一个镜像使用版本latest,一个镜像使用时间戳来标记版本,这样,我们的流水线只需要使用image:latest即一直使用latest版本即可,因为相同版本的镜像会覆盖,这样我们的latest就会保持最新,同时还会有一个时间戳版本的镜像用于回滚。

还有一个要注意的点就是使用这个插件的机器需要提前登录镜像仓库,即使用docker login xxx命令的操作,这个操作各云服务镜像仓库都给了详细的说明,这样我们就获取了打包到云上仓库的功能了,配合流水线启动美滋滋。

最后我们只需要在流水线脚本或者本地机器上使用mvn clean package docker:build docker:push命令即可完成docker镜像从打包到推送的全过程了。

如果觉得我的文章对你有用,请随意赞赏