世界を動かす技術を、日本語で。

Android上でLinuxコンテナを実行、ルート権限不要

概要

Podroid は、 Android端末Linuxコンテナ を動作させるアプリ。 root不要 で、 Alpine Linux VM 上の Podman を利用可能。 QEMU仮想化シリアルターミナル を内蔵。 永続性ネットワークポートフォワーディング に対応。 Android 8.0+(arm64)端末 で利用可能。

Podroidの特徴

  • root権限不要 でLinuxコンテナ実行を実現
  • QEMU による軽量な Alpine Linux VM を起動
  • Podman によるOCIコンテナランタイム提供
  • シリアルターミナル 内蔵(xterm完全エミュレーション)
  • 永続化 機能:パッケージ、設定、コンテナイメージ保存
  • ネットワーク :インターネット接続とポートフォワーディング対応
  • 自己完結型 :root不要、Termux不要、ホストバイナリ不要
  • 対応要件 :arm64 Android 8.0+、150MB以上の空き容量

クイックスタート手順

  • APK をReleasesからインストール
  • Podroidを開き、「 Start Podman」をタップ
  • 20秒 でVMが起動(画面・通知で進捗表示)
  • Open Terminal」をタップしターミナル起動
  • コンテナ実行例
    • podman run --rm alpine echo hello
    • podman run --rm -it alpine sh
    • podman run -d -p 8080:80 nginx

ターミナル機能詳細

  • TermuxのTerminalView を利用した VT100/xtermエミュレーション
  • 追加キー バー(ESC、TAB、CTRL、ALT、F1–F12等)
  • CTRL/ALTトグル操作 対応
  • SYNC ボタンで端末サイズ手動同期
  • キーボード開閉時 に自動で端末サイズ同期
  • ベル文字 でバイブレーション通知
  • TUIアプリ (vim、btop、htop等)も正しく表示

ポートフォワーディング機能

  • VMからAndroid端末への ポート転送 設定
    • 設定画面でルール追加(例:TCP 8080→80)
    • 端末のlocalhost:8080でサービスへアクセス
  • ルールは 再起動後も保持、VM稼働中でも追加・削除可能

仕組み・アーキテクチャ

  • Androidアプリ
    • Foreground Service でVMを常駐
    • PodroidQemu (libqemu-system-aarch64.so使用、KVMなし)
      • シリアル標準入出力←→ターミナルエミュレータ
      • QMPソケット(ポート転送・VM制御)
  • Alpine Linux VM
    • 読み取り専用initramfs+永続ext4ディスク(overlayfs構成)
    • ttyAMA0上でgettyによるジョブ制御
    • Podman+crun+netavark+slirp4netns搭載

起動シーケンス

  • QEMUがvmlinuz-virt+initrd.imgをロード
  • 2段階init(init-podroid)が永続ext4ディスクをoverlayfs上にマウント
  • インストールパッケージやコンテナイメージはoverlayに保存され再起動後も維持

ターミナル連携

  • Androidアプリはホストプロセスのfork不可
  • TerminalSessionはQEMUのシリアルI/Oにリフレクションで直結
  • キーボード入力→QEMU stdin、QEMU stdout→ターミナル
  • sttyで端末サイズ同期、TUIアプリも正しく表示

ネットワーク

  • QEMUのユーザーモードネットワーク(SLIRP)によりVMは10.0.2.15を取得
  • ポートフォワードはQEMUのhostfwd機能をCLI引数・QMP経由で管理

ソースからのビルド方法

  • initramfsのビルド(multi-arch対応Docker必要)
    • ./docker-build-initramfs.sh
  • APKのビルド
    • ./gradlew assembleDebug
    • adb install -r app/build/outputs/apk/debug/app-debug.apk

プロジェクト構成

  • Dockerfile:initramfsビルダー(Alpine aarch64)
  • docker-build-initramfs.sh:ワンコマンドビルドスクリプト
  • init-podroid:VM用カスタムinit
  • app/src/main/
    • java/com/excp/podroid/
      • engine/:QEMUライフサイクル・QMPクライアント・VM状態管理
      • service/:フォアグラウンドサービス・起動通知
      • data/repository/:設定・ポート転送永続化
      • ui/screens/:ホーム・ターミナル・設定(Jetpack Compose)
    • jniLibs/arm64-v8a/:プリビルドQEMU+libslirp
    • assets/:カーネル+initramfs(自動生成)

クレジット

  • QEMU :マシンエミュレーション
  • Alpine Linux :VMベース
  • Podman :コンテナランタイム
  • Termux :ターミナルエミュレータライブラリ
  • Limbo PC Emulator :Android上QEMUの先駆者

ライセンス

  • GNU General Public License v2.0

Hackerたちの意見

これ、Podmanに組み込まれるかもね。Podmanはすでにpodman machineを使ってVMをサポートしてるし(OSによって中身は違う技術使ってるけど)。これ、また別のバックエンドになりそう。

それは素晴らしいね。

これの逆が動くようにするのは可能かな?(WaydroidをLinuxのスマホ、例えばpostmarketOSで使うとか)

なんで無理なんだろう?AndroidのIPC用のバインダーデバイスと、Waydroidを起動するためのrootアクセスがあればいいだけだよ。Waylandと一緒にインストールして使えば、問題なく動くはず。

Librem 5でPureOSを使ってWaydroidとmicroGを何年も使ってるよ。あんまり使ってないけど、Androidを起動する理由があればすぐに使える状態。WaydroidにPlay Servicesをインストールするためのガイドも見たけど、個人的には興味ないかな。

これが何に役立つのか、よくわからないな。AndroidのLinuxターミナルアプリ(欲しいなら開発者設定でチェックしてみて)もすでにあって、ハードウェアアクセラレーションの仮想化使ってるし、こっちはQEMUとTCG使ってる。LinuxターミナルアプリはDEも動かせるし(VNCなしでね!)、フルシェル、フルルート、Podroidの機能も全部揃ってる。ターミナルも好きなように入れ替えられるし。これの唯一の利点はAndroid 14、15、16をサポートしてることみたいだけど、何か見落としてる?それとも目的がないの?

あなたが言ってること、まさに私にとっての利点を的確に表現してるね:スマホのAndroidバージョンをサポートしてること。おそらく、Android 16を持ってないのは私だけじゃないと思う。

統合されたLinuxターミナルは、Snapdragonのような全てのプロセッサでサポートされているわけじゃないし、Samsungのような全てのメーカーでも利用できないってことを理解してる。だから、このアプローチはもっと多くの人に届くと思うよ。

古いスマホを使ってPiHoleを動かせるよ。

Samsungのスマホで試してみたけど、すぐクラッシュしちゃう。「リカバリー」すると全部消えちゃって、最初からやり直し。セッションは5分も持たなかったよ。

新しいアプリは本当に素晴らしい!デスクトップ環境を動かせたし、Minecraftのサーバーとクライアントもできた。ただ、USBパススルーができないのが残念。

え、こんなのあったんだ!ありがとう。でも761MBのダウンロードって、ターミナルにしてはめっちゃ大きいね。なんでこんなに大きいの?

これね。あと、Androidの仮想化をサポートしてない電話用には、Termuxの上流にあるユーザースペースのハックがあって、LD_PRELOADを使ってルートなしのchrootができるよ。詳細はここで確認してね: https://wiki.termux.com/wiki/PRoot。systemdはこれでは起動しないけど(PID 1が必要)、多くのソフトウェアは問題なく動くし、エミュレーションのオーバーヘッドはほぼゼロだよ。

AndroidのLinuxターミナルアプリ(欲しいなら開発者設定をチェックしてね)見当たらないんだけど、どうやってインストールするの?

AndroidのLinuxターミナルアプリに関するredditは不安定な報告でいっぱいだよ。私の理解では、全然役に立たない。これがあれば、開発用にスマホを使えるかもって期待してたけど、残念ながらハズレだった。せめてtermuxとprootがあるからいいけど。

Androidのターミナルアプリはすごく遅くて、Termuxと比べると起動に時間がかかるよ。それに、ターミナルアプリは基本的にウェブビューだし(私の理解では、アーキテクチャ的な理由だね)。

逆のことはどう?Waydroidのことは知ってるけど、NVIDIAとの相性が悪すぎるし、Waylandも必要だよね。

X86版のAndroidは、OSの世代がかなり遅れてる。X86でVM上でAndroidを動かすのは、基本的に死んでると思う。 :(

WindowsのVMを動かして、Windows Subsystem for Androidを使うことができるよ。

例えば、redroid(https://github.com/remote-android/redroid-doc)っていうのがあって、まさにそれみたい。コンテナ内のAndroidだね。

nvidiaのことは手伝えないけど、Waylandの問題はcageみたいなネストされたコンポジタの下で実行すれば簡単に回避できるよ。(これが、私がXorgの下でwaydroidを動かしてる方法だね)

TermuxとBTキーボードがあれば十分だね。それに、FDroidのネイティブEmacsも最近すごく改善されたし。Emacsだけでできることは: - IRC、Usenet、メールクライアント。唯一の自由なUsenetクライアントだよ。comp.archやcomp.miscでは本当に面白い議論があるし、いいコメントする人を見つけて、スパマーをブラックリストに入れられる。 - ELPA経由でGeminiとGopherも使える(Esc-x package-install RET elpherを実行) - 数学のミニCASもあって、Esc-x calc RETで使える - Esc-x package-install RET malyonで、IFDBで素敵なZMachineのテキストアドベンチャーが手に入る - Elisp環境+cl-libで色々できる - Esc-x package-install jabber、Esc-x jabberで、XMPPサーバーでクールな人たちとチャットできる - Org-Mode、言うまでもないね - eshellで自動化もできる - Elisp + Android関連機能 + org-mode: 最高だよ。 - 数独、ソコバン、テトリス… - LSP統合も可能だし。$10のポケットBluetoothキーボードを手に入れて試してみて。

Emacsを試してみたけど、gitみたいな依存パッケージをダウンロードするためにNixOSが必要だって気づいた。標準のEmacsは使えないんだ。EmacsとTermuxがパッケージを共有するトリックはあるけど、nix-on-droidには使えないよ :/

これいいと思う!Androidシステムで何かしらのDockerを使いたかったから、これでうまくいってる。apkに全部まとまってるし、今のエコシステムには確実に需要があると思う。新しいAndroidに組み込まれたターミナルは、起動しようとすると毎回クラッシュするんだよね。

限定された権限でコンテナを作るためにQEMUを使ってLinuxをエミュレートしてるのがちょっと面白いね。だって、すでにLinux上で制限された権限で動いてるのに。そういう設計になってるのは分かるけど、やっぱり面白い。

逆にどういうこと?Waydroidの状況はどうなってるの?

動くよ。

iOSでは絶対にできないことリストに追加したわ。

擁護するわけじゃないけど、WASMでLinuxをエミュレートするのは可能で、iOSでもそこそこパフォーマンス良く動くはずだよ。詳しくは https://webvm.io/ を見てみて。

QEMU TCGのアプローチは隔離には理にかなってるけど、トラフィックのルーティングについては気になるな。各コンテナは独自のネットワーク名前空間を持つの?それとも全てのトラフィックがAndroidのネットワークスタックを通るの?後者だと、キャリアレベルのDPIがコンテナが送信するものを全部見えることになるから、何を動かしてるかによっては重要だよね。