Spring Boot应用在Docker容器中崩溃(命令行运行正常)
我有一个小型Spring Boot REST服务,本地用java -jar myapp.jar运行完全正常,但部署到Docker容器后,调用curl访问服务时容器直接崩溃,抛出JVM致命错误:
A fatal error has been detected by the Java Runtime Environment:
SIGSEGV (0xb) at pc=0x00007f052205991a, pid=1, tid=40
JRE version: OpenJDK Runtime Environment Temurin-19.0.1+10 (19.0.1+10)
(build 19.0.1+10) Java VM: OpenJDK 64-Bit Server VM Temurin-19.0.1+10
(19.0.1+10, mixed mode, sharing, tiered, compressed oops, compressed class ptrs)
Problematic frame: V [libjvm.so+0xe2f91a] JVM_handle_linux_signal+0x13a
相关配置信息
Dockerfile内容:
FROM amd64/eclipse-temurin:19.0.1_10-jre-alpine VOLUME /opt/galleries RUN mkdir -p /opt/rest.galleries/logs/ ARG JAR_FILE ADD ${JAR_FILE} /opt/rest.galleries/app.jar EXPOSE 8000 ENTRYPOINT ["java","-jar","/opt/rest.galleries/app.jar"]
容器启动命令:
docker run -p 8000:8000 -v /opt/galleries:/opt/galleries --memory="1g" --memory-swap="2g" -t craigfoote/rest.galleries:latest &
图片处理依赖:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-imaging</artifactId> <version>1.0-alpha3</version> </dependency> <dependency> <groupId>org.sejda.imageio</groupId> <artifactId>webp-imageio</artifactId> <version>0.1.6</version> </dependency>
Maven镜像构建插件:
<plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.13</version> <executions> <execution> <id>default</id> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <repository>${project.artifactId}</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin>
崩溃发生在调用ImageIO.read(file); // file为238kB的WebP图片时。本地运行正常,排除代码逻辑问题,尝试增加容器内存到4G、swap到8G仍未解决,且无法找到崩溃时生成的hs_err_pid1.log文件。
解决思路
定位崩溃日志文件:修改Docker的ENTRYPOINT,显式指定JVM错误日志输出到挂载的卷目录,比如:
ENTRYPOINT ["java", "-XX:ErrorFile=/opt/galleries/hs_err_pid%p.log", "-jar", "/opt/rest.galleries/app.jar"]这样崩溃日志会写入宿主机的
/opt/galleries目录,可直接查看具体崩溃堆栈和原因。替换Alpine基础镜像:Alpine使用musl libc而非glibc,webp-imageio依赖的native库可能存在兼容性问题。换成非Alpine的Temurin镜像:
FROM amd64/eclipse-temurin:19.0.1_10-jre重新构建镜像后测试是否还会崩溃。
升级webp-imageio依赖:当前使用的0.1.6版本较旧,升级到最新稳定版(如0.2.2),新版本可能修复了容器环境下的native库兼容性问题:
<dependency> <groupId>org.sejda.imageio</groupId> <artifactId>webp-imageio</artifactId> <version>0.2.2</version> </dependency>显式指定JVM内存参数:本地与容器环境的JVM默认参数可能存在差异,显式设置堆内存参数,避免内存分配异常:
修改ENTRYPOINT为:ENTRYPOINT ["java", "-Xmx512m", "-Xms256m", "-jar", "/opt/rest.galleries/app.jar"]检查文件权限:确认容器内挂载目录
/opt/galleries下的WebP文件具备可读权限,可在启动容器时添加--user参数指定用户,或给宿主机文件添加全局可读权限。
内容的提问来源于stack exchange,提问作者CraigFoote

