在使用Spring Boot Devtools和Jib进行组合时,有时希望在容器运行时禁用Devtools,这是一个讨论

怎么了? le?)

我认为在使用Spring Boot创建Docker镜像时,使用Cloud Native Buildpacks是标准做法。

当我试图使用Jib构建时,发现在依赖关系中包含Spring Boot Devtools会遇到一些困难,所以我将这个问题记下来。

发生的事件和解决方法

遇到的问题是,在包含Spring Boot Devtools依赖的情况下使用Jib创建并执行Docker镜像时,导致在Docker容器运行时Spring Boot Devtools被激活了。

据写着,Spring Boot Devtools在打包执行时会被禁用。

当运行完全打包的应用程序时,开发者工具会自动禁用。如果您的应用程序从java -jar启动,或者从特殊的类加载器启动,则被视为“生产应用程序”。

使用Spring Boot / 开发者工具进行开发

从一开始就认为,在生产环境中,应该不启用Devtool。

在生产环境中运行开发工具是一种安全风险,因此这是不能被允许的。

在这里,我会看一下Jib文档中关于专门针对Spring Boot的描述。

常见问题解答(FAQ)/ Jib CLI / jar命令如何支持Spring Boot JAR包?

推荐的是以“Exploded Mode”模式执行,执行格式为java -cp /app org.springframework.boot.loader.JarLauncher。
(实际运行时,感觉有些不同…)

然后,问题是如果不做任何更改,Spring Boot Devtools将会被启用。

要禁用它,只需在创建Docker镜像的时候将Spring Boot Devtools的作用域设置为provided,这样在打包时就不会包含进去了。

 

或者,您可以在运行时使用-Dspring.devtools.restart.enabled=false进行指定。

如果可以的话,我认为在创建Docker镜像时最好将其排除掉才更保险。

那么,我们来确认一下实际操作。

环境

这次的环境是这里。

$ java --version
openjdk 11.0.15 2022-04-19
OpenJDK Runtime Environment (build 11.0.15+10-Ubuntu-0ubuntu0.20.04.1)
OpenJDK 64-Bit Server VM (build 11.0.15+10-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing)


$ mvn --version
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
Maven home: /home/charon/.sdkman/candidates/maven/current
Java version: 11.0.15, vendor: Private Build, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: ja_JP, platform encoding: UTF-8
OS name: "linux", version: "5.4.0-120-generic", arch: "amd64", family: "unix"
$ docker version
Client: Docker Engine - Community
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.17.11
 Git commit:        100c701
 Built:             Mon Jun  6 23:02:57 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.17.11
  Git commit:       a89b842
  Built:            Mon Jun  6 23:01:03 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.6
  GitCommit:        10c12954828e7c7c9b6e0ea9b0c02b01407d3ae1
 runc:
  Version:          1.1.2
  GitCommit:        v1.1.2-0-ga916309
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

创建一个Spring Boot项目,并添加Jib。

首先,创建一个Spring Boot项目。在依赖项中,我已经包含了web和devtools。

$ curl -s https://start.spring.io/starter.tgz \
  -d bootVersion=2.7.0 \
  -d javaVersion=11 \
  -d name=devtools-with-jib \
  -d groupId=com.example \
  -d artifactId=devtools-with-jib \
  -d version=0.0.1-SNAPSHOT \
  -d packageName=com.example.spring \
  -d dependencies=web,devtools \
  -d baseDir=devtools-with-jib | tar zxvf -

进入项目内部。

$ cd devtools-with-jib

请查看以下依存关系。

        <properties>
                <java.version>11</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-devtools</artifactId>
                        <scope>runtime</scope>
                        <optional>true</optional>
                </dependency>
                <dependency>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-starter-test</artifactId>
                        <scope>test</scope>
                </dependency>
        </dependencies>

        <build>
                <plugins>
                        <plugin>
                                <groupId>org.springframework.boot</groupId>
                                <artifactId>spring-boot-maven-plugin</artifactId>
                        </plugin>
                </plugins>
        </build>

在这里添加Jib的Maven插件。

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>com.google.cloud.tools</groupId>
				<artifactId>jib-maven-plugin</artifactId>
				<version>3.2.1</version>
			</plugin>
		</plugins>
	</build>

现在我们来创建源代码。

暂时删除生成的源代码。

$ rm src/main/java/com/example/spring/DevtoolsWithJibApplication.java src/test/java/com/example/spring/DevtoolsWithJibApplicationTests.java

创建一个简单的源代码。

package com.example.spring;

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;

@SpringBootApplication
@RestController
public class App {
    public static void main(String... args) {
        SpringApplication.run(App.class, args);
    }

    @GetMapping
    public String hello() {
        return "Hello World";
    }
}

我会尝试确认

那么,我们来创建一个Docker镜像。

$ mvn package jib:dockerBuild

## 以下でも同じ
$ mvn compile jib:dockerBuild

执行。

$ docker container run -it --rm -p 8080:8080 --name app devtools-with-jib:0.0.1-SNAPSHOT

从日志中看,可以知道Spring Boot Devtools已经启用了。

2022-06-22 15:25:21.171  INFO 1 --- [  restartedMain] com.example.spring.App                   : Starting App using Java 11.0.15 on 173c614374c4 with PID 1 (/app/classes started by root in /)
2022-06-22 15:25:21.177  INFO 1 --- [  restartedMain] com.example.spring.App                   : No active profile set, falling back to 1 default profile: "default"
2022-06-22 15:25:21.563  INFO 1 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2022-06-22 15:25:21.569  INFO 1 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2022-06-22 15:25:26.686  INFO 1 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

由于主题是“restartedMain”,所以。

容器内的执行命令大致如下。

$ docker container exec -it app sh -c 'ps -ef | grep java | grep -v grep'
root           1       0 62 15:25 pts/0    00:00:39 java -cp @/app/jib-classpath-file com.example.spring.App

当然,虽然我还是以平常的方式运动。

$ curl localhost:8080
Hello World

所以,由于包含了Spring Boot Devtools有点讨厌,我们要想办法解决一下。

更改Spring Boot Devtools的作用域。

首先,让我们按照Jib的问题所提到的,尝试修改Spring Boot Devtools的范围。

 

这是利用了「provided」的条件,使其在打包时不再包含。

将范围定义为属性

Note: The provided translation is in Simplified Chinese.

	<properties>
		<java.version>11</java.version>
		<devtools.dependency.scope>runtime</devtools.dependency.scope>
	</properties>

将Spring Boot Devtools的scope设置为runtime为默认值。

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>${devtools.dependency.scope}</scope>
			<optional>true</optional>
		</dependency>

最后,在打包时指定范围的方式如下。

$ mvn package jib:dockerBuild -Ddevtools.dependency.scope=provided

这样一来,Spring Boot Devtools就不能正常工作了。

2022-06-22 15:29:28.859  INFO 1 --- [           main] com.example.spring.App                   : Starting App using Java 11.0.15 on a1826ae55975 with PID 1 (/app/classes started by root in /)
2022-06-22 15:29:28.862  INFO 1 --- [           main] com.example.spring.App                   : No active profile set, falling back to 1 default profile: "default"
2022-06-22 15:29:30.187  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

将spring.devtools.restart.enabled属性设置为false。

另一种方法是将spring.devtools.restart.enabled属性设置为false。

本次是将Jib的Maven插件的jvmFlags参数指定为指定的选项。

			<plugin>
				<groupId>com.google.cloud.tools</groupId>
				<artifactId>jib-maven-plugin</artifactId>
				<version>3.2.1</version>
				<configuration>
					<container>
						<jvmFlags>
							<jvmFlag>-Dspring.devtools.restart.enabled=false</jvmFlag>
						</jvmFlags>
					</container>
				</configuration>
			</plugin>

创建容器镜像。

$ mvn package jib:dockerBuild

在这里,结果与刚才一样。

2022-06-22 15:32:11.576  INFO 1 --- [           main] com.example.spring.App                   : Starting App using Java 11.0.15 on dfa3860ded97 with PID 1 (/app/classes started by root in /)
2022-06-22 15:32:11.578  INFO 1 --- [           main] com.example.spring.App                   : No active profile set, falling back to 1 default profile: "default"
2022-06-22 15:32:11.658  INFO 1 --- [           main] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2022-06-22 15:32:12.823  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
广告
将在 10 秒后关闭
bannerAds