Browse Source

打包模块之 docker 案例完成

3.x
Yangkai.Shen 2 years ago
parent
commit
6f8d28dca8
14 changed files with 181 additions and 252 deletions
  1. +0
    -25
      demo-docker/.gitignore
  2. +0
    -20
      demo-docker/Dockerfile
  3. +0
    -116
      demo-docker/README.md
  4. +0
    -71
      demo-docker/pom.xml
  5. +0
    -16
      demo-docker/src/test/java/com/xkcoding/docker/SpringBootDemoDockerApplicationTests.java
  6. +26
    -0
      demo-package/demo-package-docker/Dockerfile
  7. +80
    -0
      demo-package/demo-package-docker/README.md
  8. +52
    -0
      demo-package/demo-package-docker/pom.xml
  9. +2
    -2
      demo-package/demo-package-docker/src/main/java/com/xkcoding/docker/DockerApplication.java
  10. +4
    -1
      demo-package/demo-package-docker/src/main/java/com/xkcoding/docker/controller/HelloController.java
  11. +0
    -0
      demo-package/demo-package-docker/src/main/resources/application.yml
  12. +13
    -0
      demo-package/demo-package-docker/src/test/java/com/xkcoding/docker/DockerApplicationTests.java
  13. +4
    -0
      demo-package/pom.xml
  14. +0
    -1
      pom.xml

+ 0
- 25
demo-docker/.gitignore View File

@@ -1,25 +0,0 @@
/target/
!.mvn/wrapper/maven-wrapper.jar

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

+ 0
- 20
demo-docker/Dockerfile View File

@@ -1,20 +0,0 @@
# 基础镜像
FROM openjdk:8-jdk-alpine

# 作者信息
MAINTAINER "Yangkai.Shen 237497819@qq.com"

# 添加一个存储空间
VOLUME /tmp

# 暴露8080端口
EXPOSE 8080

# 添加变量,如果使用dockerfile-maven-plugin,则会自动替换这里的变量内容
ARG JAR_FILE=target/spring-boot-demo-docker.jar

# 往容器中添加jar包
ADD ${JAR_FILE} app.jar

# 启动镜像自动运行程序
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/urandom","-jar","/app.jar"]

+ 0
- 116
demo-docker/README.md View File

@@ -1,116 +0,0 @@
# spring-boot-demo-docker

> 本 demo 主要演示了如何容器化一个 Spring Boot 项目。通过 `Dockerfile` 的方式打包成一个 images 。

## Dockerfile

```dockerfile
# 基础镜像
FROM openjdk:8-jdk-alpine

# 作者信息
MAINTAINER "Yangkai.Shen 237497819@qq.com"

# 添加一个存储空间
VOLUME /tmp

# 暴露8080端口
EXPOSE 8080

# 添加变量,如果使用dockerfile-maven-plugin,则会自动替换这里的变量内容
ARG JAR_FILE=target/spring-boot-demo-docker.jar

# 往容器中添加jar包
ADD ${JAR_FILE} app.jar

# 启动镜像自动运行程序
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/urandom","-jar","/app.jar"]
```

## 打包方式

### 手动打包

1. 前往 Dockerfile 目录,打开命令行执行

```bash
$ docker build -t spring-boot-demo-docker .
```

2. 查看生成镜像

```bash
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot-demo-docker latest bc29a29ffca0 2 hours ago 119MB
openjdk 8-jdk-alpine 97bc1352afde 5 weeks ago 103MB
```

3. 运行

```bash
$ docker run -d -p 9090:8080 spring-boot-demo-docker
```

### 使用 maven 插件打包

1. pom.xml 中添加插件

2. ```xml
<properties>
<dockerfile-version>1.4.9</dockerfile-version>
</properties>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-version}</version>
<configuration>
<repository>${project.build.finalName}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
<executions>
<execution>
<id>default</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
```

2. 执行mvn打包命令,因为插件中 `execution` 节点配置了 package,所以会在打包的时候自动执行 build 命令。

```bash
$ mvn clean package -Dmaven.test.skip=true
```

3. 查看镜像

```bash
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot-demo-docker 1.0.0-SNAPSHOT bc29a29ffca0 2 hours ago 119MB
openjdk 8-jdk-alpine 97bc1352afde 5 weeks ago 103MB
```

4. 运行

```bash
$ docker run -d -p 9090:8080 spring-boot-demo-docker:1.0.0-SNAPSHOT
```

## 参考

- docker 官方文档:https://docs.docker.com/
- Dockerfile 命令,参考文档:https://docs.docker.com/engine/reference/builder/
- maven插件使用,参考地址:https://github.com/spotify/dockerfile-maven

+ 0
- 71
demo-docker/pom.xml View File

@@ -1,71 +0,0 @@
<?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>demo-docker</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

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

<parent>
<groupId>com.xkcoding</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<dockerfile-version>1.4.9</dockerfile-version>
</properties>

<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>
</dependencies>

<build>
<finalName>demo-docker</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-version}</version>
<configuration>
<repository>${project.build.finalName}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
<!-- <executions>-->
<!-- &lt;!&ndash;设置运行 mvn package 的时候自动执行docker build&ndash;&gt;-->
<!-- <execution>-->
<!-- <id>default</id>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>build</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
</plugin>
</plugins>
</build>

</project>

+ 0
- 16
demo-docker/src/test/java/com/xkcoding/docker/SpringBootDemoDockerApplicationTests.java View File

@@ -1,16 +0,0 @@
package com.xkcoding.docker;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootDemoDockerApplicationTests {

@Test
public void contextLoads() {
}

}

+ 26
- 0
demo-package/demo-package-docker/Dockerfile View File

@@ -0,0 +1,26 @@
# 多阶段构建
FROM amazoncorretto:17.0.4-alpine3.15 as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
# layertools extract 命令会将 spring boot fatjar 解压成多个 layers
RUN java -Djarmode=layertools -jar application.jar extract


FROM amazoncorretto:17.0.4-alpine3.15
# 作者信息
MAINTAINER "Yangkai.Shen 237497819@qq.com"

WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./

# 添加一个存储空间
VOLUME /tmp

# 暴露8080端口
EXPOSE 8080
# 入口
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom","org.springframework.boot.loader.JarLauncher"]

+ 80
- 0
demo-package/demo-package-docker/README.md View File

@@ -0,0 +1,80 @@
## spring-boot-demo-docker

> 本 demo 主要演示了如何容器化一个 Spring Boot 项目。通过 `Dockerfile` 的方式打包成一个 images 。

### 1.开发步骤

#### 1.1.创建一个 HelloWorld 的 SpringBoot 项目

参考 `demo-base-helloworld` 案例即可

#### 1.2.创建Dockerfile

```dockerfile
# 多阶段构建
FROM amazoncorretto:17.0.4-alpine3.15 as builder
WORKDIR application
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} application.jar
# layertools extract 命令会将 spring boot fatjar 解压成多个 layers
RUN java -Djarmode=layertools -jar application.jar extract


FROM amazoncorretto:17.0.4-alpine3.15
# 作者信息
MAINTAINER "Yangkai.Shen 237497819@qq.com"

WORKDIR application
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./

# 添加一个存储空间
VOLUME /tmp

# 暴露8080端口
EXPOSE 8080
# 入口
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/urandom","org.springframework.boot.loader.JarLauncher"]
```

#### 1.2.打包

1. 首先在 spring-boot-demo 根目录下,先执行编译打包 Jar 文件

```shell
$ mvn clean -DskipTests package
```

2. 再进入 `demo-package-docker` 目录,构建镜像

```shell
$ cd demo-package/demo-package-docker
$ docker build -t demo-package-docker:v1 .
```

3. 查看生成镜像

```shell
$ docker images | grep demo
demo-package-docker v3 58e9b4918f61 19 minutes ago 353MB
demo-package-docker v2 35303ce1960c 22 minutes ago 351MB
demo-package-docker v1 7d4a9e953a19 28 minutes ago 351MB
```

4. 测试运行

```shell
$ docker run -p 8080:8080 demo-package-docker:v1
```

> 注意:
> 1.Spring Boot 提供的 maven 插件中已包含 `spring-boot-loader-tools` 依赖,该依赖可以将 SpringBoot FatJar 解压为每个layer,这样在 Docker 多阶段构建的时候,可以让 Docker 复用已存在的 layer,达到加速构建、加速上传、加速下载的目的
> 2.同学们可以通过修改代码、添加依赖等方式重新 build 不同版本的镜像,然后通过 `docker inspect xxx` 命令对比不同版本的 layer,观察输出信息是否存在相同的 layer sha256 值,存在即表示 Docker 已经复用了该 layer

### 2.参考

- Spring Boot 官方文档:https://docs.spring.io/spring-boot/docs/3.0.0-M4/reference/htmlsingle/#container-images.dockerfiles
- docker 官方文档:https://docs.docker.com/
- Dockerfile 命令,参考文档:https://docs.docker.com/engine/reference/builder/

+ 52
- 0
demo-package/demo-package-docker/pom.xml View File

@@ -0,0 +1,52 @@
<?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">
<parent>
<groupId>com.xkcoding</groupId>
<artifactId>demo-package</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>

<artifactId>demo-package-docker</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>demo-package-docker</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>17</java.version>
</properties>

<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>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

<build>
<finalName>demo-package-docker</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

demo-docker/src/main/java/com/xkcoding/docker/SpringBootDemoDockerApplication.java → demo-package/demo-package-docker/src/main/java/com/xkcoding/docker/DockerApplication.java View File

@@ -12,9 +12,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @date Created in 2018-11-29 14:59
*/
@SpringBootApplication
public class SpringBootDemoDockerApplication {
public class DockerApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBootDemoDockerApplication.class, args);
SpringApplication.run(DockerApplication.class, args);
}
}

demo-docker/src/main/java/com/xkcoding/docker/controller/HelloController.java → demo-package/demo-package-docker/src/main/java/com/xkcoding/docker/controller/HelloController.java View File

@@ -1,5 +1,6 @@
package com.xkcoding.docker.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -12,11 +13,13 @@ import org.springframework.web.bind.annotation.RestController;
* @author yangkai.shen
* @date Created in 2018-11-29 14:58
*/
@Slf4j
@RestController
@RequestMapping
public class HelloController {
@GetMapping
@GetMapping("/hello")
public String hello() {
log.info("[HelloController#hello], receive a request...");
return "Hello,From Docker!";
}
}

demo-docker/src/main/resources/application.yml → demo-package/demo-package-docker/src/main/resources/application.yml View File


+ 13
- 0
demo-package/demo-package-docker/src/test/java/com/xkcoding/docker/DockerApplicationTests.java View File

@@ -0,0 +1,13 @@
package com.xkcoding.docker;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class DockerApplicationTests {

@Test
void contextLoads() {
}

}

+ 4
- 0
demo-package/pom.xml View File

@@ -18,4 +18,8 @@
<java.version>17</java.version>
</properties>

<modules>
<module>demo-package-docker</module>
</modules>

</project>

+ 0
- 1
pom.xml View File

@@ -68,7 +68,6 @@
<!-- <module>demo-elasticsearch</module>-->
<!-- <module>demo-mongodb</module>-->
<!-- <module>demo-neo4j</module>-->
<!-- <module>demo-docker</module>-->
<!-- <module>demo-multi-datasource-jpa</module>-->
<!-- <module>demo-multi-datasource-mybatis</module>-->
<!-- <module>demo-sharding-jdbc</module>-->


Loading…
Cancel
Save