Esta página se ve mejor con JavaScript habilitado

Alpine Android

🐋 Imagen de Docker ligera para compilar y testear aplicaciones de Android

 ·   ·  ☕ 13 minutos de lectura

Descripción

Alpine Android es una ligera imagen de Docker para compilar y testear aplicaciones Android. Basada en la imagen de Alpine, hace que el tamaño se reduzca comparado con imágenes basadas en Debian o Ubuntu. Además, hay imágenes distintas por cada SDK y sólo se incluyen los paquetes mínimos.

Están disponibles las versiones del SDK desde Android 21 hasta Android 30. Cada versión del SDK tiene su propia imagen, siendo el identificador alvrme/alpine-android:android-<version>. Si siempre quieres hacer referencia a la última versión estable de Android que se encuentre disponible, se puede usar también alvrme/alpine-android:latest. Hay que tener en cuenta de que cuando se publique la versión 31 del SDK, si quieres seguir usando la 30, es mejor usar la etiqueta identificativa de la versión.

Hay que tener en cuenta de que cuando se publique la versión 31 del SDK, si quieres seguir usando la 30, es mejor usar la etiqueta identificativa de la versión.

Alpine Android Base

Hay dos versiones disponibles para extender desde. La imagen basada en AdoptOpenJDK8 Alpine con sufijo -jdk8 y la imagen basada en AdoptOpenJDK11 Alpine con sufijo -jdk11. La versión con Java 11 es obligatoria si se usa una versión de Android Gradle Plugin igual o superior a 7.0.0. Ambas versiones contiene las herramientas básicas y necesarias para compilar y testear cualquier aplicación o biblioteca Android cuyo compileSdkVersion se encuentre entre la versión 21 (Android 5 / Lollipop) y la versión 30 (Android 11).

Esto facilita la actualización de las imágenes que extienden de ella, ya que sólo habría que modificar el Dockerfile necesario.

Usar como imagen base

Para extender de la imagen base y poder configurar tu propia imagen con los paquetes y aplicaciones que desees, sólo hay que añadir la siguiente línea al principio de Dockerfile:

1
FROM alvrme/alpine-android-base

Instalar aplicaciones y paquetes

Se puede instalar cualquier aplicación de Alpine de la siguiente lista añadiendo el siguiente comando al Dockerfile:

1
2
RUN apk add --no-cache <paquete1> <paquete2> <...> && \
    rm -rf /tmp/* /var/tmp/*

De igual forma, puedes instalar cualquier paquete disponible de Android:

1
RUN sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --install <paquete1> <paquete2> <...>

Variantes

Hay dos variantes de la imagen:

  • Las imágenes JDK8 están basadas en adoptopenjdk/openjdk8:alpine (JDK 8u292-b10) y usa el sufijo -jdk8.
  • Las imágenes JDK11 están basadas en adoptopenjdk/openjdk11:alpine (JDK 11.0.11+9) y usa el sufijo -jdk11.

¿Cuál debería usar?

La versión recomendada es JDK8 si no se utiliza AGP v7.0.0+ o si se utiliza DataBinding con una versión de AGP anterior a la v7.0.0. En caso contrario se debe utilizar la versión JDK11 porque AGP v7.0.0+ sólo funcionará con la versión 11+ del JDK.

Si desea utilizar una imagen JDK11 con una versión de AGP anterior a la v7, recuerde que JAXB no está incluido y debe añadir las siguientes dependencias si utiliza DataBinding:

1
implementation "org.glassfish.jaxb:jaxb-runtime:2.3.3"
1
implementation("org.glassfish.jaxb:jaxb-runtime:2.3.3")

Etiquetado

APIJDK8JDK11
Imagen basejdk8, latest, latest-jdk8jdk11, latest-jdk11
Android 5.0 (21)android-21, android-21-jdk8android-21-jdk11
Android 5.1 (22)android-22, android-22-jdk8android-22-jdk11
Android 6.0 (23)android-23, android-23-jdk8android-23-jdk11
Android 7.0 (24)android-24, android-24-jdk8android-24-jdk11
Android 7.1 (25)android-25, android-25-jdk8android-25-jdk11
Android 8.0 (26)android-26, android-26-jdk8android-26-jdk11
Android 8.1 (27)android-27, android-27-jdk8android-27-jdk11
Android 9.0 (28)android-28, android-28-jdk8android-28-jdk11
Android 10 (29)android-29, android-29-jdk8android-29-jdk11
Android 11 (30)android-30, android-30-jdk8, latest, latest-jdk8android-30-jdk11, latest-jdk11
Android 12 (31)android-S, android-S-jdk8android-S-jdk11

📝 Las etiquetas latest y android-XX usarán la imagen base del JDK8 durante un año después de que se publique AGP 7.0.0 para evitar problemas con las configuraciones actuales de CI/CD. Esa fecha está aún por determinar. Después de esa fecha, si desea seguir utilizando JDK8, debe actualizar su configuración con la etiqueta correspondiente.

⚠️ Android 12 está en estado beta. Las versiones preliminares se etiquetan de forma diferente utilizando la letra de la versión en lugar del nivel de la API. Android 12 utilizará la etiqueta latest un mes y medio después del lanzamiento estable (TBD).

Versionado

Desde el 1 de enero de 2021, las nuevas versiones incluyen ahora la fecha de publicación, por lo que es posible volver a una versión anterior. El versionado sólo se aplica a las etiquetas con la versión JDK especificada. El formato de la etiqueta es: android-XX-jdkZZ-vYYYY.MM.DD, donde:

  • XX es la API del SDK.
  • ZZ es la versión del JDK.
  • YYYY es el año de la publicación de la versión.
  • MM es el mes del año de la versión de lanzamiento con ceros a la izquierda.
  • DD es el día del mes de la versión de lanzamiento con ceros a la izquierda.

Un ejemplo sería android-30-jdk11-v2021.01.01. Aquí están listadas todas las versiones.

📝 El versionado no está disponible para alpine-android-base.

Herramientas incluidas

A continuación se lista todas las herramientas incluídas con la instalación de los diferentes paquetes. Aquellos que tengan documentación propia están enlazados.

No está instalado el paquete gradle, por lo que no está disponible el comando en el PATH. El motivo de esto es que el paquete puede estar desactualizado y no ser compatible con alguna de las APIs utilizadas en la configuración. Es por eso que se debe de usar siempre el wrapper que viene en el proyecto y cuya versión está indicada en el fichero gradle-wrapper.properties. Puedes consultar aquí como configurar el wrapper para usarlo en los distintos servicios de CI/CD.

Línea de comandos

  • apkanalyzer: Proporciona estadísticas sobre la composición de tu APK una vez completado el proceso de compilación.
  • avdmanager: Te permite crear y administrar dispositivos virtuales de Android (AVD) desde la línea de comandos.
  • lint: Es una herramienta de escaneo de código que te ayuda a identificar y corregir problemas relacionados con la calidad estructural de tu código.
  • screenshot2: Haz una captura de pantalla del emulador que se esté ejecutando.
  • sdkmanager: Te permite ver, instalar, actualizar y desinstalar paquetes para el SDK de Android.

Compilación del SDK

  • aapt2: Analiza, indexa y compila recursos de Android en un formato binario que está optimizado para la plataforma Android, y empaqueta los recursos compilados en una sola salida.
  • apksigner: Firma los APK y comprueba si las firmas del APK se verificarán con éxito en todas las versiones de plataforma que admite un APK determinado.
  • zipalign: Optimiza los archivos APK garantizando que todos los datos sin comprimir comiencen con una alineación determinada en relación con el inicio del archivo.

Plataforma del SDK

  • adb: Android Debug Bridge (adb) es una herramienta versátil que te permite administrar el estado de una instancia de emulador o dispositivo con Android. También puedes usarla para instalar un APK en un dispositivo.
  • etc1tool: Una utilidad de línea de comandos que te permite codificar imágenes PNG al estándar de compresión ETC1 y decodificar imágenes comprimidas ETC1 de nuevo a PNG.
  • fastboot: Actualiza un dispositivo con imágenes de plataforma y del sistema.
  • logcat: Esta es una herramienta que se invoca mediante adb para ver los registros de la app y del sistema.

Otras herramientas

  • ia: Comprueba y ejecuta una aplicación instantánea.

Además de las anteriores herramientas específicas de Android, también se encuentran disponibles los comandos de BusyBox y los paquetes instalados en la imagen base:

  • git
  • unzip
  • wget

Extras

En la imagen base se incluye también el comando extras que contiene pequeñas utilidades que no están instaladas por defecto, ya que su uso no está generalizado.

Estos extras se ejecutan mediante el comando extras <comando> y son los siguientes:

Fastlane

fastlane es una herramienta para desarrolladores de iOS y Android para automatizar tareas tediosas como capturas de pantalla, crear perfiles de desarrollador y publicar aplicaciones. Visita su documentación para más información.

Este comando permite instalar fastlane. Hay dos variantes:

1
extras fastlane

Esta variante permite instalar la última versión de fastlane. Si quieres especificar una versión en concreto, el comando es el siguiente:

1
extras fastlane <version>

Contenido de cada imagen

PathVersionDescriptionLocation
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
PaqueteVersiónDescripciónUbicación
build-tools;21.1.221.1.2Android SDK Build-Toolsbuild-tools/21.1.2/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-212Android SDK Platform 21platforms/android-21/
PaqueteVersiónDescripciónUbicación
build-tools;22.0.122.0.1Android SDK Build-Toolsbuild-tools/22.0.1/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-222Android SDK Platform 22platforms/android-22/
PaqueteVersiónDescripciónUbicación
build-tools;23.0.323.0.3Android SDK Build-Toolsbuild-tools/23.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-233Android SDK Platform 23platforms/android-23/
PaqueteVersiónDescripciónUbicación
build-tools;24.0.324.0.3Android SDK Build-Toolsbuild-tools/24.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-242Android SDK Platform 24platforms/android-24/
PaqueteVersiónDescripciónUbicación
build-tools;25.0.325.0.3Android SDK Build-Toolsbuild-tools/25.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-253Android SDK Platform 25platforms/android-25/
PaqueteVersiónDescripciónUbicación
build-tools;26.0.326.0.3Android SDK Build-Toolsbuild-tools/26.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-262Android SDK Platform 26platforms/android-26/
PaqueteVersiónDescripciónUbicación
build-tools;27.0.327.0.3Android SDK Build-Toolsbuild-tools/27.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-273Android SDK Platform 27platforms/android-27/
PaqueteVersiónDescripciónUbicación
build-tools;28.0.328.0.3Android SDK Build-Toolsbuild-tools/28.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-286Android SDK Platform 28platforms/android-28/
PaqueteVersiónDescripciónUbicación
build-tools;29.0.329.0.3Android SDK Build-Toolsbuild-tools/29.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-295Android SDK Platform 29platforms/android-29/
PaqueteVersiónDescripciónUbicación
build-tools;30.0.330.0.3Android SDK Build-Toolsbuild-tools/30.0.3/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-303Android SDK Platform 30platforms/android-30/
PathVersionDescriptionLocation
build-tools;31.0.0-rc431.0.0-rc4Android SDK Build-Toolsbuild-tools/31.0.0-rc4/
extras;google;instantapps1.9.0Google Play Instant Development SDKextras/google/instantapps/
patcher;v41SDK Patch Applier v4patcher/v4/
platform-tools31.0.2Android SDK Platform-Toolsplatform-tools/
platforms;android-S4Android SDK Platform S (Preview)platforms/android-S/

Registro de contenedores

Por la limitación de DockerHub, la imagen ahora está disponible en tres registros de contenedores diferentes.

Como imagen base

Reemplaza <tag> con una de las etiquetas disponibles.

Imagen base de DockerHub

Puedes usar las imágenes de DockerHub como imagen base para crear una nueva:

1
FROM alvrme/alpine-android-base:<tag>
1
FROM alvrme/alpine-android:<tag>

Imagen base de GHCR

Puedes usar las imágenes de GitHub Container Registry como imagen base para crear una nueva:

1
FROM ghcr.io/alvr/alpine-android-base:<tag>
1
FROM ghcr.io/alvr/alpine-android:<tag>

Imagen base de Quay

Puedes usar las imágenes de Quay como imagen base para crear una nueva:

1
FROM quay.io/alvr/alpine-android-base:<tag>
1
FROM quay.io/alvr/alpine-android:<tag>

Descargar

Reemplaza <tag> con una de las etiquetas disponibles.

Descargar desde DockerHub

Puedes descargar una imagen específica desde DockerHub con el siguiente comando:

1
docker pull alvrme/alpine-android-base:<tag>
1
docker pull alvrme/alpine-android:<tag>

Descargar desde GHCR

Puedes descargar una imagen específica desde GitHub Container Registry con el siguiente comando:

1
docker pull ghcr.io/alvr/alpine-android-base:<tag>
1
docker pull ghcr.io/alvr/alpine-android:<tag>

Descargar desde Quay

Puedes descargar una imagen específica desde Quay con el siguiente comando:

1
docker pull quay.io/alvr/alpine-android-base:<tag>
1
docker pull quay.io/alvr/alpine-android:<tag>

Ejecutar contenedor

Reemplaza <tag> con una de las etiquetas disponibles.

El siguiente comando creará un nuevo contenedor basado en la imagen específica. Se abrirá en el directorio /home/android y se podrán ejecutar los diversos comandos disponibles en el PATH. Una vez cerrado el contenedor se eliminará. Para que se mantenga el contenedor después de cerrarlo, hay que quitar --rm del comando.

Ejecutar desde DockerHub

Ejecuta el contenedor desde DockerHub:

1
docker run --rm -it alvrme/alpine-android-base:<tag>
1
docker run --rm -it alvrme/alpine-android:<tag>

Ejecutar desde GHCR

Ejecuta el contenedor desde GitHub Container Registry:

1
docker run --rm -it ghcr.io/alvr/alpine-android-base:<tag>
1
docker run --rm -it ghcr.io/alvr/alpine-android:<tag>

Ejecutar desde Quay

Ejecuta el contenedor desde del Quay:

1
docker run --rm -it quay.io/alvr/alpine-android-base:<tag>
1
docker run --rm -it quay.io/alvr/alpine-android:<tag>

Usar en diferentes CI/CD

Aquí hay diferentes configuraciones para algunos de los distintos servicios de CI/CD disponibles. Antes de empezar, hay que recordar de que se debe de usar el wrapper de Gradle y éste necesita permisos de ejecución. Para dar permisos de ejecución a un ejecutable, hay que añadir chmod +x ./gradlew a la configuración de los pasos, o usar git update-index --chmod=+x ./gradlew en el repositorio y después hacer push del cambio. De esta forma, no será necesario aplicar permisos de ejecución cada vez.

CircleCI

Un ejemplo de configuración para CircleCI. Para más información, visita la documentación oficial.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
version: 2
jobs:
  build:
    docker:
      - image: alvrme/alpine-android:android-30
    environment:
      JVM_OPTS: -Xmx3200m
    steps:
      - checkout
      - restore_cache:
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run: # Se puede omitir si se ha usado `git update-index --chmod=+x ./gradlew` anteriormente.
         name: Añadir permisos de ejecución
         command: chmod +x ./gradlew
      - run:
          name: Descargar dependencias
          command: ./gradlew androidDependencies
      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run:
          name: Compilar
          command: ./gradlew build
      - run:
          name: Ejecutar tests
          command: ./gradlew lint test
      - run:
          name: Empaquetar
          command: |
            ./gradlew assembleRelease
            apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass pass:<keystore-pass> --key-pass pass:<alias-pass> app.apk # Contraseñas en plano
            apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass env:<keystore-pass> --key-pass env:<alias-pass> app.apk # Contraseñas en variables            

GitHub

Un ejemplo de configuración para GitHub Actions. Para más información, visita la documentación oficial.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
jobs:
  build:
    container:
      image: alvrme/alpine-android:android-30

    steps:
      - uses: actions/[email protected]
      - name: Añadir permisos de ejecución # Se puede omitir si se ha usado `git update-index --chmod=+x ./gradlew` anteriormente.
        run: chmod +x ./gradlew
      - uses: actions/[email protected]
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper            
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
          restore-keys: |
                        ${{ runner.os }}-gradle-
      - name: Descargar dependencias
        run: ./gradlew androidDependencies
      - name: Compilar
        run: ./gradlew build
      - name: Ejecutar tests
        run: ./gradlew lint test
      - name: Empaquetar
        run: |
          ./gradlew assembleRelease
          apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass pass:<keystore-pass> --key-pass pass:<alias-pass> app.apk # Contraseñas en plano
          apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass env:<keystore-pass> --key-pass env:<alias-pass> app.apk # Contraseñas en variables          

GitLab

Un ejemplo de configuración para GitLab CI/CD. Para más información, visita la documentación oficial.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
image: alvrme/alpine-android:android-30

before_script:
  - export GRADLE_USER_HOME=`pwd`/.gradle
  - chmod +x ./gradlew # Se puede omitir si se ha usado `git update-index --chmod=+x ./gradlew` anteriormente.

cache:
  key: "$CI_COMMIT_REF_NAME" # Opcional: compartir caché por ramas
  paths:
     - .gradle/wrapper
     - .gradle/caches

stages:
  - build
  - test
  - assemble

build:
  stage: build
  script:
    - ./gradlew build

tests:
  stage: test
  script:
    - ./gradlew lint test

assemble:
  stage: assemble
  script:
    - ./gradlew assembleRelease
    - apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass pass:<keystore-pass> --key-pass pass:<alias-pass> app.apk # Contraseñas en plano
    - apksigner sign --ks keystore.jks --ks-key-alias <alias> --ks-pass env:<keystore-pass> --key-pass env:<alias-pass> app.apk # Contraseñas en variables

Estadísticas

dockeri.co
dockeri.co

Enlaces

GitHub

Docker Alpine Android
Docker Alpine Android Base

Compartir en
Apoya al autor con