【日常小问】解决 Jenkins 部署 Spring Cloud 微服务到 Docker 容器启动失败的问题

一、问题出现

在使用 Jenkins 进行 CI/CD 部署 Spring Cloud 微服务项目时,遇到了一个让人头疼的问题:所有通过 Jenkins 构建的 Docker 容器启动后立即退出,状态码为 Exited (1)

查看容器日志,报错信息如下:

复制代码
***************************
APPLICATION FAILED TO START
***************************

Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason:
Failed to determine a suitable driver class

看起来是数据库配置没有加载到,但奇怪的是,同样的项目在其他人的电脑上可以正常运行,唯独到了我的环境就各种报错。

二、问题原因

经过一番排查,发现这个问题其实是三个独立的问题叠加导致的:

2.1 Docker 网络不通

项目的各个微服务(Nacos、MySQL、Redis 等)部署在同一个 Linux 虚拟机的 Docker 中,但它们分布在不同的 Docker 网络里:

容器 所在网络 说明
Nacos、MySQL、Redis tjxt 手动部署时创建的网络
Jenkins 构建的应用容器 heima-net 启动脚本中指定的网络

两个网络互相隔离,导致应用容器根本访问不到 Nacos 和 MySQL。

2.2 Nacos 认证信息缺失

项目使用了 Spring Cloud Alibaba Nacos 作为配置中心和服务注册发现中心。但 bootstrap.yml没有配置 Nacos 的地址和认证信息 ,默认使用 localhost:8848

在 Docker 容器中,localhost 指向的是容器自己,而不是宿主机的 Nacos 服务。即使网络通了,没有正确的地址和认证信息也无法连接。

2.3 共享配置位置错误

在修改 bootstrap.yml 添加 Nacos 配置时,不小心把 shared-configs(共享配置)放在了 discovery(服务发现)下面,而不是 config(配置中心)下面。这导致应用虽然能连接 Nacos,但无法加载共享的数据库配置

复制代码
# ❌ 错误的结构
spring:
  cloud:
    nacos:
      config:
        server-addr: 192.168.150.101:8848
        username: nacos
        password: nacos
        file-extension: yaml
      discovery:
        server-addr: 192.168.150.101:8848
        username: nacos
        password: nacos
        shared-configs:  # ❌ 放在 discovery 下面,不会被加载
          - data-id: shared-mybatis.yaml
            refresh: false

三、解决问题

3.1 解决 Docker 网络问题

方法一:修改 Jenkins 启动脚本(推荐)

编辑 /usr/local/src/script/startup.sh,将 --network heima-net 改为 --network tjxt

复制代码
# 修改前
--network heima-net ${IMAGE_NAME} \

# 修改后
--network tjxt ${IMAGE_NAME} \

方法二:手动连接网络

如果不想修改脚本,也可以手动将容器连接到正确的网络:

复制代码
docker network connect tjxt tj-user
docker network connect tjxt tj-trade
docker restart tj-user tj-trade

3.2 配置 Docker 镜像加速器

在国内网络环境下,Docker Hub 经常超时。配置镜像加速器可以显著提升拉取镜像的速度:

复制代码
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.1ms.run",
    "https://docker.xuanyuan.me"
  ]
}
EOF

sudo systemctl daemon-reload
sudo systemctl restart docker

3.3 添加 Nacos 认证配置

在每个微服务的 bootstrap.yml 中添加 Nacos 的地址和认证信息。注意 shared-configs 必须在 config 下面

复制代码
spring:
  cloud:
    nacos:
      config:
        server-addr: 192.168.150.101:8848
        username: nacos
        password: nacos
        file-extension: yaml
        shared-configs: # ✅ 正确位置:在 config 下面
          - data-id: shared-spring.yaml
            refresh: false
          - data-id: shared-redis.yaml
            refresh: false
          - data-id: shared-mybatis.yaml
            refresh: false
          - data-id: shared-logs.yaml
            refresh: false
          - data-id: shared-feign.yaml
            refresh: false
      discovery:
        server-addr: 192.168.150.101:8848
        username: nacos
        password: nacos

为什么需要配置两份认证?

Nacos 在 Spring Cloud 中承担了两个角色:

  • 配置中心(Config):存储和管理配置文件,应用启动时从这里拉取数据库、Redis 等配置
  • 服务注册发现(Discovery):服务启动时注册自己的地址,让其他服务能找到自己

两个功能是独立的请求,所以需要分别配置认证信息。

3.4 重新构建部署

完成以上修改后:

  1. 将代码提交到 Gogs

  2. 删除旧的 Docker 容器和镜像

  3. 重新触发 Jenkins 构建

    删除旧容器和镜像

    docker rm -f tj-user tj-trade
    docker rmi tj-user:latest tj-trade:latest

四、总结

这次问题的根本原因是环境差异 :在 IDE 中直接运行时,localhost 指向宿主机,Nacos 认证信息可以通过其他方式注入;但在 Docker 容器中,网络隔离和配置缺失的问题被放大了。

排查这类问题的思路是:

  1. 先看日志docker logs 容器名 是最直接的排查手段
  2. 分层排查:网络 → 连接 → 认证 → 配置,逐层检查
  3. 对比差异:和能正常运行的环境对比,找出配置差异

希望这篇文章能帮到遇到类似问题的朋友。

相关推荐
AC赳赳老秦1 小时前
故障自愈实战:用 OpenClaw 实现服务器日志自动化分析、根因定位、解决方案自动生成
大数据·运维·服务器·自动化·github·deepseek·openclaw
晓梦林1 小时前
Fuzzz靶场学习笔记
笔记·学习·安全·web安全
一只积极向上的小咸鱼1 小时前
Linux 下 Claude Code 配置文件位置总结
linux·运维·服务器
七牛云行业应用1 小时前
GPT-5.5 Instant vs Grok 4 完整对比【2026年5月最新】:哪个大模型更适合开发者?
人工智能·docker·github·ai实战·大模型部署·claude opus 4.7·api接入
j_xxx404_1 小时前
Linux共享内存原理与实战:从内核到C++实现|附源码
linux·运维·开发语言·c++·人工智能
Hammer_Hans1 小时前
DFT笔记47
笔记
汪汪大队u1 小时前
从 Docker Compose 到 Kubernetes:物联网管理系统迁移实战(续1)
物联网·docker·容器·kubernetes
Anjgst1 小时前
宝塔面板命令行
linux·运维·服务器·笔记
程序猿乐锅1 小时前
【Tilas|第七篇】学员管理实现
java·笔记·idea·tlias