Docker Compose中SpringBoot服务无法连接MySQL容器求助
Docker Compose中SpringBoot连接MySQL容器被拒绝问题解决
问题场景
单独运行MySQL Docker镜像,本地启动SpringBoot服务可正常连接;但通过Docker Compose同时启动两者时,连接被拒绝,已尝试自定义网络等方案,耗时2天仍未解决。
现有配置
Docker Compose配置
version : '3.8' services: healthcare: build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: - mysql restart: always environment: RDS_URL: mysql networks: - saman-network mysql: image: mysql:8-oracle container_name: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: hospital_db MYSQL_USER: saman MYSQL_PASSWORD: saman volumes: - myvolume:/var/lib/mysql ports: - "3308:3306" networks: - saman-network volumes: myvolume: networks: saman-network:
application.properties配置
server.port=8080 spring.application.name=healthcare spring.datasource.url=jdbc:mysql://${RDS_URL:localhost}:3308/hospital_db spring.datasource.username=saman spring.datasource.password=saman spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
错误信息
springboot-hospitalmng-sample-healthcare-1 | ... 46 common frames omitted springboot-hospitalmng-sample-healthcare-1 | Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure
springboot-hospitalmng-sample-healthcare-1 | ... 59 common frames omitted springboot-hospitalmng-sample-healthcare-1 | Caused by: java.net.ConnectException: Connection refused springboot-hospitalmng-sample-healthcare-1 | at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] springboot-hospitalmng-sample-healthcare-1 | at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] springboot-hospitalmng-sample-healthcare-1 | at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542) ~[na:an] springboot-hospitalmng-sample-healthcare-1 | The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. springboot-hospitalmng-sample-healthcare-1 | 2023-01-05T14:20:37.165Z ERROR 1 --- [ main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
问题原因及解决方案
1. 数据库端口错误
容器间通信使用容器内部端口,而非映射到主机的端口。你的MySQL容器内部端口是3306,主机映射端口是3308,但SpringBoot容器连接时用了3308,导致无法访问。
修改application.properties中的数据库URL:
spring.datasource.url=jdbc:mysql://${RDS_URL:localhost}:3306/hospital_db
2. MySQL未完全就绪时SpringBoot已启动
depends_on仅保证容器启动顺序,不保证MySQL服务已完全初始化。需要添加健康检查,让SpringBoot等待MySQL就绪后再启动。
修改Docker Compose配置:
version : '3.8' services: healthcare: build: context: . dockerfile: Dockerfile ports: - "8080:8080" depends_on: mysql: condition: service_healthy # 等待MySQL健康检查通过 restart: always environment: RDS_URL: mysql networks: - saman-network mysql: image: mysql:8-oracle container_name: mysql environment: MYSQL_ROOT_PASSWORD: root MYSQL_DATABASE: hospital_db MYSQL_USER: saman MYSQL_PASSWORD: saman volumes: - myvolume:/var/lib/mysql ports: - "3308:3306" networks: - saman-network healthcheck: # 添加健康检查 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "saman", "-psaman"] interval: 5s timeout: 5s retries: 10 volumes: myvolume: networks: saman-network:
验证修改
执行docker-compose down清理现有容器,再执行docker-compose up --build重新构建启动。此时SpringBoot会等待MySQL服务完全就绪后再尝试连接,端口也符合容器间通信要求,即可正常建立连接。
内容的提问来源于stack exchange,提问作者Saman KHATAEI
相关产品推荐
相关产品推荐

