Docker容器中Spring Boot连接MySQL容器失败问题求助
Docker Compose下Spring Boot连接MySQL失败排查
问题概述
通过Docker Compose部署Spring Boot应用和MySQL容器,两者处于同一自定义网络,MySQL容器状态健康且healthcheck验证通过,但Spring Boot始终无法连接到MySQL。已尝试使用服务名database、容器别名container_db、固定IP10.5.0.5三种方式配置JDBC URL,均失败。
现有配置片段
Dockerfile
FROM openjdk:21-jdk WORKDIR /app COPY out/artifacts/jar-with-dependencies.jar /app/your-spring-server.jar # 原尝试的启动命令 CMD ["java", "-jar", "/app/your-spring-server.jar", "--spring.datasource.url=jdbc:mysql://10.5.0.5:3307/my_db"] # 也曾试过 # CMD ["java", "-jar", "/app/your-spring-server.jar", "--spring.datasource.url=jdbc:mysql://container_db:3307/my_db"]
docker-compose.yml
services: database: image: mysql:latest container_name: container_db environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: my_db ports: - "3307:3306" healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u root", "-proot"] interval: 10s timeout: 5s retries: 3 networks: docker_network: aliases: - container_db ipv4_address: 10.5.0.5 spring_server: image: spring-app-img container_name: spring_server ports: - "8089:8088" depends_on: database: condition: service_healthy networks: docker_network: aliases: - spring_server ipv4_address: 10.5.0.6 networks: docker_network: driver: bridge name: my_network ipam: config: - subnet: 10.5.0.0/16 gateway: 10.5.0.1
核心问题分析
- 端口使用错误:容器间通信应使用MySQL容器内部的
3306端口,而非宿主机映射的3307端口。你在JDBC URL里写的3307是宿主机端口,容器内部访问MySQL不需要走端口映射。 - MySQL权限限制:默认情况下MySQL的
root用户只允许localhost访问,Spring Boot容器属于外部主机,没有访问权限。 - 连接参数缺失:Spring Boot连接MySQL时,通常需要指定
useSSL=false和allowPublicKeyRetrieval=true参数,否则可能因SSL或密钥问题连接失败;另外你未在启动参数里指定数据库用户名和密码。 - 冗余网络配置:Docker Compose默认支持服务名直接访问,手动指定固定IP和别名完全没必要,反而增加出错概率。
解决步骤
1. 修正JDBC URL
将端口改为3306,添加必要参数,同时指定用户名和密码:
CMD ["java", "-jar", "/app/your-spring-server.jar", \ "--spring.datasource.url=jdbc:mysql://database:3306/my_db?useSSL=false&allowPublicKeyRetrieval=true", \ "--spring.datasource.username=root", \ "--spring.datasource.password=root"]
直接用服务名
database即可,Docker Compose会自动解析到MySQL容器。
2. 授权MySQL远程访问
进入MySQL容器执行授权命令:
docker exec -it container_db mysql -uroot -proot
在MySQL命令行中执行:
GRANT ALL PRIVILEGES ON my_db.* TO 'root'@'%' IDENTIFIED BY 'root'; FLUSH PRIVILEGES;
%表示允许从任意主机访问,也可以指定Spring容器的IP10.5.0.6更安全。
3. 简化网络配置(可选)
去掉docker-compose.yml中手动指定的IP和别名,简化后网络配置如下:
services: database: # ... 其他配置不变 ... networks: - docker_network spring_server: # ... 其他配置不变 ... networks: - docker_network networks: docker_network: driver: bridge name: my_network
Docker Compose会自动处理服务发现,服务名
database依然可以正常访问。
4. 重新构建并启动服务
docker-compose down docker-compose build spring_server docker-compose up -d
内容的提问来源于stack exchange,提问作者valentin.ciprian
相关产品推荐
相关产品推荐

