【日常小问】解决 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. 对比差异:和能正常运行的环境对比,找出配置差异

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

相关推荐
为思念酝酿的痛21 小时前
POSIX信号量
linux·运维·服务器·后端
专业白嫖怪21 小时前
什么是docker
运维·docker·容器
sheeta19981 天前
LeetCode 每日一题笔记 日期:2026.05.29 题目:3300. 最小元素
笔记·leetcode
中屹指纹浏览器1 天前
2026指纹浏览器代理链路适配原理与多线路集群调度方案
经验分享·笔记
人还是要有梦想的1 天前
linux下用搜狗输入法,中英文切换
linux·运维·服务器
北京智和信通1 天前
某部队IT基础设施及机房动环统一运维建设实例
运维·网管平台·网管软件·网络管理系统·网络运维平台·网络运维系统
不羁的木木1 天前
ArkWeb实战学习笔记05-综合实战:构建混合应用
笔记·学习·harmonyos
乐维_lwops1 天前
从 “救火运维” 到 “自动驾驶”:运维智能体到底解决了什么?
运维·人工智能·运维智能体
bush41 天前
嵌入式linux学习记录二
linux·运维·学习
CC大煊1 天前
一个Javaer的AI转型笔记(1):入坑LangChain,我的第一个hello world
笔记·langchain