Bygga ett Android-projekt i en Docker-behållare

När du utvecklar ett projekt för Android-plattformen, även det minsta, måste du förr eller senare ta itu med utvecklingsmiljön. Förutom Android SDK är det nödvändigt att ha den senaste versionen av Kotlin, Gradle, plattformsverktyg, byggverktyg. Och om alla dessa beroenden på utvecklarens maskin löses i större utsträckning med Android Studio IDE, kan varje uppdatering på CI/CD-servern bli en huvudvärk. Och om i webbutveckling Docker har blivit standardlösningen på miljöproblemet, varför inte försöka lösa ett liknande problem i Android-utveckling med det...

För den som inte vet vad Docker är, för att uttrycka det enkelt, är det ett verktyg för att skapa den sk. "behållare" som innehåller en minimal OS-kärna och den nödvändiga uppsättning mjukvara som vi kan distribuera var vi vill, samtidigt som miljön bevaras. Exakt vad som kommer att finnas i vår behållare bestäms i Dockerfilen, som sedan sätts ihop till en bild som kan lanseras var som helst och har idempotensegenskaper.

Installationsprocessen och grunderna för Docker beskrivs perfekt i hans officiella hemsida. Därför, när vi tittar lite framåt, är det här Dockerfilen vi slutade med:

# Т.к. основным инструментом для сборки Android-проектов является Gradle, 
# и по счастливому стечению обстоятельств есть официальный Docker-образ 
# мы решили за основу взять именно его с нужной нам версией Gradle
FROM gradle:5.4.1-jdk8

# Задаем переменные с локальной папкой для Android SDK и 
# версиями платформы и инструментария
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" 
    ANDROID_HOME="/usr/local/android-sdk" 
    ANDROID_VERSION=28 
    ANDROID_BUILD_TOOLS_VERSION=28.0.3

# Создаем папку, скачиваем туда SDK и распаковываем архив,
# который после сборки удаляем
RUN mkdir "$ANDROID_HOME" .android 
    && cd "$ANDROID_HOME" 
    && curl -o sdk.zip $SDK_URL 
    && unzip sdk.zip 
    && rm sdk.zip 
# В следующих строчках мы создаем папку и текстовые файлы 
# с лицензиями. На оф. сайте Android написано что мы 
# можем копировать эти файлы с машин где вручную эти 
# лицензии подтвердили и что автоматически 
# их сгенерировать нельзя
    && mkdir "$ANDROID_HOME/licenses" || true 
    && echo "24333f8a63b6825ea9c5514f83c2829b004d1" > "$ANDROID_HOME/licenses/android-sdk-license" 
    && echo "84831b9409646a918e30573bab4c9c91346d8" > "$ANDROID_HOME/licenses/android-sdk-preview-license"    

# Запускаем обновление SDK и установку build-tools, platform-tools
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"

Vi sparar den i mappen med vårt Android-projekt och börjar bygga behållaren med kommandot

docker build -t android-build:5.4-28-27 .

Parameter -t anger taggen eller namnet på vår behållare, som vanligtvis består av dess namn och version. I vårt fall kallade vi det android-build och i versionen angav vi en uppsättning versioner av gradle, android-sdk och plattformsverktyg. I framtiden kommer det att bli lättare för oss att söka efter bilden vi behöver med namn med hjälp av denna "version".

Efter att monteringen är klar kan vi använda vår bild lokalt, vi kan ladda ner den med kommandot hamnarbetare till ett offentligt eller privat bildarkiv för att ladda ner det till andra maskiner.

Som ett exempel, låt oss bygga ett projekt lokalt. För att göra detta, kör kommandot i mappen med projektet

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebug

Låt oss ta reda på vad det betyder:

docker körning - själva kommandot för bildstart
-rm — betyder att efter att behållaren har stannat, tar den bort allt som skapades under dess livstid
-v "$PWD":/home/gradle/ — monterar den aktuella mappen med vårt Android-projekt i den interna containermappen /home/gradle/
-w /home/gradle — anger behållarens arbetskatalog
android-build:5.4.1-28-27 — namnet på vår container som vi samlade in
gradle assembleDebug — själva monteringsteamet som monterar vårt projekt

Om allt går bra, kommer du inom ett par sekunder/minuter att se något liknande på din skärm BYGGA FRAMGÅNGSRIKTIGT på 8m 3s! Och mappen app/build/output/apk kommer att innehålla den sammansatta applikationen.

Du kan utföra andra graderade uppgifter på liknande sätt - kontrollera projektet, köra tester osv. Den största fördelen är att om vi behöver bygga projektet på någon annan maskin behöver vi inte oroa oss för att installera hela miljön och det kommer att räcka för att ladda ner den nödvändiga bilden och köra byggnaden i den.

Behållaren lagrar inga ändringar, och varje assembly startas från grunden, vilket å ena sidan garanterar assemblyens identitet oavsett var den lanseras, å andra sidan varje gång du ska ladda ner alla beroenden och kompilera all kod igen, och det kan ibland ta lång tid. Därför har vi, förutom den vanliga "kallstarten", möjligheten att starta bygget samtidigt som vi sparar den sk. "cache", där vi sparar ~/.gradle-mappen genom att helt enkelt kopiera den till projektets arbetsmapp, och i början av nästa build returnerar vi den tillbaka. Vi flyttade alla kopieringsprocedurer till separata skript och själva startkommandot började se ut så här

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 /bin/bash -c "./pre.sh; gradle assembleDebug; ./post.sh"

Som ett resultat av detta minskade vår genomsnittliga projektbyggtid flera gånger (beroende på antalet beroenden på projektet, men det genomsnittliga projektet började alltså monteras på 1 minut istället för 5 minuter).

Allt detta är naturligtvis bara vettigt om du har din egen interna CI/CD-server, som du själv stödjer. Men nu finns det många molntjänster där alla dessa problem är lösta och du behöver inte oroa dig för det, och de nödvändiga monteringsegenskaperna kan också specificeras i projektinställningarna.

Endast registrerade användare kan delta i undersökningen. Logga in, Snälla du.

Håller du ditt CI/CD-system internt eller använder du en tredjepartstjänst?

  • Vi använder en intern server

  • Vi använder en extern tjänst

  • Vi använder inte CI/CD

  • Andra

42 användare röstade. 16 användare avstod från att rösta.

Källa: will.com

Lägg en kommentar