如何让Spring Boot项目通过Docker一键运行无需本地MySQL配置
你的核心需求是让用户无需本地MySQL,仅通过三条命令就能启动项目,现有配置有几个小问题需要调整,下面是具体修改方案:
1. 修正Dockerfile文件名匹配问题
你的docker-compose.yml里写的是dockerfile: DockerFile,但实际文件名是Dockerfile(小写f),这会导致构建时找不到文件,直接修改docker-compose里的对应行:
build: context: . dockerfile: Dockerfile # 把DockerFile改成Dockerfile
2. 解决MySQL未就绪导致Spring连接失败的问题
depends_on只会保证容器启动顺序,但MySQL启动后还需要时间初始化数据库,这时Spring去连接会报错。我们可以给MySQL加健康检查,让web_app等MySQL完全就绪后再启动:
修改docker-compose.yml里的mysqldb服务:
mysqldb: image: mysql:8.0 # 指定具体版本,避免最新版本兼容性问题 restart: unless-stopped env_file: ./.env environment: - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD - MYSQL_DATABASE=$MYSQLDB_DATABASE - MYSQL_USER=$MYSQLDB_USER # 补充创建指定用户,避免用root连接(可选但更规范) - MYSQL_PASSWORD=$MYSQLDB_ROOT_PASSWORD ports: - ${MYSQLDB_LOCAL_PORT}:${MYSQLDB_DOCKER_PORT} volumes: - db:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "$MYSQLDB_USER", "-p$MYSQLDB_ROOT_PASSWORD"] timeout: 20s retries: 10
然后修改web_app服务的depends_on,加上健康检查依赖:
web_app: depends_on: mysqldb: condition: service_healthy # 等MySQL健康检查通过再启动
3. 修正Spring环境变量解析问题
原来的SPRING_APPLICATION_JSON用了单引号,docker-compose不会解析里面的$变量,改成拆成单独的环境变量更可靠(可读性更好):
替换web_app里的environment部分:
environment: - SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb:${MYSQLDB_DOCKER_PORT}/${MYSQLDB_DATABASE}?allowPublicKeyRetrieval=true&useSSL=false - SPRING_DATASOURCE_USERNAME=${MYSQLDB_USER} - SPRING_DATASOURCE_PASSWORD=${MYSQLDB_ROOT_PASSWORD} - SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQLDialect - SPRING_JPA_HIBERNATE_DDL_AUTO=update
4. 移除不必要的配置
web_app里的stdin_open: true、tty: true和.m2挂载可以去掉,因为镜像构建时已经把jar包打包进去了,不需要本地maven仓库挂载。
5. (可选)Spring Boot端添加连接重试配置
为了更保险,在Spring Boot的application.properties或application.yml里添加连接重试配置,即使健康检查有延迟,Spring也会自动重试:
application.properties:
spring.datasource.hikari.connection-timeout=60000 spring.datasource.hikari.maximum-pool-size=10 spring.jpa.open-in-view=false # 连接重试 spring.datasource.hikari.validation-timeout=3000 spring.datasource.hikari.connection-test-query=SELECT 1
修改后的完整配置文件
.env(无需修改)
MYSQLDB_USER=root MYSQLDB_ROOT_PASSWORD=12345 MYSQLDB_DATABASE=familybudgetapp MYSQLDB_LOCAL_PORT=3307 MYSQLDB_DOCKER_PORT=3306 SPRING_LOCAL_PORT=8081 SPRING_DOCKER_PORT=8081
Dockerfile(无需修改)
FROM openjdk:17-jdk-slim EXPOSE 8081 ARG JAR_FILE=target/family-budget-app-0.0.1-SNAPSHOT.jar ADD ${JAR_FILE} family-budget-app.jar ENTRYPOINT ["java","-jar","family-budget-app.jar"]
docker-compose.yml(修改后)
version: "3.8" services: mysqldb: image: mysql:8.0 restart: unless-stopped env_file: ./.env environment: - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD - MYSQL_DATABASE=$MYSQLDB_DATABASE - MYSQL_USER=$MYSQLDB_USER - MYSQL_PASSWORD=$MYSQLDB_ROOT_PASSWORD ports: - ${MYSQLDB_LOCAL_PORT}:${MYSQLDB_DOCKER_PORT} volumes: - db:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "$MYSQLDB_USER", "-p$MYSQLDB_ROOT_PASSWORD"] timeout: 20s retries: 10 web_app: depends_on: mysqldb: condition: service_healthy build: context: . dockerfile: Dockerfile restart: on-failure env_file: ./.env ports: - ${SPRING_LOCAL_PORT}:${SPRING_DOCKER_PORT} environment: - SPRING_DATASOURCE_URL=jdbc:mysql://mysqldb:${MYSQLDB_DOCKER_PORT}/${MYSQLDB_DATABASE}?allowPublicKeyRetrieval=true&useSSL=false - SPRING_DATASOURCE_USERNAME=${MYSQLDB_USER} - SPRING_DATASOURCE_PASSWORD=${MYSQLDB_ROOT_PASSWORD} - SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT=org.hibernate.dialect.MySQLDialect - SPRING_JPA_HIBERNATE_DDL_AUTO=update volumes: db:
使用说明
用户只需要执行以下命令即可启动项目,无需任何本地数据库配置:
./mvnw clean package && docker-compose build && docker-compose up
启动后访问http://localhost:8081即可使用你的Spring Boot应用。
内容的提问来源于stack exchange,提问作者Taha Ünsal

