Skip to content

feat(build): add Docker-based Android build environment - #13

Merged
BGLuis merged 2 commits into
BGLuis:developfrom
vladislav-smirnov:docker_for_build_make_host_os_clean
Sep 25, 2026
Merged

BGLuis merged 2 commits into
BGLuis:developfrom
vladislav-smirnov:docker_for_build_make_host_os_clean

Conversation

@vladislav-smirnov

@vladislav-smirnov vladislav-smirnov commented Sep 24, 2026 •

Copy link
Copy Markdown

Description

Added docker to build apk to make host OS clean

Type of change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 🛠️ Technical refactor / Code improvement
  • 📝 Documentation update
  • 🚀 Performance optimization
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)

Affected layers

  • 🟣 Kotlin (app/) — app shell, UI panels, credentials, history, i18n
  • 🔵 C++ (native/) — OpenXR session, Vulkan/GLES render loop, controller input
  • 🦀 Rust (rust/) — demux, decode, audio, network protocols
  • 🔧 Build / CI / scripts
  • 📚 Docs only

How has this been tested?

  • Unit tests (JVM / cargo test)
  • Native/Vulkan build compiled without errors
  • Physically tested on a device (Quest 2 / Quest 3 / Quest 3s)

Checklist:

  • My code follows the project's style guidelines (ktlint, rustfmt, clippy -D warnings).
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added new tests that prove my fix is effective or that my feature works.
  • The CI/CD Actions (build-and-lint) are passing for this PR.

If applicable

  • Kotlin never calls Rust directly — the Kotlin → JNI → C++ → C ABI → Rust path is preserved (ADR-002).
  • I changed the screen/stereo mode enum and kept it in sync across all three places: SCREEN_MODE in rust/bridge/src/lib.rs, enum class ScreenMode in native/include/screen_mode.h, and the catalog in ScreenFormatCatalog.kt.
  • I added or changed user-facing strings and updated both values/strings.xml and values-pt-rBR/strings.xml, keeping the key order mirrored and using positional placeholders (%1$s).
  • Pure logic I added lives in media-logic (host-testable) rather than in core, where it could not be tested.
  • No credential is stored or logged in plain text.

Screenshots / Videos (if applicable)

Add Dockerfile, build entrypoint, convenience script, and documentation for building the APK without installing Android tooling on the host.
@vladislav-smirnov
vladislav-smirnov changed the base branch from main to develop September 24, 2026 09:21
@vladislav-smirnov

Copy link
Copy Markdown
Author

@BGLuis Could you please review it. I believe it's nice to have

- Roda como não-root com o UID/GID do host (--user), --cap-drop ALL e
  no-new-privileges; remove o chown (que só rodava em caso de sucesso) e
  os arquivos de root deixados no projeto após falha de build.
- Remove o symlink ffmpeg-android-maker dentro do projeto e o rm -rf do
  entrypoint; scripts/build.sh passa a aceitar FFMPEG_MAKER_DIR.
- Entrypoint só valida o ambiente (git worktree, Meta SDK, FFmpeg) e
  delega para scripts/build.sh; o cp dos .so não esconde mais falhas.
- Dockerfile multi-stage (sdk, ffmpeg, rust, final) com base por digest e
  Rust, cargo-ndk, rustup-init e commandlinetools fixados (SHA-256);
  imagem de ~6,4 GB. Adiciona .dockerignore e cache mounts do apt.
- Move docker-build.sh para scripts/, repassa APP_VERSION_*, suporta
  DOCKER=podman e adiciona `make docker-build`.
- Atualiza o README do Docker e o CLAUDE.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@BGLuis

BGLuis commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Hi @vladislav-smirnov, thank you very much for the contribution! A containerized build is a really nice addition, and it lowers the barrier for new contributors, since nothing has to be installed on the host.

I reviewed it, built the image and generated the APK inside the container to check it end to end. It worked, so I made a few changes on top of your code, all pushed to your branch (commit 98b91b3). Here's what I changed and why:

Security / robustness

  • The container now runs as a non-root user with the host UID/GID (--user), plus --cap-drop ALL and no-new-privileges. This removes the chown step, which only ran on success: after a failed build, root-owned files were left in rust/target, Cargo.lock and the project root.
  • Removed the ffmpeg-android-maker symlink created inside the project (and the rm -rf of that folder in the entrypoint). scripts/build.sh now accepts FFMPEG_MAKER_DIR, so the prebuilt FFmpeg stays in /opt inside the image.
  • The entrypoint fails early with a clear message when /project is a git worktree or the Meta SDK is missing. The cp of the FFmpeg .so files no longer hides failures (|| true).

Dockerfile

  • Multi-stage (sdk, ffmpeg, rust, final): the first three build in parallel and the final image drops nasm/yasm/curl/wget, the maker's .git and the FFmpeg sources. The image went from the estimated 12–15 GB to about 6.4 GB.
  • Reproducibility: Ubuntu pinned by digest, and pinned Rust, cargo-ndk, rustup-init and commandlinetools (the last two verified with SHA-256, so no more curl | sh). The FFmpeg commit is the same one used by scripts/setup-deps.sh.
  • Added a whitelist .dockerignore and apt cache mounts.

Scripts / docs

  • The entrypoint now just validates the environment and delegates to scripts/build.sh, so there is a single source of truth for the pipeline (local, CI and container).
  • Moved docker-build.sh to scripts/ (matching the repo convention). It always runs docker build (cached), forwards APP_VERSION_NAME/APP_VERSION_CODE, and supports DOCKER=podman. Added make docker-build, and updated the Docker README and CLAUDE.md.

What I tested: the full flow through scripts/docker-build.sh produced app-debug.apk (BUILD SUCCESSFUL, 11 arm64 libs, no files owned by root). I did not test installing/running the APK on a headset, --rebuild/--shell, or rootless Podman.

A small suggestion for the PR description, when you have a moment: since this PR only touches the build tooling and not the app code, it might be worth updating the checklist to reflect what you ran (for example, the container build), so reviewers know exactly what was verified. Totally optional!

Thanks again! Feel free to look at the changes and tell me if anything looks off.

@BGLuis
BGLuis merged commit 149a2e2 into BGLuis:develop Sep 25, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants