【问题标题】:How to populate Gradle cache in a Docker image?如何在 Docker 映像中填充 Gradle 缓存?
【发布时间】:2019-02-21 21:57:16
【问题描述】:

我正在尝试构建用于开发 Android 应用程序的 Docker 映像。我有一个安装 JDK、Android SDK + NDK 的镜像。

当我运行映像并运行 gradle 包装器 (gradlew) 时,包装器会下载最新的 Gradle,然后是我的应用程序的所有依赖项,所以我看到如下消息:

Download https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.1.4/gradle-3.1.4.pom
Download https://dl.google.com/dl/android/maven2/com/android/tools/build/builder/3.1.4/builder-3.1.4.pom
...
Download https://jcenter.bintray.com/org/jetbrains/kotlin/kotlin-stdlib-jre8/1.2.0/kotlin-stdlib-jre8-1.2.0.pom
Download https://jcenter.bintray.com/com/squareup/javawriter/2.5.0/javawriter-2.5.0.pom
...
Download https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle/3.1.4/gradle-3.1.4.jar
Download https://dl.google.com/dl/android/maven2/com/android/tools/build/gradle-core/3.1.4/gradle-core-3.1.4.jar

等等

由于 Docker 容器的特性,每次我运行一个新容器时,它都必须重新下载所有这些依赖项,就好像这是第一次一样。 (我可以重复使用容器,但我希望使用此图像的每个人都不必下载这些文件;并且出于其他原因,每次都使用新容器是可取的。)所以我想让它们“烘焙”进入” Docker 映像。最好的方法是什么?

一个想法是向 Dockerfile 添加指令以复制到我的项目的源代码中并进行构建(然后从映像中删除项目文件)。然而,这似乎很棘手(我们应该忽略不被 .git 跟踪的文件)和浪费(为什么实际上要进行整个构建;我只想下载这些文件并将其放入适当的位置)。

另一种选择是进行构建,从构建输出中获取所有这些 URL,找出它们应该在磁盘上的位置(不知道如何执行此操作),然后在 Dockerfile 中添加指令以手动复制他们到位。但这似乎需要做很多工作,并且当我的应用依赖项发生变化时需要手动更新。

似乎应该有一种方法可以复制 gradle 包装器和一组最小的 gradle 构建文件并要求它“仅恢复依赖项”,但我一直无法找到这样的目标。有没有办法做到这一点?

【问题讨论】:

    标签: android docker gradle android-gradle-plugin gradlew


    【解决方案1】:

    我通过创建一个精简版的build.gradle 脚本来缓存下载,并使用它来触发我的 Dockerfile 中的下载。因此,我的 Dockerfile 目录还包含 gradle 包装器(gradlew 脚本和关联的 gradle 目录,其中包含 .jar)、我的最小 build.gradle 文件以及满足 android 插件所需的最小虚拟 AndroidManifest.xml 文件.

    (这不是理想的 IMO,所以如果有人有更好的方法,我仍然很想听听。)

    从我的 Dockerfile 中,我像这样触发下载:

    # The following steps use some dummy build files to trigger gradle to download depencies,
    # so that they will be available in the image.
    COPY . /tmp/triggerGradleDownloads/
    
    RUN     cd /tmp/triggerGradleDownloads
        && ./gradlew --no-daemon --refresh-dependencies androidDependencies lint
        && rm -rf /tmp/triggerGradleDownloads
    

    ./src/main/AndroidManifest.xml 的内容:

    <?xml version="1.0" encoding="utf-8"?>
    <!-- we just need a package name in this file to satisfy the android plugin -->
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dummy">
    </manifest>
    

    我的 build.gradle 文件的内容:

    // This is a cut-down and hacked-together build script used only to trigger download of dependencies.
    // From your Dockerfile, run "./gradlew --no-daemon --refresh-dependencies androidDependencies lint".
    
    buildscript {
    
        repositories {
            google()
            jcenter()
        }
        dependencies {
            classpath 'com.android.tools.build:gradle:3.1.4'
        }
    }
    
    allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    
    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 28
        defaultConfig {
            minSdkVersion 15
            targetSdkVersion 28
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
        implementation 'com.android.support.constraint:constraint-layout:1.1.3'
        implementation 'com.android.support:design:28.0.0-rc02'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用 Artifactory 运行您自己的本地 Maven 工件缓存。

      【讨论】:

      • 对不起;我在 gradle 下载的东西列表中看到了 maven 相关的东西,但我认为这实际上与 maven 没有任何关系。 (我对 java/android/gradle/maven 完全陌生,所以我可能是错的。)我更新了标题以删除“maven”。
      • Gradle 只是基于 maven 构建的,您可以将 Gradle 指向一个工件,就像使用 Maven 一样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2020-02-23
      • 2018-06-27
      • 2021-04-07
      • 1970-01-01
      • 2023-03-14
      相关资源
      最近更新 更多