Docker Compose 部署 Spring Boot 应用 502 Bad Gateway 问题排查与解决

问题描述

在使用 Docker Compose 部署周报系统后,前端访问登录接口时出现 502 Bad Gateway 错误:

复制代码
POST http://172.16.xxx.xxx:5173/api/login 502 (Bad Gateway)

前端控制台错误信息:

javascript 复制代码
AxiosError: Request failed with status code 502
    at ot (request-BdhJx_rg.js:3:1078)
    at XMLHttpRequest.E (request-BdhJx_rg.js:3:5798)

问题分析

1. 502 Bad Gateway 错误含义

502 Bad Gateway 表示 Nginx 作为反向代理无法连接到后端服务。常见原因包括:

  • 后端容器未启动或已崩溃
  • 后端服务监听端口配置错误
  • 后端服务启动失败
  • 网络连接问题

2. 排查步骤

第一步:检查容器状态
bash 复制代码
docker-compose ps

所有容器是否都在运行,不应该啊!!!??

第二步:查看后端日志
bash 复制代码
docker-compose logs backend --tail=100

关键发现:

复制代码
weekly-backend  | no main manifest attribute, in app.jar
weekly-backend  | no main manifest attribute, in app.jar
weekly-backend  | no main manifest attribute, in app.jar
...

这个错误信息表明:jar 包中缺少主清单属性,导致 Java 无法找到主类来启动应用程序。

为什么?我明明存在该jar包,为什么会出现缺少主清单的app.jar

进一步分析

1. 检查 jar 包清单文件

bash 复制代码
unzip -p weekly.jar META-INF/MANIFEST.MF

发现的问题:

复制代码
Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.4.1
Build-Jdk-Spec: 11

啊?为什么清单文件内容不完整,缺少了 Spring Boot 可执行 jar 包所需的关键属性。

2. 正确的清单文件应该包含

复制代码
Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.4.1
Build-Jdk-Spec: 11
Main-Class: org.springframework.boot.loader.JarLauncher    ← 缺少
Start-Class: com.example.SpringbootApplication            ← 缺少
Spring-Boot-Version: 2.6.13                               ← 缺少
Spring-Boot-Classes: BOOT-INF/classes/                    ← 缺少
Spring-Boot-Lib: BOOT-INF/lib/                            ← 缺少

3. 根本原因

检查 pom.xml 文件发现配置错误:

xml 复制代码
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring-boot.version}</version>
    <configuration>
        <mainClass>com.example.Car-endApplication</mainClass>  ← 主类名称错误
        <skip>true</skip>                                        ← 跳过构建
    </configuration>
    <executions>
        <execution>
            <id>repackage</id>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

问题分析:

  1. 主类名称错误 :com.example.Car-endApplication 应该是 com.example.SpringbootApplication
  2. 跳过构建 :<skip>true</skip> 导致打包时跳过了 Spring Boot Maven Plugin 的 repackage 阶段
  3. 结果:生成的是普通 jar 包而不是可执行的 Spring Boot fat jar

如果 pom.xml 文件没有发现配置错误?那就是IDEA受网络波动影响导致打包一半(作者就是出现这个原因,真的是百思不得其解!气死了)

解决方案

1. 修复 pom.xml 配置

xml 复制代码
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring-boot.version}</version>
    <configuration>
        <mainClass>com.example.SpringbootApplication</mainClass>
    </configuration>
    <executions>
        <execution>
            <id>repackage</id>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

修改内容:

  • 修正主类名称:com.example.Car-endApplication → com.example.SpringbootApplication
  • 删除跳过构建配置:移除 <skip>true</skip>

2. 重新打包项目

在本地开发机器上执行:

bash 复制代码
cd d:\jiangcaidu\code\周报\Weekly_end

# 清理并重新打包
mvn clean package -DskipTests

3. 验证打包结果

bash 复制代码
# 查看 jar 包大小
dir target\Weekly_end-0.0.1-SNAPSHOT.jar

# 查看清单文件
jar xf target\Weekly_end-0.0.1-SNAPSHOT.jar META-INF\MANIFEST.MF
type META-INF\MANIFEST.MF

正确的清单文件:

复制代码
Manifest-Version: 1.0
Created-By: Maven JAR Plugin 3.4.1
Build-Jdk-Spec: 11
Main-Class: org.springframework.boot.loader.JarLauncher
Start-Class: com.example.SpringbootApplication
Spring-Boot-Version: 2.6.13
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Spring-Boot-Layers-Index: BOOT-INF/layers.idx

终于是正确了!

jar 包特征:

  • 文件大小:50MB - 100MB(包含所有依赖)
  • 清单文件包含 Main-Class 和 Start-Class

4. 接着上传新的 jar 包到服务器

bash 复制代码
# 在服务器上,备份旧的 jar 包
mv weekly.jar weekly.jar.backup

# 上传新的 jar 包到这个目录,并重命名为 weekly.jar

5. 重新构建 Docker 镜像

关键步骤 :必须重新构建 Docker 镜像,因为 Dockerfile 中的 COPY weekly.jar app.jar 会在构建时将 jar 包复制到镜像内部。

bash 复制代码
# 停止并删除旧容器
docker-compose down

# 重新构建后端镜像(使用新的 jar 包)
docker-compose build backend

# 启动服务
docker-compose up -d

# 查看后端日志
docker-compose logs backend -f

6. 验证服务启动成功

后端启动成功后,日志应该显示:

复制代码
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::               (v2.6.13)

...
Started SpringbootApplication in X.XXX seconds (JVM running for X.XXX)

参考资源


如果部署中遇到502 Bad Gateway,觉得有帮助,欢迎点赞收藏!有问题欢迎评论区交流~

相关推荐
霸道流氓气质28 分钟前
OpenTelemetry 入门与实战:Java Agent、Spring Boot Starter与LLM调用追踪示例
java·开发语言·spring boot
m0_5873830034 分钟前
24 小时自助健身房系统软件开发实战指南与案例解析
java·spring boot·spring·系统架构·需求分析
爱编程的小白L38 分钟前
基于SpringBoot+Vue的医院门诊排队叫号系统的设计与实现
spring boot
程序员老赵1 小时前
Docker 部署 WordPress:轻松搭建开源内容管理平台
docker·开源·wordpress
马剑威(威哥爱编程)1 小时前
【AI全栈后端12-12】Spring Boot 3.x 到 4.x 迁移实操:Jakarta 11、Jackson 3 与 AI 2.0
java·开发语言·spring boot·后端
IT研究室1 小时前
最新计算机毕业设计选题推荐-基于spring boot的心桥·心理健康综合服务平台-网站-文档指导-Java-springboot
java·spring boot·课程设计
知守观1 小时前
feign-core 就在依赖树里,运行时却找不到类:一次 provided scope 引发的启动失败排查
java·spring cloud·maven
她的男孩1 小时前
企业接口照样拦得住:独立 Flyway、@RequiresFeature 与离线许可证
java·spring boot·后端
十年Java程序媛2 小时前
Lambda 与函数式接口|别只会复制 ()->{},底层规则和坑一次性讲清
java·spring boot·后端
sbjdhjd2 小时前
云安全 | 从特权容器到旧版 runC:Docker 宿主机访问与运行时缺陷复盘
运维·网络安全·docker·云原生·kubernetes·云计算·云安全