Spring Boot 使用 Docker 部署

使用 Docker 部署 Spring Boot 项目有多种方法,既可以通过人工通过 docker 命令进行制作,也可以通过 Maven 插件直接生成。

我们主要讲使用 IntelliJ IDEA 自动生成 Docker 的步骤过程。

1. 新建Spring Boot工程

新建一个Spring Boot项目,添加一个简单的HelloController,方便进行测试。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class Demo1Application {

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

    @GetMapping(value="/")
    public String hello() {
        return "Hello";
    }
}

2. 添加Docker支持

在 pom.xml 中添加 Docker 镜像的名称:

<properties>
    <docker.image.prefix>springboot</docker.image.prefix>
</properties>

在 pom.xml 中添加 Docker 插件:

<build>    <plugins>        <plugin>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-maven-plugin</artifactId>        </plugin>        <plugin>            <groupId>com.spotify</groupId>            <artifactId>docker-maven-plugin</artifactId>            <version>1.0.0</version>            <configuration>                <imageName>${docker.image.prefix}/${project.artifactId}</imageName>                <dockerDirectory>docker</dockerDirectory>                <resources>                    <resource>                        <targetPath>/</targetPath>                        <directory>${project.build.directory}</directory>                        <include>${project.build.finalName}.jar</include>                    </resource>                </resources>            </configuration>        </plugin>    </plugins></build>

3. 编写Dockerfile文件

在项目的根目录创建 docker 子目录,并在 docker 中创建一个 Dockerfile 文件,Dockerfile 文件用来构建镜像的命令脚本。

FROM openjdk:8-jdk-alpine 
VOLUME /tmp
ADD demo-0.0.1-SNAPSHOT.jar app.jar 
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

其中:

FROM 指令用来指定基础镜像,我们使用了开源免费的 alpine 的 openjdk8 版本,使用 alpine 主要考虑镜像尽量小。

我们也可以使用 Oracle JDK8 的 CentOS 基础镜像:FROM jdk。 但是最终的生成 Docker 镜像会很大。

VOLUME 指令,VOLUME 指定挂载了 /tmp 目录。由于 Spring Boot 使用内置的 Tomcat 容器,Tomcat 默认使用 /tmp 作为工作目录。

这个命令的效果是:在宿主机的 /var/lib/docker 目录下创建一个临时文件,并把它链接到容器中的 /tmp 目录。

ADD指令,拷贝文件并且进行了重命名。将 demo1-1.0.0.jar 拷贝到 Docker 镜像的根目录中,而且改名为 app.jar。

ENTRYPOINT 指令,指定 docker 启动后执行的命令。

4. 部署Spring Boot工程

在 IJ IDEA中的菜单 View -&gt Tool Windows -&gt Maven,点击 Maven, 出现 Maven 工作窗口。

打开 Plugins,点击 docker,我们就会看到 bulid 选项。双击后,Maven 开始制作 Docker 镜像。

/Library/Java/JavaVirtualMachines/jdk1.8.0_201.jdk/Contents/Home/bin/java -Dmaven.multiModuleProjectDirectory=/Users/wangzebin/mydemo/demo "-Dmaven.home=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3" "-Dclassworlds.conf=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/m2.conf" "-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=52985:/Applications/IntelliJ IDEA.app/Contents/bin" -Dfile.encoding=GB2312 -classpath "/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/boot/plexus-classworlds-2.5.2.jar" org.codehaus.classworlds.Launcher -Didea.version=2018.3.4 com.spotify:docker-maven-plugin:1.0.0:build
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building demo 0.0.1
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- docker-maven-plugin:1.0.0:build (default-cli) @ demo---
[INFO] Using authentication suppliers: [ConfigFileRegistryAuthSupplier]
[INFO] Copying /Users/wangzebin/mydemo/demo1/target/demo-0.0.1-SNAPSHOT.jar -> /Users/wangzebin/mydemo/demo/target/docker/demo-0.0.1-SNAPSHOT.jar
[INFO] Copying docker/Dockerfile -> /Users/wangzebin/mydemo/demo/target/docker/Dockerfile
[INFO] Building image springboot/demo
Step 1/4 : FROM openjdk:8-jdk-alpine
 ---> a3562aa0b991
Step 2/4 : VOLUME /tmp
 ---> Running in 94a47191cdea
 ---> 5110c95f55bf
Removing intermediate container 94a47191cdea
Step 3/4 : ADD demo-0.0.1-SNAPSHOT.jar app.jar
 ---> f5f79d8817c7
Step 4/4 : ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar
 ---> Running in ca39f62863a3
 ---> f26e20c63ef4
Removing intermediate container ca39f62863a3
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built f26e20c63ef4
Successfully tagged springboot/demo:latest
[INFO] Built springboot/demo
[INFO] Tagging springboot/demo with 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 6.423 s
[INFO] Finished at: 2022-02-12T14:38:43+08:00
[INFO] Final Memory: 24M/359M
[INFO] ------------------------------------------------------------------------

5. 运行验证

打包完成后,在 shell 中使用 docker images 命令查看构建好的镜像:

[root@localhost ~]# docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
springboot/demo       latest              39aabeebb971        5 days ago          660 MB

运行docker镜像:

docker run -p 8080:8080 springboot/docker

在本机的浏览器进行访问,在浏览器中输入 http://localhost:8080,我们可以看到返回的结果为 Hello,说明部署成功。

下一章:Spring Boot 启动原理

我们开发任何一个Spring Boot项目,都会用到如下的启动类:@SpringBootApplicationpublic class Application { public static void ...