基于Docker Compose的Spring Boot容器启动执行Liquibase脚本失败
1. 优先修正数据库连接地址
别用localhost、host.docker.internal这类环境相关的地址,直接用Docker Compose里MySQL服务的名称作为连接地址。比如你的MySQL服务叫mysql,那JDBC URL就写:
spring.datasource.url=jdbc:mysql://mysql:3306/your_database_name?useSSL=false&serverTimezone=UTC
Docker Compose默认会为所有服务创建内部DNS解析,服务名直接对应容器IP,这在任何Docker环境下都通用,不管是macOS还是Ubuntu。
2. 确保MySQL健康检查真的生效
很多时候健康检查命令写得不对,导致Spring Boot在MySQL还没完全就绪时就启动。给MySQL配置准确的健康检查:
services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: your_root_pw MYSQL_DATABASE: your_db MYSQL_USER: your_user MYSQL_PASSWORD: your_pw healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "your_user", "-pyour_pw"] interval: 3s timeout: 3s retries: 15
然后Spring Boot服务必须依赖MySQL的健康状态,而不是仅仅依赖服务启动:
services: spring-boot-app: build: . depends_on: mysql: condition: service_healthy
3. 确认Spring Boot镜像里的Liquibase文件没问题
进入Spring Boot容器,检查changelog文件是否在配置的路径下:
docker exec -it [你的Spring Boot容器ID/名称] bash # 假设你配置的是classpath:/db/changelog/master.xml,查看对应路径 ls /app/BOOT-INF/classes/db/changelog/
如果文件不存在,检查Dockerfile的复制命令是否正确。比如用Maven打包的话,要确保src/main/resources/db/changelog下的文件被复制到镜像中:
COPY src/main/resources/db/changelog/ /app/src/main/resources/db/changelog/ # 或者如果是用JAR包运行,确保打包时包含了这些文件(Maven默认会包含resources下的文件)
4. 检查MySQL的网络绑定配置
进入MySQL容器,查看my.cnf配置:
docker exec -it [MySQL容器ID/名称] cat /etc/mysql/my.cnf
如果有bind-address=127.0.0.1这一行,直接注释掉或者改成bind-address=0.0.0.0,否则MySQL只会接受本地连接,同一Docker网络的Spring Boot容器连不上。
同时查看MySQL日志,确认数据库正常启动:
docker logs [MySQL容器ID/名称]
看到ready for connections的日志,说明数据库已经就绪。
5. 验证Docker网络连通性
在Spring Boot容器里ping MySQL服务名,看能不能解析:
docker exec -it [你的Spring Boot容器ID/名称] ping mysql
如果ping不通,检查Docker Compose的网络配置,确保两个服务在同一个网络下:
networks: app-network: driver: bridge services: mysql: networks: - app-network spring-boot-app: networks: - app-network
内容的提问来源于stack exchange,提问作者JdF90

