这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战
除了使用 Docker 运行各种中间件容器,方便日常开发,我们也可以将 Spring Boot 等 Web 应用放在容器中运行,这样我们可以让开发、测试、生产环境保持一致的运行环境,避免很多因为运行环境差异带来的问题。这篇文章通过一个 Spring Boot 的工程来演示如何 Spring Boot 应用在 Docker 容器中运行。
创建 Spring Boot 应用
首先,创建一个用来测试的 Spring Boot 应用,最简单的方式就是通过 Spring Initializr 来创建,在项目中添加 Spring Web 模块即可。
之后点击「GENERATE」按钮生成项目并下载,这时就得到了一个空的 Spring Boot 项目。接下来,在启动类当中添加一个 Web 接口。
@SpringBootApplication
@RestController
public class SpringBootDockerDemoApplication {
public static void main ( String [] args ) {
SpringApplication.run( SpringBootDockerDemoApplication.class, args ) ;
}
@RequestMapping ( "/" )
public String greeting () {
return "Hello form Docker";
}
}
运行启动类,如果访问 localhost:8080 可以得到 Hello form Docker 结果,说明运行没有问题。
➜ curl localhost:8080
Hello form Docker
最后,通过 mvn package 将项目打包。
通过 Dockerfile 构建镜像
接下来,编写 Dockerfile。
FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
以 openjdk:8-jdk-alpine 为基础镜像,设置一个参数,指向我们打包好的 JAR 包文件,将其拷贝入镜像中,然后执行 JAR 文件。以上的 Dockerfile 是最简单的实现方式。
但是为了保证容器中操作系统的安全,我们最好在运行应用程序的时候限制它的权限,也就是用非 root 用户运行我们的 Spring Boot 程序。我们可以在镜像中,创建一个专用的用户组和用户,用它来执行 JAR 文件。
FROM openjdk:8-jdk-alpine
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
以上的 Dockerfile 中,使用 RUN 指令创建了 spring 用户组和用户,然后使用 USER 指令,使接下来的命令都是以这个用户的身份来运行。
把 Dockerfile 放在 Spring Boot 工程的根目录,这样,就可以构建镜像。
docker build -t spring-boot-docker-demo .
成功之后,就可以用 docker images 看到刚才创建的镜像。
REPOSITORY TAG IMAGE ID CREATED SIZE
spring-boot-docker-demo latest 05303192f7e7 26 seconds ago 122MB
通过容器运行 Spring Boot 应用
基于刚才创建的镜像,运行一个容器。
docker run -p 8080:8080 spring-boot-docker-demo
这里使用 -p 将容器中的 8080 端口与宿主机的 8080 端口绑定,由于没有使用 -d 运行,所以我们可以直接在控制台看到日志。启动成功后,可以用 curl测试它是否运行成功。