frezzen
frezzen

Reputation: 51

Android SDK on Docker for ARM64 (Raspberry Pi 4) for building APK

I am trying to create an ARM64 Docker image which is able to build an apk file of my React Native app.

Background:

For exercise purposes I built a Kubernetes cluster wiht 5 Raspberry Pi 4 boards. Everything is working fine, Jenkins is running on it and the backend part (Java Microservice, Maven) can be built, deployed and run on it.

Now I am trying to create a Pipeline for the Android App part, which I build in React Native, Gradle. I'm just learning how everything fits together and am stuck with building the apk file on Jenkins. Locally building it (on Linux) is working fine but I'm not able to create a Docker container for the aarch64 architecture with the necessary Android SDK stuff installed to build it with Jenkins. Here is what I have by now (tell me, if I have to provide more information!):

Dockerfile:

FROM openjdk:8-alpine3.9

ENV ANDROID_SDK_ROOT /opt/android-sdk-linux

RUN apk add --no-cache curl wget bash unzip \
    && apk add --no-cache --update nodejs npm \
    && npm install -g react-native-cli

RUN cd /opt \
    && wget -q https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip -O android-commandline-tools.zip \
    && mkdir -p ${ANDROID_SDK_ROOT}/cmdline-tools \
    && unzip -q android-commandline-tools.zip -d ${ANDROID_SDK_ROOT}/cmdline-tools \
    && rm android-commandline-tools.zip

ENV PATH ${PATH}:${ANDROID_SDK_ROOT}/platform-tools:${ANDROID_SDK_ROOT}/cmdline-tools/tools/bin

RUN yes | sdkmanager --licenses

RUN touch /root/.android/repositories.cfg

# This part fails!
# RUN yes | sdkmanager "emulator" "platform-tools"

RUN yes | sdkmanager --update --channel=3
RUN yes | sdkmanager \
    "platforms;android-29" \
    "build-tools;29.0.3" \
    "build-tools;29.0.2" \
    "build-tools;29.0.1" \
    "build-tools;29.0.0"

Jenkinsfile:

pipeline {
    agent {
        kubernetes {
            defaultContainer 'app-build'
            yamlFile 'kubernetes-pod.yaml'
        }
    }
    stages {
        stage ('print env vars') {
            steps {
                sh 'printenv'
                sh 'echo "JAVA-VERSION: "'
                sh 'java -version'
                sh 'echo "NODE-VERSION:"'
                sh 'node --version'
                sh 'echo "NPM version:" '
                sh 'npm --version'
                sh 'echo "REACT-NATIVE-VERSION:"'
                sh 'react-native --version'
            }
        }
       stage ('Gradle Build') {
           steps {
               sh ('react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res')
               dir ('android') {
                   // this step fails (error message below)
                   gradlew('assembleRelease', '--scan')
               }
           }
       }

       /* ... more steps ... */
    }
}

def gradlew(String... args) {
    sh "./gradlew ${args.join(' ')} -s"
}

The error message I get on Jenkins is the following:

Starting a Gradle Daemon (subsequent builds will be faster)

> Configure project :react-native-reanimated
Warning: Dependant package with key emulator not found!

FAILURE: Build failed with an exception.

* Where:
Build file '/home/jenkins/agent/workspace/nches_CHEF-8-frontend-deployment/node_modules/react-native-reanimated/android/build.gradle' line: 89

* What went wrong:
A problem occurred configuring project ':react-native-reanimated'.
> Failed to install the following SDK components:
      build-tools;29.0.2 Android SDK Build-Tools 29.0.2
  Install the missing components using the SDK manager in Android Studio.

kubernetes-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  labels:
    label: jenkins-agent
    job: build-services
  namespace: build-services
spec:
  containers:
    - name: jnlp
      image: franzbuholzer/jenkins-jnlp-arm64:4.6
      tty: true
    - name: maven
      image: maven:3.6.3-jdk-11
      tty: true
      command: ["cat"]
      volumeMounts:
        - name: repository
          mountPath: /root/.m2/repository
    - name: docker
      image: docker:19.03.13
      command: ["cat"]
      tty: true
      volumeMounts:
        - name: docker-sock
          mountPath: /var/run/docker.sock
  volumes:
    - name: repository
      persistentVolumeClaim:
        claimName: repository
    - name: docker-sock
      hostPath:
        path: /var/run/docker.sock

I would be very happy if someone could help me solving this problem, that so I can attack the next obstacles, which I guess would be copying the generated apk into another Docker image and deploy it on the cluster to make it downloadable...

Upvotes: 5

Views: 3587

Answers (1)

Holmes Conan
Holmes Conan

Reputation: 1241

Although the question is inactive for month, I should record my effort for the later. Since sdkmanager using progress bar like output, some messages are override which cause the key problem is hard to find: there is a key dependent emulator is failed to install. I think it is because there is no matched version of qemu. But actually we do not need the emulator during compile time. So my simple solution is:

  1. Install the Android command line tool on a x86 based linux
  2. Install platform-tools, build-tools
  3. tarball the emulator directory in $ANDROID_SDK_ROOT
  4. Install Android command line tool on Raspberry Pi
  5. Install platform-tools which create basic directory structure
  6. Extract emulator from the tarball into $ANDROID_SDK_ROOT
  7. GOOD LUCK

It seems some tools cannot run under 32-bit system, so one cannot use their favorite Raspberry Pi OS which is 32-bit only. Use Ubuntu 64-bit instead.

Unfortunately after another hours research, the solution cannot work besides one can install build-tools. You cannot compile Android application on AArch64(or arm64) just because all toolchain download from official repository are built for x86. If one want to build Android application on AArch64 CPU such as Raspberry PI, they need to build the whole toolchain on that arch.

Upvotes: 3

Related Questions