1. 简介
Docker 是一个开源的应用容器引擎,让开发人员可以将应用打包部署到一个可移植的容器中,然后发布到任何流行的Linux服务器上,容器是完全使用沙箱机制,相互之间不会有任何接口。
一个完整的Docker有以下几个部分组成:
- Docker Client 客户端
- Docker Daemon 守护进程
- Docker Image 镜像
- Docker Container 容器
2. 准备工作
为了通过Docker来构建与部署Spring Boot应用, 我们需要有一个安装过 Docker 环境的服务器来打包 Spring Boot 项目, 因此在进行项目构建时, 需要安装Java、Maven和Docker的应用环境,建议使用Linux系统来构建Docker镜像。 Java与Maven环境安装与配置在这就不详细介绍了,Docker环境安装与配置可以参考之前写过的文章《Docker容器安装与部署》。
环境配置
- Java版本: JDK1.8+
- Maven版本: Maven3.0+
- Docker版本: Docker 17.06+
3. 构建Spring Boot项目
1. 配置Maven项目依赖文件pom.xml
- 添加Spring Boot项目依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0</version>
<relativePath/>
</parent>
- 添加Spring Boot项目相关的依赖包
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Java Mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
- 创建Controller, 提供服务接口, 此处提供一个测试接口
@RestController
public class HelloController {
@RequestMapping("/sayHello")
public String sayHello() {
return "Hello Spring Boot!";
}
}
- 创建Spring Boot启动类
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);
}
}
添加完毕后启动项目,启动成功后浏览器访问:http://localhost:8080/sayHello,调用接口页面返回:Hello Spring Boot!,说明 Spring Boot 项目工作正常。
4. Spring Boot项目中添加Docker构建组件
支持Spring Boot项目Docker容器构建的组件有许多个, 此处选择com.spotify:docker-maven-plugin
组件进行构建。
- 修改pom.xml文件, 添加Docker编译支持组件
<properties>
<docker.image.prefix>myProject</docker.image.prefix>
</properties>
<build>
<plugins>
<!-- Spring Boot Build Plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Docker maven plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}:${project.version}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<!-- Docker maven plugin -->
</plugins>
</build>
说明 :
- ${docker.image.prefix}为pom文件中properties中添加的配置;
- ${project.artifactId}为pom文件中的artifactId属性,${project.version}为pom文件中的version属性;
- dockerDirectory属性配置dockerfile文件的存放路径
/src/main/docker
;- resources属性中配置复制 jar 包到 docker 容器指定目录配置,将target下编译的Jar包复制到docker目录下。
我们也可以通过spotify的docker-maven-plugin组件配置, 自动创建Docker镜像,绕过下面创建Dockerfile的步骤, 直接生成Docker镜像:
<properties>
<docker.image.prefix>myProject</docker.image.prefix>
</properties>
<build>
<plugins>
<!-- Spring Boot Build Plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- Docker maven plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}:${project.version}</imageName>
<baseImage>docker.io/cemmersb/centos-jdk8:latest</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<!-- Docker maven plugin -->
</plugins>
</build>
说明:
- 使用baseImage属性配置Docker容器依赖的基础镜像信息;
- 使用entryPoint属性配置Docker容器的入口命令。
- 在
src/main/docker
下创建Dockerfile
FROM docker.io/cemmersb/centos-jdk8:latest
MAINTAINER garyond
VOLUME /tmp
ADD hello-service:0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
关于Dockerfile的相关命令可以参考我的文章《使用Dockerfile构建Docker镜像》, 这里我就不详细讲解了。
- 编译项目, 进行Docker镜像打包, 执行命令
mvn clean package docker:build
$ mvn clean package docker:build
...
Step 1/5 : FROM docker.io/cemmersb/centos-jdk8:latest
---> ccba23a213f2
Step 2/5 : MAINTAINER zhangjiayang <zhangjiayang@sczq.com.cn>
---> 0de52ae244d4
Step 3/5 : VOLUME /tmp
---> 3d25b5f60bb8
Step 4/5 : ADD hello-service-0.0.1-SNAPSHOT.jar app.jar
---> a02fcec9904c
Step 5/5 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
---> Running in a5cf7c699a3f
Removing intermediate container a5cf7c699a3f
---> 2177684b649d
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built 2177684b649d
Successfully tagged hello-service:0.0.1-SNAPSHOT
...
由于Docker构建时需要下载基础镜像信息, 所以过程会比较长, 所以我只粘贴了最后一部分编译的信息。编译完成后, 查看主机的镜像信息。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-service 0.0.1-SNAPSHOT 2177684b649d 13 minutes ago 875MB
rabbitmq 3-management 75472a5c510b 2 months ago 149MB
cemmersb/centos-jdk8 latest ccba23a213f2 3 years ago 858MB
- Docker镜像生成后, 运行Docker容器
$ docker run -d -p 8080:8080 hello-service:0.0.1-SNAPSHOT
通过docker ps
命令查询Docker容器是否正常启动
$ docker ps
容器成功启动后,打开浏览器访问:http://localhost:8080/sayHello,调用接口页面返回:Hello Spring Boot!,说明 Spring Boot 项目Docker容器工作正常。
5. 构建Spring Boot多模块依赖工程
由于Spring Boot项目开发中经常会遇见多模块的应用, 比如下面有一个应用sword
, 应用中包含以下几个模块, 其中需要部署三个应用sword-api、sword-job、sword-admin
:
- sword-common 公共模块(基础依赖)
- sword-util 常用工具模块(基础依赖)
- sword-api 接口模块(独立部署)
- sword-job 应用采集模块(独立部署)
- sword-admin 管理后台模块(独立部署)
5.1 准备工作
- 配置总体项目POM
<?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.garyond</groupId>
<artifactId>sword</artifactId>
<version>2.0.0</version>
<packaging>pom</packaging>
<modules>
<module>sword-common</module> <!--核心业务 -->
<module>sword-admin</module><!-- 后台 -->
<module>sword-api</module><!-- API -->
<module>sword-job</module><!-- 定时采集程序 -->
<module>sword-util</module><!-- 常用工具 -->
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
</project>
- 配置sword-common等基础依赖模块
<?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>
<artifactId>sword-common</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.garyod</groupId>
<artifactId>sword</artifactId>
<version>2.0.0</version>
<relativePath>../pom.xml</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>
<relativePath/>
</properties>
<dependencies>
......
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 配置sword-api、sword-admin等应用模块
<?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>
<artifactId>sword-api</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.garyond</groupId>
<artifactId>sword</artifactId>
<version>2.0.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
......
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
<!-- Docker maven plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<imageName>${project.groupId}/${project.artifactId}:${project.version}</imageName>
<baseImage>java:8</baseImage>
<maintainer>garyond</maintainer>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<!-- Docker maven plugin -->
</plugins>
</build>
</project>
5.2 应用部署
- 进入父工程(sword)pom文件所在目录,打包编译,将依赖包放至本地仓库
mvn clean install package -Dmaven.test.skip
- 分别进入各模块(sword-api/sword-admin/sword-job)目录,使用 Docker构建镜像
mvn package docker:build -Dmaven.test.skip
- 运行Docker容器
docker run -d -p 8080:8080 --name=sword-admin sword-admin:2.0.0
网友评论