Gitlab CI/CD切换Docker执行器构建Android包Gradle卡住问题
核心问题点
你遇到的Gradle启动阶段卡住问题,是多个配置错误叠加导致的:
- 最致命的配置错误:自定义Dockerfile中下载的是macOS版本的Android命令行工具,Docker执行器运行的是Linux环境容器,macOS二进制无法在Linux下正常执行,Gradle调用SDK相关组件时会直接挂住,无任何报错输出
- 镜像与Runner配置错误:构建镜像时提前将本地代码COPY进镜像、工作目录与Gitlab CI默认构建路径不匹配,触发文件权限问题;Runner配置中
shm_size = 0,共享内存仅为默认64M,Android构建dex编译阶段所需内存远大于该值,会直接卡死无日志 - CI流程配置错误:CI环境下默认开启Gradle Daemon,三个构建任务并行时会争抢缓存锁;Dockerfile中仅写入了一个SDK许可哈希值,未提前接受所有Android SDK许可,无交互场景下进程会持续等待用户输入许可,永久阻塞
- 资源配置不合理:Runner配置
concurrent = 10并发过高,单Android构建任务至少需要2-4G内存,机器内存不足时进程会被系统直接OOM杀死,日志停留在Gradle启动阶段
修复方案
按以下步骤逐一调整配置即可恢复正常构建:
1. 重写自定义构建镜像的Dockerfile
丢弃之前错误的镜像配置,使用Linux版本SDK组件,移除多余的代码复制操作,提前接受所有SDK许可:
FROM jangrewe/gitlab-ci-android:latest USER root # 配置环境变量,注意命令行工具使用Linux版本 ENV ANDROID_HOME="/sdk" \ ANDROID_SDK_ROOT="/sdk" \ CMDLINE_TOOLS_PACKAGE="commandlinetools-linux-9477386_latest.zip" \ PATH="${PATH}:${ANDROID_HOME}/cmdline-tools/latest/bin:${ANDROID_HOME}/platform-tools" # 安装配置Android SDK RUN mkdir -p ${ANDROID_HOME}/cmdline-tools \ && cd ${ANDROID_HOME}/cmdline-tools \ && curl -o sdk.zip https://dl.google.com/android/repository/${CMDLINE_TOOLS_PACKAGE} \ && unzip -q sdk.zip \ && rm sdk.zip \ && mv cmdline-tools latest \ # 一次性接受所有SDK许可,避免构建时无交互阻塞 && yes | sdkmanager --licenses > /dev/null \ # 安装项目所需对应版本的SDK组件,版本号与项目build.gradle配置对齐 && sdkmanager "platform-tools" "platforms;android-30" "build-tools;30.0.3" \ # 清理临时文件减小镜像体积 && rm -rf /var/lib/apt/lists/* /tmp/* # 不要在构建镜像时COPY项目代码,CI执行时会自动拉取对应提交的代码到容器 # 切换回默认非root用户,避免文件权限问题 USER gitlab-runner
构建该镜像后重新推送到Gitlab容器仓库即可。
2. 调整Docker Runner的配置
修改Runner的config.toml配置,调整资源限制与缓存挂载,修改完成后重启Gitlab-Runner服务:
# 根据机器内存配置调整并发数,单任务按3G内存估算,8G内存建议设为2,16G内存建议设为4 concurrent = 4 check_interval = 0 [session_server] session_timeout = 1800 [[runners]] name = "docker-android" url = "你的Gitlab实例地址" token = "你的Runner令牌" executor = "docker" [runners.custom_build_dir] [runners.cache] [runners.cache.s3] [runners.cache.gcs] [runners.cache.azure] [runners.docker] tls_verify = false image = "你推送的自定义Android镜像地址" privileged = false disable_entrypoint_overwrite = false oom_kill_disable = false disable_cache = false # 挂载持久化缓存目录,避免每次构建重复下载Gradle依赖、SDK组件 volumes = ["/cache", "/cache/gradle:/home/gitlab-runner/.gradle"] # 共享内存设置为2G,满足Android构建dex阶段的内存需求 shm_size = 2147483648 # 镜像拉取策略优先使用本地镜像,减少构建等待时间 pull_policy = ["if-not-present"]
3. 优化.gitlab-ci.yml配置
关闭CI环境下无用的Gradle Daemon,增加构建内存参数,修正路径配置:
default: image: 你推送的自定义Android镜像地址 # 全局Gradle配置:关闭daemon、开启构建缓存、配置最大堆内存 variables: GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.caching=true -Xmx4g -XX:MaxMetaspaceSize=1g" GRADLE_USER_HOME: "${CI_PROJECT_DIR}/.gradle" before_script: - chmod +x ./gradlew # 构建前验证环境是否正常 - ./gradlew --version stages: - build create common folder to store build: stage: build needs: [] tags: - docker script: - mkdir -p popa artifacts: paths: - ./popa/ get debug apk build: stage: build needs: ["create common folder to store build"] tags: - docker script: - ./gradlew app:assembleGooglePlayDebug --no-daemon - mv app/build/outputs/apk/googlePlay/debug/*.apk ./popa/ artifacts: paths: - ./popa/ get release apk build: stage: build needs: ["create common folder to store build"] tags: - docker script: - ./gradlew app:assembleGooglePlayRelease --no-daemon - mv app/build/outputs/apk/googlePlay/release/*.apk ./popa/ artifacts: paths: - ./popa/ get release aab build: stage: build needs: ["create common folder to store build"] tags: - docker script: - ./gradlew app:bundleGooglePlayRelease --no-daemon - mv app/build/outputs/bundle/googlePlayRelease/*.aab ./popa/ artifacts: paths: - ./popa/ get one folder build: stage: build tags: - docker needs: ["get debug apk build", "get release apk build", "get release aab build"] script: - echo "构建完成,产物已归档" artifacts: paths: - ./popa/
验证说明
首次运行构建时因为需要下载Gradle依赖、项目依赖库,耗时会稍长,后续缓存命中后构建速度与原shell执行器基本一致。若仍有卡住问题,可在Gradle命令后加--info参数打印详细日志定位具体卡点。
内容的提问来源于stack exchange,提问作者user19358111
相关产品推荐
相关产品推荐

