前言
首先来了解下什么是Dockerfile
:
Dockerfile
是一个包含命令和指令的脚本文件,用于构建Docker
镜像。它包含了构建镜像的全部指令,可以使得从头开始构建一个完整的Docker
镜像变得十分容易。
以下是Dockerfile
的使用方法:
- 创建
Dockerfile
文件:在项目目录中使用文本编辑器创建Dockerfile
文件并编写相应的指令。 - 编写
Dockerfile
指令:使用Dockerfile
指令来构建镜像,例如FROM
、RUN
、COPY
、CMD
等等。 - 构建镜像:使用
docker build
命令构建镜像。例如:docker build -t imagename .
- 运行容器:使用
docker run
命令运行容器。例如:docker run -d -p 8080:8080 imagename
。 - 打包和分享镜像:可以使用
docker save
和docker load
命令来打包和分享镜像。
以上是对dockerfile的一般理解和使用方法。
前提
- 一个正常可打包的
Spring Boot
web项目 - 一个可用的云端镜像仓库
- 一个可以本地连接使用的
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提供了一系列目标和插件,包括:
docker:build
:用于构建Docker镜像的目标。docker:start
和docker:stop
:用于启动和停止Docker容器的目标。docker:push
:用于将Docker镜像推送到远程仓库的目标。dockerfile:build
:使用自定义Dockerfile文件构建Docker镜像的目标。dockerfile:tag
:用于将Docker镜像标记为指定的标签的目标。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
镜像从打包到推送的全过程了。