WSL2中Gradle容器化Kotlin Spring Boot应用遇问题求助
问题背景
在WSL2环境下,通过Gradle(Kotlin)将Spring Boot应用容器化,目标是完全通过Docker运行以避免本地依赖,执行docker-compose时遇到三个核心问题:
- 初始jar文件路径错误,提示
Unable to access jarfile ./build/libs/app.jar - 修改jar路径后出现MySQL连接失败:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure - 执行
docker buildx build时提示ERROR: "docker buildx build" requires exactly 1 argument.
1. jar文件路径错误解决
你已经通过docker-compose run yourapp ls build/libs定位到实际jar文件名是twitch-bot-0.0.1-SNAPSHOT.jar,修改Dockerfile中的CMD参数即可直接解决。此外建议优化Dockerfile为多阶段构建,大幅减少最终镜像体积:
优化后的Dockerfile:
# 构建阶段:使用Gradle镜像编译代码 FROM gradle:7.4.1-jdk17 AS builder WORKDIR /app COPY . . RUN ./gradlew clean build -x test # 运行阶段:使用轻量JRE镜像 FROM openjdk:17-jre-slim WORKDIR /app # 从构建阶段复制编译好的jar包 COPY --from=builder /app/build/libs/twitch-bot-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 CMD ["java", "-jar", "app.jar"]
如果后续jar版本变更不想每次修改Dockerfile,可以在构建阶段添加自动复制逻辑:
# 在构建阶段的RUN命令后添加,自动找到唯一jar并统一命名 RUN find /app/build/libs -name "*.jar" -exec cp {} /app/build/libs/app.jar \;
这样CMD可以固定为["java", "-jar", "./build/libs/app.jar"],避免版本号变更带来的重复修改。
2. MySQL连接失败解决
连接失败的核心原因有两个:
(1)容器内localhost指向错误
在Docker容器中,localhost指代容器自身,而非宿主机或MySQL容器。需要将Spring Boot配置中的数据库地址改为docker-compose中MySQL服务的名称mysql。
修改application.properties:
spring.datasource.url=jdbc:mysql://mysql:3306/twitch-bot?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=secret spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect # 适配最新MySQL版本 spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=update
添加额外参数解决SSL、密钥检索和时区问题,避免连接时的额外报错。
(2)MySQL未就绪时Spring Boot提前启动
depends_on仅保证服务启动顺序,不保证MySQL完全初始化就绪。需要给MySQL服务添加健康检查,让Spring Boot等待MySQL就绪后再启动。
修改docker-compose.yml:
version: '3' services: mysql: image: 'mysql:latest' environment: - 'MYSQL_DATABASE=twitch-bot' - 'MYSQL_PASSWORD=secret' - 'MYSQL_ROOT_PASSWORD=secret' # 移除无效的MYSQL_HOST=localhost,MySQL容器无需该变量 ports: - '3306:3306' healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-psecret"] interval: 5s timeout: 5s retries: 5 spring-boot-kotlin: depends_on: mysql: condition: service_healthy # 等待MySQL健康检查通过再启动 build: context: . dockerfile: Dockerfile ports: - '8080:8080'
3. docker buildx build参数错误解决
docker buildx build命令必须指定构建上下文(通常为当前目录.),正确的命令格式为:
docker buildx build .
如果需要指定镜像名称和标签:
docker buildx build -t your-image-name:tag .
更推荐直接使用docker-compose管理构建,无需单独执行build命令:
docker-compose up --build
该命令会自动构建Spring Boot镜像并启动所有服务,适配当前多服务场景。
内容的提问来源于stack exchange,提问作者AllAboutCake

