git.iko.soy/parseable-android
on master help sign in
parseable-android/Dockerfile
72 lines 3.3 kB history raw
1# syntax=docker/dockerfile:1
3# ---- Build stage -------------------------------------------------------------
4# Builds the Parseable Android APK from source. Mirrors the GitHub Actions CI:
5# JDK 17, Android SDK (compileSdk 35), Gradle 8.9, with the wrapper generated
6# on the fly (gradle-wrapper.jar is gitignored). The app's build.gradle.kts
7# derives its version from `git log`, so git + the .git directory are required.
8#
9# Pinned to linux/amd64: the Android toolchain (aapt2) ships only x86-64 Linux
10# binaries. On an arm64 host (Apple Silicon) a native arm64 image can't exec
11# them ("rosetta error: failed to open elf .../ld-linux-x86-64.so.2"); a full
12# amd64 image gives Rosetta/QEMU a complete x86-64 userland to emulate. On an
13# amd64 host this is native. Override with --build-arg BUILD_PLATFORM=... .
14ARG BUILD_PLATFORM=linux/amd64
15FROM --platform=${BUILD_PLATFORM} eclipse-temurin:17-jdk-jammy AS build
17# Versions (override at build time with --build-arg if needed)
18ARG GRADLE_VERSION=8.9
19ARG ANDROID_CMDLINE_TOOLS_VERSION=11076708
20ARG ANDROID_PLATFORM=35
21ARG ANDROID_BUILD_TOOLS=35.0.0
22# Gradle task to run: assembleDebug (default) or assembleRelease
23ARG GRADLE_TASK=assembleDebug
25ENV ANDROID_SDK_ROOT=/opt/android-sdk \
26 ANDROID_HOME=/opt/android-sdk \
27 GRADLE_USER_HOME=/root/.gradle \
28 DEBIAN_FRONTEND=noninteractive
30# Base tooling: git (version stamp), unzip/curl (fetching SDK + Gradle)
31RUN apt-get update && \
32 apt-get install -y --no-install-recommends git unzip curl ca-certificates && \
33 rm -rf /var/lib/apt/lists/*
35# Android SDK command-line tools
36RUN mkdir -p "${ANDROID_SDK_ROOT}/cmdline-tools" && \
37 curl -fsSL "https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_CMDLINE_TOOLS_VERSION}_latest.zip" -o /tmp/cmdline-tools.zip && \
38 unzip -q /tmp/cmdline-tools.zip -d "${ANDROID_SDK_ROOT}/cmdline-tools" && \
39 mv "${ANDROID_SDK_ROOT}/cmdline-tools/cmdline-tools" "${ANDROID_SDK_ROOT}/cmdline-tools/latest" && \
40 rm /tmp/cmdline-tools.zip
42ENV PATH="${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin:${ANDROID_SDK_ROOT}/platform-tools:${PATH}"
44# Accept licenses and install required SDK packages
45RUN yes | sdkmanager --licenses >/dev/null && \
46 sdkmanager --install \
47 "platform-tools" \
48 "platforms;android-${ANDROID_PLATFORM}" \
49 "build-tools;${ANDROID_BUILD_TOOLS}" >/dev/null
51# Gradle (used to generate the wrapper, then the wrapper drives the build)
52RUN curl -fsSL "https://services.gradle.org/distributions/gradle-${GRADLE_VERSION}-bin.zip" -o /tmp/gradle.zip && \
53 unzip -q /tmp/gradle.zip -d /opt && \
54 rm /tmp/gradle.zip
55ENV PATH="/opt/gradle-${GRADLE_VERSION}/bin:${PATH}"
57WORKDIR /workspace
59# Copy the full project (including .git for the version stamp; see .dockerignore)
60COPY . .
62# Generate the Gradle wrapper, then build the APK
63RUN gradle wrapper --gradle-version "${GRADLE_VERSION}" && \
64 ./gradlew --no-daemon "${GRADLE_TASK}"
66# ---- Export stage ------------------------------------------------------------
67# Minimal final image holding just the built APK(s) under /apks.
68# Extract them to ./out with:
69# docker build --target export --output type=local,dest=./out .
70# (A scratch image has no shell, so use --output, not docker create/cp.)
71FROM scratch AS export
72COPY --from=build /workspace/app/build/outputs/apk/ /apks/