You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用本地正常运行,Docker容器中Tomcat无法启动求助

问题:Spring Boot应用本地正常运行,Docker容器中Tomcat未启动导致进程退出

我有一个使用Java编写的Spring Boot REST API应用,已添加@SpringBootApplication注解,其build.gradle配置如下:

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.2'
    id 'io.spring.dependency-management' version '1.1.4'
    id "com.github.johnrengelman.shadow" version "7.1.2" 
}

group = 'commandexecutor'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '17'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

shadowJar { 
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    mergeServiceFiles()
    manifest {
        attributes(
                'Class-Path': 'demo.main',
                'Main-Class': 'commandexecutor.demo.DemoApplication'
        )
    }
}

该应用在本地IDE中运行一切正常,但部署到Docker容器后,进程会在5-6秒后变为exited状态(原因是Tomcat未启动)。困惑于Tomcat在本地能成功启动但容器中不行的差异,请问根本原因是什么?


根本原因分析

  • 打包插件冲突:你同时用了Spring Boot官方打包插件和ShadowJar插件,二者在依赖处理、MANIFEST配置和类加载逻辑上存在冲突。Spring Boot自带的插件已经能生成可执行JAR,而你给ShadowJar手动配置的Main-Class和无效Class-Path直接破坏了Spring Boot的自动初始化流程,导致容器内无法启动Tomcat。
  • MANIFEST配置错误:ShadowJar里设置的Class-Path: demo.main是完全无效的路径,Spring Boot找不到必要的依赖和配置资源,自然启动不了Tomcat。本地IDE是直接加载编译后的类文件,不受这个错误配置影响,所以能正常运行。

解决方案

  1. 移除ShadowJar插件(推荐):如果不需要ShadowJar的特殊打包功能(比如合并多JAR、自定义类加载),直接删掉ShadowJar相关配置,用Spring Boot官方的bootJar任务打包即可:

    // 移除ShadowJar插件声明
    // id "com.github.johnrengelman.shadow" version "7.1.2"
    
    // 移除整个shadowJar配置块
    // shadowJar { ... }
    

    执行命令./gradlew bootJar生成可执行JAR,在Docker容器中运行该JAR就能正常启动Tomcat。

  2. 保留ShadowJar的适配配置:如果必须用ShadowJar,得调整配置适配Spring Boot的打包逻辑:

    shadowJar {
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
        mergeServiceFiles()
        // 不要手动指定Main-Class,仅设置Spring Boot所需的Start-Class
        manifest {
            attributes 'Start-Class': 'commandexecutor.demo.DemoApplication'
        }
        // 排除重复的Tomcat依赖,避免类加载冲突
        dependencies {
            exclude(dependency('org.springframework.boot:spring-boot-starter-tomcat'))
        }
    }
    

    同时要确保Docker镜像中运行的是ShadowJar生成的JAR包,启动命令正确无误。


内容的提问来源于stack exchange,提问作者Владислав Загородний

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:07:56