使用Docker部署Spring boot项目

Docker是一个使用广泛的Linux容器管理工具包,它允许用户创建镜像,并将其容器实例化。通过本指南,我们可以学习到如何使用Docker部署Spring Boot项目。

先决条件

开发之前,你必须具备如下条件才能够开发:

  • 你必须在物理机或虚拟机上安装Docker,如果条件不允许,你可以是在本机安装Docker Toolbox,使用Docker Machine创建Docker引擎。关于Docker Toolbox的安装请查看官方安装方式。关于Docker的安装你可以参考:在Centos上安装Docker
  • 你需要掌握Spring Boot框架的变成模型

步骤一:构建Spring Boot项目

  1. 使用IDE工具(推荐Idea)构建Spring Boot项目:项目名称demo。在该项目中,我们发布一个Rest API服务,端点是:/user。由于发布的是基于Http的API接口,因此pom中需要引入spring-boot-starter-web构建。
  2. 开发DemoController代码如下:
@RestController
public class DemoController {

    @RequestMapping("/user")
    public Map<String,Object> getUser() {
        Map<String, Object> userMap = new HashMap<>(16);
        userMap.put("name", "Jim");
        userMap.put("sex", "male");
        userMap.put("age", 22);
        return userMap;
    }
}
  1. 编辑application.yml文件:
server:
  port: 8080
spring:
  application:
    name: demo-service

现在,一个微服务项目就开发完成了!

步骤二:使用插件构建项目

一般来说,开发完Spring Boot项目后,需要编写Dockerfile,然后使用mvn clean package命令对项目进行编译和打包,然后通过运行docker build命令,构建项目的镜像。这样做显得比较繁琐,为了提升开发效率,减轻开发人员工作量,我们可以使用docker-maven-plugin插件。通过该插件,你可以通过Maven构建的Docker镜像。使用mvn com.spotify:docker-maven-plugin:<version>:help -Ddetail=true命令查看docker-maven-plugin插件帮助信息。

  1. 在pom文件中引入,添加docker-maven-plugin插件
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.0.0</version>
</plugin>
  1. 配置docker-maven-plugin。在构建之前,我们需要配置该插件,详细配置请参考这里
<plugin>
	<groupId>com.spotify</groupId>
	<artifactId>docker-maven-plugin</artifactId>
	<version>1.0.0</version>
	<configuration>
		<dockerHost>https://172.20.5.79:2376</dockerHost>
		<dockerCertPath>C:\Users\Administrator\.docker\machine\cert_79</dockerCertPath>
		<baseImage>openjdk:8-alpine</baseImage>
		<imageName>${project.build.finalName}</imageName>
		<imageTags>
			<imageTag>${project.version}</imageTag>
			<imageTag>latest</imageTag>
		</imageTags>
		<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
		<exposes>
			<expose>8080</expose>
		</exposes>
		<resources>
			<resource>
				<targetPath>/</targetPath>
				<directory>${project.build.directory}</directory>
				<include>${project.build.finalName}.jar</include>
			</resource>
		</resources>
	</configuration>
</plugin>

解释一下上述配置:

  • dockerHost:配置Docker引擎的地址,格式为:http|https://ip:port
  • dockerCertPath:如果Docker引擎开启了TLS验证功能,你必须要将客户端证书、秘钥以及CA证书的路径配置在这里
  • baseImage:基准镜像。与Dockerfile中的FROM <baseImage>指令一致
  • imageName:镜像名称。由项目名称与版本号组成
  • imageTags:镜像Tag。默认是项目的版本号与latest
  • entryPoint:容器启动时,执行的命令
  • exposes:需要暴漏的端口
  • resource.targetPath:打包好的项目文件放置在容器的位置,targetPath路径必须要与entryPoint中的一致
  • resource.directory:项目的构建目录
  • resource.include:需要将项目构建目录中哪些内容拷贝至镜像中

步骤三:构建Docker镜像

  1. 配置完插件后,我们就可以构建Docker镜像了:
mvn clean package docker:build
  1. 使用Docker客户端查看docker 镜像:
[root@docker-test sentinel]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
demo                1.0                 506b7ed0635e        22 seconds ago      116MB
  1. 运行demo:1.0镜像,将demo服务的8080端口映射到宿主机:
[root@docker-test sentinel]# docker run -itd --name demo -p 8080:8080 demo:1.0
dc5cd4780f8e42a4bf6ea0a696dbf3289785f2044e66aec8ba43213dd86a4fcc
  1. 查看已运行容器:
[root@docker-test sentinel]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
dc5cd4780f8e        demo:1.0            "java -jar /demo.jar"    4 seconds ago       Up 3 seconds        0.0.0.0:8080->8080/tcp   demo
  1. 在浏览器中运行:http://ip:8080/user。如果返回数据,那就恭喜你了。

步骤四:将镜像上传至私有的镜像仓储中

在上述步骤中,我们已经实现了如何使用docker-maven-plugin插件将Spring Boot项目构建至Docker中。那么,如何将镜像推送至私有仓储呢?

在本实例中,我们采用阿里云的镜像仓储。

  1. 修改setting.xml文件,通常来说,该文件在~/.m2目录下。在setting.xml文件中添加server节点,用于登录阿里云的镜像注册中心:
<server>
	<id>docker-repository</id>
	<username>some_user</username>
	<password>some_password</password>
</server>
  • username:登录阿里云注册中心用户名
  • password:登录阿里云注册中心的密码

由于要保证密码的安全性,这里不采用明文,需要对密码进行加密。加密方式参考:maven密码加密。步骤如下:

  • 首先使用你的私有仓库访问密码生成主密码:
mvn --encrypt-master-password <password>
  • 其次在settings.xml文件的同级目录创建settings-security.xml文件,将主密码写入:
<?xml version="1.0" encoding="UTF-8"?>
<settingsSecurity>
  <master>{Ns0JM49fW9gHMTZ44n*****************=}</master>
</settingsSecurity>
  • 最后使用你的私有仓库访问密码生成服务密码,将生成的密码写入到settings.xml的<server>中:
mvn --encrypt-password <password>
<server>
			<id>docker-repository</id>
			<username>some_user</username>
			<password>{73eo3WYROT0HkVfHD0cUF2Z/dtaGVtSPJ1TOsFLuO08=}</password>
		</server>
  1. 修改pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.2</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<docker.host>https://172.20.5.79:2376</docker.host>
		<docker.cert.path>C:\Users\Administrator\.docker\machine\cert_79</docker.cert.path>
		<docker.repository>registry.cn-hangzhou.aliyuncs.com/mark0614</docker.repository>
		<docker.registry.name>${project.artifactId}</docker.registry.name>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

	<build>
		<finalName>${project.artifactId}</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<executable>true</executable>
				</configuration>
			</plugin>
			<plugin>
				<groupId>com.spotify</groupId>
				<artifactId>docker-maven-plugin</artifactId>
				<version>1.0.0</version>
				<executions>
					<execution>
						<id>package</id>
						<phase>package</phase>
						<goals>
							<goal>build</goal>
						</goals>
					</execution>
					<execution>
						<id>tag-image</id>
						<phase>package</phase>
						<goals>
							<goal>tag</goal>
						</goals>
						<configuration>
							<image>${project.build.finalName}:${project.version}</image>
							<newName>${docker.repository}/${project.build.finalName}:${project.version}</newName>
						</configuration>
					</execution>
					<execution>
						<id>install</id>
						<phase>install</phase>
						<goals>
							<goal>push</goal>
						</goals>
						<configuration>
							<imageName>${docker.repository}/${project.build.finalName}:${project.version}</imageName>
						</configuration>
					</execution>
				</executions>
				<configuration>
					<dockerHost>${docker.host}</dockerHost>
					<dockerCertPath>${docker.cert.path}</dockerCertPath>
					<baseImage>openjdk:8-jre-alpine</baseImage>
					<imageName>${project.build.finalName}</imageName>
					<serverId>docker-repository</serverId>
					<registryUrl>${docker.repository}</registryUrl>
					<imageTags>
						<imageTag>${project.version}</imageTag>
						<imageTag>latest</imageTag>
					</imageTags>
					<entryPoint>["java", "-jar", "/var/app/${artifactId}/${project.build.finalName}.jar"]</entryPoint>
					<exposes>
						<expose>8080</expose>
					</exposes>
					<resources>
						<resource>
							<targetPath>/var/app/${project.build.finalName}/</targetPath>
							<directory>${project.build.directory}</directory>
							<include>${project.build.finalName}.jar</include>
						</resource>
					</resources>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

解释一下:

  • executionsdocker-maven-plugin会在不同的构建阶段执行不同的目标任务。
    • package阶段进行docker build操作
    • package阶段同时执行tag操作,将镜像重新tag成docker-repository:port/namespace/imageName:version格式
    • install或者deploy阶段进行push操作
  • registryUrl:镜像注册中心地址
  • serverId:配置在settings.xml中的server认证信息
  1. 构建项目:
mvn clean package -Dmaven.test.skip=true

打印出如下信息,说明你成功了:

[INFO] Pushing registry.cn-hangzhou.aliyuncs.com/mark0614/demo:0.0.2
The push refers to repository [registry.cn-hangzhou.aliyuncs.com/mark0614/demo]
3148c56ca932: Preparing
69cc5717c281: Preparing
5b1e27e74327: Preparing
04a094fe844e: Preparing
3148c56ca932: Pushing [>                                                  ]  165.9kB/14.51MB
69cc5717c281: Layer already exists
3148c56ca932: Pushing [=>                                                 ]  493.6kB/14.51MB
04a094fe844e: Layer already exists
3148c56ca932: Pushing [==>                                                ]  821.2kB/14.51MB
5b1e27e74327: Layer already exists
3148c56ca932: Pushing [====>                                              ]  1.313MB/14.51MB
3148c56ca932: Pushing [=======>                                           ]  2.132MB/14.51MB
3148c56ca932: Pushing [========>                                          ]   2.46MB/14.51MB
3148c56ca932: Pushing [=========>                                         ]  2.787MB/14.51MB
3148c56ca932: Pushing [===========>                                       ]  3.279MB/14.51MB
3148c56ca932: Pushing [============>                                      ]  3.607MB/14.51MB
3148c56ca932: Pushing [==============>                                    ]  4.098MB/14.51MB
3148c56ca932: Pushing [===============>                                   ]  4.426MB/14.51MB

 http://note.youdao.com/noteshare?id=07e1e408801bdf8d907ab81850dd60c2&sub=CEE7634AEEE542F3A07EDC31DC0EFAC9

原文地址:https://www.cnblogs.com/softidea/p/8044031.html