CI build image for Android apps with a Rust core
  • Dockerfile 73.6%
  • Shell 26.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-24 17:04:16 +02:00
.gitignore feat: android and rust build image 2026-10-24 16:37:58 +02:00
build.sh fix: link the tools into /usr/local/bin, runners replace PATH 2026-10-24 17:04:16 +02:00
Dockerfile fix: link the tools into /usr/local/bin, runners replace PATH 2026-10-24 17:04:16 +02:00
LICENSE feat: android and rust build image 2026-10-24 16:37:58 +02:00
README.md fix: link the tools into /usr/local/bin, runners replace PATH 2026-10-24 17:04:16 +02:00
versions.env fix: link the tools into /usr/local/bin, runners replace PATH 2026-10-24 17:04:16 +02:00

android-rust-builder

A CI build image for Android apps with a Rust core, such as UniFFI or cargo-ndk projects. It holds:

What Version (see versions.env)
Node and git, a C toolchain, perl, python3 from node:22-bookworm, so JavaScript CI actions such as checkout run
JDK (Temurin) 25
Android SDK platform, build tools, NDK API 37, 36.0.0, 27.2.12479018
Rust the current stable at build time, with clippy, rustfmt and the Android targets
cargo-ndk 4.1.2

Linux x86_64 only: Google ships the NDK for no other host.

Use

jobs:
  build:
    runs-on: linux-amd64-medium
    container:
      image: registry.git.petal.cafe/mug/android-rust:jdk25-api37-ndk27.2.12479018-r2

The tag says what the image holds: jdk<major>-api<level>-ndk<version>-r<revision>. latest is the newest build. The commands (cargo, java, sdkmanager, cargo-ndk) are linked into /usr/local/bin, because CI runners replace PATH. The image sets JAVA_HOME, ANDROID_HOME, ANDROID_NDK_HOME, RUSTUP_HOME and CARGO_HOME, and records JDK_MAJOR, ANDROID_API, NDK_VERSION, BUILD_TOOLS and CARGO_NDK_VERSION, so a project can check that it matches what its build wants. It holds no secret: keys come from the CI job's secrets.

A project that lists other Rust targets in rust-toolchain.toml (iOS ones, say) installs them itself.

Build

./build.sh                      # podman build, tagged from versions.env
REGISTRY_TOKEN=... ./build.sh push

Change a version in versions.env, build, and push: the tag changes with it, and old tags stay available. REGISTRY and REGISTRY_USER default to registry.git.petal.cafe and mug. Use that host, not git.petal.cafe: the latter is behind Cloudflare, which rejects a request body over 100 MB, and an image layer is larger.

Licence

MIT for the Dockerfile and scripts. The image bundles software under its own terms: the Android SDK and NDK (Android SDK licence, accepted at build time), Temurin, Rust, Node and Debian packages.