メインコンテンツへスキップ

ReDroidチュートリアル:DockerでAndroidシステムを動かし、x86 PCでARMスマホゲームを遊ぶ

·
カテゴリー Linuxシステム Self-Hosting
タグ ReDroid Android Docker Linux Scrcpy
目次

ReDroid (Remote anDroid) は自前で「クラウドスマホ」を構築する方案で、DockerでAndroidシステムコンテナを動かし、さらにScrcpyの画面ミラーリング機能でAndroidデスクトップへ接続します。

LinuxでReDroidを使ってFGOをプレイ

ReDroidもPC上でオープンソースソフトウェアを使ってAndroidアプリを動かすソリューションです。クラウドスマホはさておき、多くのAndroidスマホゲームエミュレーターはクローズドソースソフトウェアですからね。それに比べ、ReDroidはARMトランスレーター以外はオープンソースです。さらに素晴らしいことに、ReDroidはGPUアクセラレーション+ARMからx86へのトランスレーターに対応しているため、大多数のスマホ3Dゲームを遊べます。

Linuxユーザーにとって、これはWaydroidとAndroid-x86仮想マシン以外に、Linux PCでAndroidアプリを高効率に動かす方法でもあります。さらにWaydroidよりクラウドスマホ用途に向いています。Self-hosting Cloud Phoneを参照してください

この記事では、x86アーキテクチャのLinux PCでReDroidを使い、ARMアーキテクチャのスマホゲームを遊ぶ方法を扱います。最良の使用体験を得るため、ReDroidイメージにARMトランスレーター+Googleサービスフレームワークを追加します。

1. ReDroidシステム要件
#

任意のLinuxディストリビューションで使えるはずです。

この記事ではx86アーキテクチャのPCでReDroidを動かす例を示します。ARMアーキテクチャのPCについては、Oracle ARMアーキテクチャサーバーでのデプロイ成功例を報告したネットユーザーがおり、私もRaspberry Pi 5でReDroidを動かせることをテスト済みです。

PCがx86アーキテクチャの場合、実行できるのはx86アーキテクチャのAndroidアプリだけです。しかし多くのスマホゲームはARMアーキテクチャ版しかないため、ReDroidにはlibndkまたはlibhoudiniのARMトランスレーターを入れる必要があります。

スマホゲームを遊ぶなら、PCには少なくとも8GB以上のRAMをおすすめします。ARMをx86命令へ変換するとき、大量のRAMを消費することがあるためです。

GPUアクセラレーションについては、IntelやAMDのGPUなど、Linux Mesaがサポートするドライバーの使用をおすすめします。3Dアクセラレーションがそのまま使えます。Nvidiaはおすすめしません。


Androidバージョンについて、Redroid作者が公開しているredroid:11.0.0-latestredroid:12.0.0-latestイメージにはGoogle開発のARMトランスレーターlibndkが内蔵されています。試したところAndroid 11だけが比較的安定しており、GAppsも使えたので、この記事ではAndroid 11のイメージを選びます。

2. ReDroid前提依存項目をインストール
#

ReDroidのGithubには主要Linuxディストリビューション向けのインストール説明があります。私はUbuntuシステムを例にします。

  1. まずbinderカーネルモジュールを用意します。Ubuntu 24.04では以下のコマンドを実行し、必要なbinderカーネルモジュールをインストールします:
sudo apt install linux-modules-extra-`uname -r`

sudo modprobe binder_linux devices="binder,hwbinder,vndbinder"
  1. 上記カーネルモジュールを起動時自動読み込みに追加します
echo 'binder_linux options binder_linux devices="binder,hwbinder,vndbinder"' | sudo tee -a /etc/modules-load.d/redroid.conf
  1. コンテナ実行用にDockerをインストールします

  2. ADBツールをインストールします

  3. 最後にScrcpyをインストールします。

キーマッピングを統合したグラフィカルなScrcpy UIが欲しい場合は、QtScrcpyを入れてもよいです。Web版のws-scrcpyも試せます。

3. ReDroidイメージに事前にGAppsをインストール
#

ReDroid作者が公開しているイメージは素のAndroidで、GAppsはプリインストールされていません。Docker Hubで他人が事前にビルドしたReDroidイメージを探すこともできます。GApps内蔵のものなら自分でbuildする必要はありません。もちろん、リスクは自己責任です。

ここではayasa520のRemote-Android Scriptを使い、ReDroidイメージを自動取得してGAppsを入れます。Android 11のイメージのみ対応です。

このスクリプトはlibndk、libhoudini、Magisk、Widevine DRMなどのコンポーネントのインストールにも使えます。

  1. Remote-Android Scriptリポジトリをクローンし、Python仮想環境を作成します
sudo apt install lzip python3 python3-venv python3-pip

git clone https://github.com/ayasa520/redroid-script.git

cd redroid-script

python3 -m venv venv

venv/bin/pip install -r requirements.txt
  1. Android 11のイメージを取得し、GAppsをインストールします
venv/bin/python3 redroid.py -a 11.0.0 -g
  1. これでGApps入りイメージredroid/redroid:11.0.0_gappsが得られます。

4. docker-composeでReDroidコンテナを起動
#

  1. この手順はNvidiaグラフィックカードの場合のみ必要です。IntelとAMDグラフィックカードのユーザーは次の手順へ直接進んでください。ReDroidのNvidiaグラフィックカード対応は良くありません。可能なら内蔵GPUで動かすことをおすすめします。どうしてもNvidiaを使うなら、ReDroid用の仮想マシンを作成します。NvidiaクローズドソースドライバーではReDroidにGPUアクセラレーションを使わせられないため、QEMU仮想マシンを動かし、その中にReDroidを入れてvirtio-gpuでハードウェアアクセラレーションを実現する必要があります。ただしこれは準仮想化技術なので性能損失は大きいです。仮想マシンを作らず、PCに内蔵GPUもない場合、ReDroidはソフトウェアレンダリングになります。ソフトウェアレンダリングの性能を受け入れられるなら、仮想マシンをインストールする必要はありません。
ReDroid用仮想マシンを作成

QEMU + Virt Managerをインストールし、Ubuntu 24.04をダウンロードして、64GBのUbuntu仮想マシンを作成します

qemu-img create -f qcow2 ubuntu.qcow2 64GB

qemu-system-x86_64 -boot d -cdrom "ubuntu-22.04.1-desktop-amd64.iso" -enable-kvm -smp 4 -device intel-hda -device hda-duplex  -device virtio-vga-gl  -net nic -net user,hostfwd=tcp::5555-:5555 -cpu host  -m 4096  -display sdl,gl=on -hda ubuntu.qcow2

仮想マシンへ起動し、その後Dockerをインストールします。

qemu-system-x86_64 -enable-kvm -smp 4 -device intel-hda -device hda-duplex  -device virtio-vga-gl  -net nic -net user,hostfwd=tcp::5555-:5555 -cpu host  -m 4096  -display sdl,gl=on -hda ubuntu.qcow2
  1. Androidデータ保存用ディレクトリを作成し、docker-composeを追加します
mkdir ~/redroid

cd redroid

vim docker-compose.yml
  1. 以下の内容を入力します:
services:
  redroid:
    image: redroid/redroid:11.0.0_gapps # 先ほど作成したGApps入りReDroidイメージを使用
    stdin_open: true
    tty: true
    privileged: true
    ports:
      - 127.0.0.1:5555:5555 # ADBポート。セキュリティ強化のためローカルlocalhostポートのみリッスン
    volumes:
      - ./redroid-11-data:/data # データは現在ディレクトリに保存
    command:
      - androidboot.redroid_width=720 # スマホ解像度
      - androidboot.redroid_height=1280
      - androidboot.redroid_dpi=320
      - androidboot.redroid_fps=60
      - androidboot.redroid_gpu_mode=host # ホストGPUハードウェアアクセラレーションを有効化。hostはGPUアクセラレーション、guestはソフトウェアレンダリング
      - ro.product.cpu.abilist0=x86_64,arm64-v8a,x86,armeabi-v7a,armeabi # libndk関連設定
      - ro.product.cpu.abilist64=x86_64,arm64-v8a
      - ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi
      - ro.dalvik.vm.isa.arm=x86
      - ro.dalvik.vm.isa.arm64=x86_64
      - ro.enable.native.bridge.exec=1
      - ro.dalvik.vm.native.bridge=libndk_translation.so
      - ro.ndk_translation.version=0.2.2
  1. サービスを起動
sudo docker compose up -d
  1. ADBでローカルのReDroidへ接続します。ローカルなのでIPはlocalhostです。ReDroidをリモートにデプロイしている場合は、リモートホストのIPに変更します。
adb connect localhost:5555

# 接続できない場合、以下のコマンドでコンテナ内部で何が起きているか確認します
sudo docker ps
sudo docker exec <容器ID> logcat
sudo docker logs <容器ID>
  1. Scrcpyを実行し、Androidへ接続します:
scrcpy -s localhost:5555 --audio-codec=aac
  1. これでAndroidデスクトップが見えます。

  2. Google Playサービスが「デバイスは認証されていません」というエラーメッセージを出すことがあります。

  3. 以下のコマンドでAndroidデバイスIDを取得し、Googleサイトでデバイスを登録します。30分ほど待ってからRedroidコンテナを再起動すると、Google Playにログインできます。

adb -s localhost:5555 root

adb -s localhost:5555 shell 'sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \
    "select * from main where name = \"android_id\";"'
  1. ReDroidの3Dアクセラレーションが正常に動いているか確認するには、AIDA64をインストールし、PCのGPU型番を認識できるか見ます。

  2. セキュリティを強化したい場合は、ReDroidのdocker-composeネットワーク設定をローカルlocalhostポートのみリッスンするようにしてください(ports: 127.0.0.1:5000:5000)。ReDroidを外部ネットワークからアクセス可能にする場合は、ファイアウォール設定に注意し、ADBの5000ポートを直接インターネットへ公開しないでください。重大なセキュリティリスクになります。

5. ReDroidにAPKをインストールする方法
#

現在、libndkをインストールしていても、Android 11のPlayストアはARMアーキテクチャのアプリをダウンロードさせてくれません。APKPureのようなアプリストアと組み合わせてアプリをインストールしてください。

コンテナ内部のブラウザでAPKをダウンロードする以外に、ADBでAPKをReDroidコンテナへインストールすることもできます。たとえばApkMirrorからLineのAPKをダウンロードし、ADBでインストールします:

adb -s localhost:5555 install "jp.naver.line.android.apk"

ScrcpyはAPKをウィンドウへドラッグしてインストールできます。

ADBのpullpushコマンドでファイルを転送することもできます。

6. ReDroidを「起動・停止」する方法
#

ReDroidを停止したい場合、Scrcpyウィンドウを閉じた後、コンテナを停止します:

cd ~/redroid

sudo docker compose down

その後、このコマンドでReDroidを再び起動できます。ReDroidコンテナの/dataデータは~/redroid/redroid-11-dataディレクトリにあり、複数システムのファイルをバックアップするのに使えます。

cd ~/redroid

sudo docker compose up -d

adb connect localhost:5555

scrcpy -s localhost:5555 --audio-codec=aac

7. ReDroid多重起動の例
#

ReDroid Multiple Instancesを参照してください

付録
#

ReDroidイメージへGAppsを手動インストール

ReDroid作者によると、Googleサービスフレームワークはプロプライエタリソフトウェアなので内蔵できません。したがって自分でインストールする必要があります。1つ目の方法はReDroidイメージの再コンパイル、2つ目はOpenGAppsの手動インストールです。

1つ目の方法はおすすめしません。時間がかかるうえ、作者が提供するGAppsビルド手順には他のアプリが検出できない問題もあります。

ここでは2つ目の方法、手動インストールを使います。

  1. OpenGappsからx86_64アーキテクチャのAndroid 11 GAppsをダウンロードし、最小構成のpico版を選びます。

  2. 展開すると、以下のディレクトリが見えます

open_gapps-x86_64-11.0-pico-20220503
├── Core
├── GApps
├── META-INF
├── Optional
  1. 展開したディレクトリopen_gapps-x86_64-11.0-pico-20220503の下にsystemディレクトリを追加します。

  2. 次に、CoreGAppsディレクトリ内の.lzファイルをすべて展開し、中のAPKディレクトリを対応するインストール先に従ってsystemディレクトリへ置きます。たとえばGApps/googletts-x86_64/nodpi/app/下のGoogleTTSディレクトリは/system/appへ置きます。

  3. 配置後、system下のディレクトリ構造はこのようになるはずです:

system
├── app
│   ├── GoogleCalendarSyncAdapter
│   │   └── GoogleCalendarSyncAdapter.apk
│   ├── GoogleContactsSyncAdapter
│   │   └── GoogleContactsSyncAdapter.apk
│   ├── GoogleExtShared
│   │   └── GoogleExtShared.apk
│   └── GoogleTTS
│       └── GoogleTTS.apk
├── etc
│   ├── default-permissions
│   │   ├── default-permissions.xml
│   │   └── opengapps-permissions-q.xml
│   ├── permissions
│   │   ├── com.google.android.dialer.support.xml
│   │   ├── com.google.android.maps.xml
│   │   ├── com.google.android.media.effects.xml
│   │   ├── privapp-permissions-google.xml
│   │   └── split-permissions-google.xml
│   ├── preferred-apps
│   │   └── google.xml
│   └── sysconfig
│       ├── dialer_experience.xml
│       ├── google_build.xml
│       ├── google_exclusives_enable.xml
│       ├── google-hiddenapi-package-whitelist.xml
│       └── google.xml
├── framework
│   ├── com.google.android.dialer.support.jar
│   ├── com.google.android.maps.jar
│   └── com.google.android.media.effects.jar
├── priv-app
│   ├── AndroidAutoPrebuiltStub
│   │   └── AndroidAutoPrebuiltStub.apk
│   ├── AndroidMigratePrebuilt
│   │   └── AndroidMigratePrebuilt.apk
│   ├── CarrierSetup
│   │   └── CarrierSetup.apk
│   ├── ConfigUpdater
│   │   └── ConfigUpdater.apk
│   ├── GoogleBackupTransport
│   │   └── GoogleBackupTransport.apk
│   ├── GoogleExtServices
│   │   └── GoogleExtServices.apk
│   ├── GoogleFeedback
│   │   └── GoogleFeedback.apk
│   ├── GoogleOneTimeInitializer
│   │   └── GoogleOneTimeInitializer.apk
│   ├── GooglePackageInstaller
│   │   └── GooglePackageInstaller.apk
│   ├── GooglePartnerSetup
│   │   └── GooglePartnerSetup.apk
│   ├── GoogleRestore
│   │   └── GoogleRestore.apk
│   ├── GoogleServicesFramework
│   │   └── GoogleServicesFramework.apk
│   ├── Phonesky
│   │   └── Phonesky.apk
│   ├── PrebuiltGmsCore
│   │   └── PrebuiltGmsCore.apk
│   └── SetupWizard
│       └── SetupWizard.apk
└── product
    └── overlay
        └── PlayStoreOverlay.apk
  1. 以下のコマンドでroot権限を取得します:
adb connect localhost:5555
adb -s localhost:5555 root
adb -s localhost:5555 remount
adb -s localhost:5555 shell "rm -rf system/priv-app/PackageInstaller"
  1. 次にsystemディレクトリをReDroidシステムへpushし、権限を付与します:
adb -s localhost:5555 push system /
adb -s localhost:5555 shell "pm grant com.google.android.gms android.permission.ACCESS_COARSE_LOCATION"
adb -s localhost:5555 shell "pm grant com.google.android.gms android.permission.ACCESS_FINE_LOCATION"
adb -s localhost:5555 shell "pm grant com.google.android.setupwizard android.permission.READ_PHONE_STATE"
adb -s localhost:5555 shell "pm grant com.google.android.setupwizard android.permission.READ_CONTACTS"
adb reboot
  1. ReDroidコンテナを再起動します:
cd ~/redroid
sudo docker compose down
sudo docker compose up -d
  1. Scrcpyを起動
scrcpy -s localhost:5555 --audio-codec=raw
  1. システム設定 → アプリを開き、右上からシステムアプリ表示を選択し、Google PlayサービスとPlayストアの権限をすべて有効にします。
libndkを手動抽出してAndroidイメージをビルド

libndkはGoogleが開発したプロプライエタリソフトウェアで、Android Studioのエミュレーターに含まれています。ReDroid作者の指示によると、新しいAndroidエミュレーターからlibndkを手動で抽出し、ReDroidの素のシステムへ入れることができます。

ここではAndroid 13を例にします。作者は必ず使えるとは保証していない点に注意してください。

  1. Android Studioをインストールし、Android 13の仮想マシンを追加します

  2. ADBで接続

adb devices
adb shell
su
  1. libndkをパッケージ化
{ find /system -name arm* -type d; find /system -name *ndk_translation*; find /system/etc -name *arm*; } | tar -cf /sdcard/nb.tar -T -
  1. libndk.soをパッケージ化
find system -type l | tar -cf /sdcard/so.tar -T -
  1. ADBを終了し、上記ファイルをローカルへ転送します
exit
exit
adb pull /sdcard/nb.tar .
adb pull /sdcard/so.tar .
  1. libndk.soをlibndkの圧縮ファイルへ追加します
tar -xvf so.tar
find system -type l | tar -rf libndk_translation.tar -T -
  1. DOCKERFILEを追加し、以下の内容を入力します:
FROM redroid/redroid:13.0.0-latest

ADD libndk_translation.tar /
  1. libndk入りAndroid 13イメージのビルドを開始します。その後、このイメージredroid:13.0.0-libndkをコンテナ実行に使えるようになります。
docker build . -t redroid:13.0.0-libndk

參考資料
#

関連記事


最後までお読みいただきありがとうございます。本サイトでは公開コメント欄を設けていません。私はソーシャルな反応やアクセス数を追い求めるためではなく、自分の考えを誠実に探求するために文章を書いています。記事を丁寧にお読みいただいたうえで、ご感想やご意見をお寄せいただければ幸いです。誤字・誤り・技術的な問題などを見つけた場合、またはフィードバックを共有したい場合は、Aboutページに記載しているメールアドレスまでお気軽にご連絡ください。