Docker构建Kotlin Gradle应用失败(exit code1)求Dockerfile修改方案
问题描述
我在IntelliJ中创建了一个Kotlin应用,配置如下:
- 名称:ktdocker
- 构建系统:Gradle
- JDK:corretto-20
- Gradle DSL:Kotlin
- GroupID:com.demo
尝试容器化到Docker时,出现以下错误:
=> ERROR [builder 9/11] RUN ./gradlew dependencies --no-daemon ERROR: failed to solve: process "/bin/sh -c ./gradlew dependencies --no-daemon" did not complete successfully: exit code: 1
构建镜像使用命令:
docker build --tag ktdocker .
系统环境:Windows 11,目标是创建可在Google Cloud Run运行的Dockerfile。
相关文件内容
Dockerfile
# Use a lightweight Java runtime image FROM eclipse-temurin:17-jdk-alpine as builder # Set the working directory WORKDIR /app # Install necessary tools RUN apk add --no-cache bash curl git dos2unix # Copy Gradle wrapper and project files COPY gradlew ./ COPY gradle ./gradle COPY build.gradle.kts ./ COPY settings.gradle.kts ./ # Fix line endings and permissions for Gradle wrapper RUN dos2unix gradlew && chmod +x gradlew # Download Gradle dependencies RUN ./gradlew dependencies --no-daemon # Copy the application source code COPY src ./src # Build the application RUN ./gradlew build --no-daemon # Use a lightweight Java runtime image for the final build FROM eclipse-temurin:17-jre-alpine # Set the working directory WORKDIR /app # Copy the jar file from the build stage COPY --from=builder /app/build/libs/*.jar app.jar # Expose the application port (Cloud Run uses PORT) EXPOSE 8080 # Command to run the application ENTRYPOINT ["java", "-jar", "app.jar"]
Main.kt
package com.demo fun main() { val name = "Kotlin" println("Hello, " + name + "!") for (i in 1..5) { println("i = $i") } }
build.gradle.kts
plugins { kotlin("jvm") version "2.0.20" } group = "com.demo" version = "1.0-SNAPSHOT" repositories { mavenCentral() } dependencies { testImplementation(kotlin("test")) } tasks.test { useJUnitPlatform() } kotlin { jvmToolchain(20) }
./gradlew -v
------------------------------------------------------------ Gradle 8.8 ------------------------------------------------------------ Build time: 2024-05-31 21:46:56 UTC Revision: 4bd1b3d3fc3f31db5a26eecb416a165b8cc36082 Kotlin: 1.9.22 Groovy: 3.0.21 Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023 JVM: 23.0.1 (Oracle Corporation 23.0.1+11-39) OS: Windows 11 10.0 amd64
解决方案
需要针对以下关键问题修改Dockerfile:
1. 统一JDK版本(核心问题)
build.gradle.kts中指定了jvmToolchain(20),但Docker构建阶段使用的是JDK 17镜像,版本不匹配会导致Gradle依赖下载或编译失败。
修改方式:将构建阶段的基础镜像替换为JDK 20版本,推荐使用与本地一致的Amazon Corretto:
FROM amazoncorretto:20-alpine-jdk as builder
2. 合并Gradle命令优化构建流程
单独执行./gradlew dependencies容易因网络或缓存问题失败,建议直接将依赖下载合并到构建步骤,同时跳过测试加快构建速度:
修改方式:
# 移除单独的dependencies命令,替换为以下构建命令 COPY src ./src RUN ./gradlew build --no-daemon --no-build-cache --refresh-dependencies -x test
3. 同步运行阶段的JRE版本
编译后的字节码需要对应版本的JRE运行,因此最终镜像也要使用JRE 20:
FROM amazoncorretto:20-alpine-jre
4. 简化工具安装与换行符处理
无需安装curl和git,仅保留必要工具;同时确保Gradle wrapper配置文件的换行符也被修复:
RUN apk add --no-cache bash dos2unix RUN dos2unix gradlew gradle/wrapper/gradle-wrapper.properties && chmod +x gradlew
5. 适配Google Cloud Run环境变量
Cloud Run会自动注入PORT环境变量,添加环境变量声明以适配平台规范:
ENV PORT=8080 EXPOSE ${PORT}
修改后的完整Dockerfile
# 使用与项目匹配的JDK 20镜像作为构建阶段 FROM amazoncorretto:20-alpine-jdk as builder WORKDIR /app # 安装必要工具 RUN apk add --no-cache bash dos2unix # 复制Gradle相关文件 COPY gradlew ./ COPY gradle ./gradle COPY build.gradle.kts ./ COPY settings.gradle.kts ./ # 修复换行符和执行权限 RUN dos2unix gradlew gradle/wrapper/gradle-wrapper.properties && chmod +x gradlew # 复制源码并构建(跳过测试,确保依赖下载) COPY src ./src RUN ./gradlew build --no-daemon --no-build-cache --refresh-dependencies -x test # 运行阶段使用匹配的JRE 20镜像 FROM amazoncorretto:20-alpine-jre WORKDIR /app # 复制构建好的jar包 COPY --from=builder /app/build/libs/*.jar app.jar # 适配Cloud Run的PORT环境变量 ENV PORT=8080 EXPOSE ${PORT} # 运行应用 ENTRYPOINT ["java", "-jar", "app.jar"]
内容的提问来源于stack exchange,提问作者Europa
相关产品推荐
相关产品推荐

