Spring Boot切换至Docker容器化MySQL数据库启动失败问题排查求助
Let’s break down the most likely issues and how to fix them:
1. Fix the MySQL Environment Variable Mistake
Looking at your docker-compose.yml, the MySQL service has incorrect environment variables:
environment: - MYSQL_ROOT_PASSWORD=sa - MYSQL_USER=password
This is a critical error: you’ve set MYSQL_USER to password (which should be the password value) and omitted the MYSQL_PASSWORD variable entirely.
If you want to use the root user for testing (not recommended for production), you can remove the MYSQL_USER line—just keep MYSQL_ROOT_PASSWORD=sa. If you prefer a dedicated non-root user, correct the variables like this:
environment: - MYSQL_ROOT_PASSWORD=rootSecurePass - MYSQL_USER=sa - MYSQL_PASSWORD=password - MYSQL_DATABASE=customer # Pre-creates the database to avoid initialization delays
Note that the official MySQL image configures the root user to allow connections from any host (%) by default, so remote access from your Spring Boot container should work if credentials are correct.
2. Wait for MySQL to Be Fully Ready Before Starting Spring Boot
The depends_on directive only ensures the MySQL container starts—it doesn’t wait for the MySQL service to finish initializing (which takes a few seconds for database setup). Your Spring Boot app is likely trying to connect before MySQL is ready.
Here are two fixes:
Option A: Add Connection Retries to Spring Boot
Update your application.properties to include connection validation and retries:
spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.maximum-pool-size=10 # Validate connection before use, retry if needed spring.datasource.test-on-borrow=true spring.datasource.validation-query=SELECT 1 spring.datasource.validation-interval=30000
Option B: Use a Wait Script in Docker
Add the wait-for-it script to delay Spring Boot startup until MySQL’s 3306 port is reachable:
- Copy the
wait-for-it.shscript into your project directory - Update your Dockerfile to include the script:
FROM openjdk:16-alpine3.13 MAINTAINER krzysztof.com EXPOSE 8084 COPY wait-for-it.sh /wait-for-it.sh RUN chmod +x /wait-for-it.sh COPY target/myapp.jar myapp.jar ENTRYPOINT ["/wait-for-it.sh", "mysql-db2:3306", "--", "java", "-jar", "/myapp.jar"]
3. Verify Container Network Connectivity
Even though Docker Compose creates a shared network, confirm connectivity between containers:
- Enter your Spring Boot container:
docker exec -it mysql-docker-app sh - Ping the MySQL container to check DNS resolution:
ping mysql-db2 - Test the port with telnet:
telnet mysql-db2 3306
If either test fails, check that all services are in the same Docker network (run docker network ls to view the default Compose network).
4. Check MySQL Logs for Clues
Inspect the MySQL container logs to find initialization errors or connection refusals:
docker logs mysql-db2
Look for lines like Access denied for user 'sa'@'xxx.xxx.xxx.xxx' (invalid credentials) or MySQL init process done. Ready for start up. (MySQL is fully ready).
5. Unify Your Database URL Configuration
Your docker-compose.yml overrides SPRING_DATASOURCE_URL but omits critical parameters from application.properties: useSSL=false&serverTimezone=UTC. Inconsistent configurations can cause unexpected issues—either update the Compose variable to match the properties file, or remove the override to let the app use its internal configuration.
6. Confirm MySQL Driver Compatibility
Ensure your pom.xml uses a compatible MySQL Connector/J version for the latest MySQL image (8.0+). Using Spring Boot’s managed dependencies avoids version mismatches:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
内容的提问来源于stack exchange,提问作者kryzystof

