每次我执行 docker run ./gradlew 命令时,它都会下载所有 gradle 文件和依赖项。如何只下载和安装一次?

Posted

技术标签:

【中文标题】每次我执行 docker run ./gradlew 命令时,它都会下载所有 gradle 文件和依赖项。如何只下载和安装一次?【英文标题】:Each time I execute docker run ./gradlew command, it downloads all the gradle files and dependencies. How to download and install only once? 【发布时间】:2020-11-25 07:25:02 【问题描述】:

我有一个简单的 dockerfile 配置为构建 android 应用程序 一切运行良好,但问题是每次我运行./gradlew 命令时,它都会下载并安装所有 Gradle 工件和依赖项。我怎样才能只安装一次?

这是 dockerfile:

FROM openjdk:8

ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" \
    ANDROID_HOME="/usr/local/android-sdk" \
    ANDROID_VERSION=26 \
    ANDROID_BUILD_TOOLS_VERSION=26.0.2

# Download Android SDK
RUN mkdir "$ANDROID_HOME" .android \
    && cd "$ANDROID_HOME" \
    && curl -o sdk.zip $SDK_URL \
    && unzip sdk.zip \
    && rm sdk.zip \
    && yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses

# Install Android Build Tool and Libraries
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;$ANDROID_BUILD_TOOLS_VERSION" \
    "platforms;android-$ANDROID_VERSION" \
    "platform-tools"

RUN mkdir /application
WORKDIR /application

这是命令:

docker run -it --rm -v "$PWD":/application packsdkandroiddocker.image bash  ./gradlew assembleRelease --debug

【问题讨论】:

【参考方案1】:

根据您的 Dockerfile,您的 gradle 的缓存目录是 /root/.gradle。所以,你需要挂载一个卷到缓存目录来持久化缓存。

使用主机卷
docker run -it --rm -v $PWD/.gradle:/root/.gradle -v $PWD:/application packsdkandroiddocker.image bash ./gradlew assembleDebug
使用命名卷
docker volume create gradle-cache
docker run -it --rm -v gradle-cache:/root/.gradle -v $PWD:/application packsdkandroiddocker.image bash ./gradlew assembleDebug

【讨论】:

谢谢,它有帮助,我怎样才能使这个新创建的 $PWD/.gradle 在创建时不会成为 root? 使用这个环境变量GRADLE_USER_HOME来指定你想要的缓存目录 在哪里?因为它从 docker 运行【参考方案2】:

正如您毫无疑问地发现的那样,问题在于枚举所有 Gradle 任务的所有可能依赖项并下载它们......并非易事。

这不是最优雅的解决方案,但我之前已经解决了这个问题(在 GitLab CI Docker 运行器的上下文中),方法是在主机上挂载一个目录作为 GRADLE_USER_HOME 目录。这样,图像本身每次运行都是新鲜的,但缓存在运行之间共享。这确实意味着每个主机的初始运行仍然很慢,但它大大减少了后续运行所花费的时间。

具体取决于您要执行的操作,这可能是也可能不是令人满意的解决方案。

【讨论】:

以上是关于每次我执行 docker run ./gradlew 命令时,它都会下载所有 gradle 文件和依赖项。如何只下载和安装一次?的主要内容,如果未能解决你的问题,请参考以下文章

run as gradle test,未执行@Test中的内容(待解决)

如何在 circleci 作业中执行“docker run”命令

docker~run起来之后执行多条命令

docker run 之后执行多条命令

flutter 之Waiting for another flutter command to release the startup lock...和Running Gradle task '

Docker学习总结之Run命令介绍