Docker是一个使用广泛的Linux容器管理工具包,它允许用户创建镜像,并将其容器实例化。通过本指南,我们可以学习到如何使用Docker部署Spring Boot项目。
先决条件
开发之前,你必须具备如下条件才能够开发:
- 你必须在物理机或虚拟机上安装Docker,如果条件不允许,你可以是在本机安装Docker Toolbox,使用Docker Machine创建Docker引擎。关于Docker Toolbox的安装请查看官方安装方式。关于Docker的安装你可以参考:在Centos上安装Docker
- 你需要掌握Spring Boot框架的变成模型
步骤一:构建Spring Boot项目
- 使用IDE工具(推荐Idea)构建Spring Boot项目:项目名称demo。在该项目中,我们发布一个Rest API服务,端点是:
/user
。由于发布的是基于Http的API接口,因此pom中需要引入spring-boot-starter-web
构建。 - 开发
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;
}
}
- 编辑
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
插件帮助信息。
- 在pom文件中引入,添加
docker-maven-plugin
插件
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
</plugin>
- 配置
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:portdockerCertPath
:如果Docker引擎开启了TLS验证功能,你必须要将客户端证书、秘钥以及CA证书的路径配置在这里baseImage
:基准镜像。与Dockerfile中的FROM <baseImage>
指令一致imageName
:镜像名称。由项目名称与版本号组成imageTags
:镜像Tag。默认是项目的版本号与latestentryPoint
:容器启动时,执行的命令exposes
:需要暴漏的端口resource.targetPath
:打包好的项目文件放置在容器的位置,targetPath路径必须要与entryPoint中的一致resource.directory
:项目的构建目录resource.include
:需要将项目构建目录中哪些内容拷贝至镜像中
步骤三:构建Docker镜像
- 配置完插件后,我们就可以构建Docker镜像了:
mvn clean package docker:build
- 使用Docker客户端查看docker 镜像:
[root@docker-test sentinel]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
demo 1.0 506b7ed0635e 22 seconds ago 116MB
- 运行demo:1.0镜像,将demo服务的8080端口映射到宿主机:
[root@docker-test sentinel]# docker run -itd --name demo -p 8080:8080 demo:1.0
dc5cd4780f8e42a4bf6ea0a696dbf3289785f2044e66aec8ba43213dd86a4fcc
- 查看已运行容器:
[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
步骤四:将镜像上传至私有的镜像仓储中
在上述步骤中,我们已经实现了如何使用docker-maven-plugin
插件将Spring Boot项目构建至Docker中。那么,如何将镜像推送至私有仓储呢?
在本实例中,我们采用阿里云的镜像仓储。
- 修改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>
- 修改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>
</