redroid 13 Control Kit
This folder contains the local control entrypoint for the remote redroid 13 environment. The goal is to keep one script and one workflow that can:
- build the image on the server
- launch one or many redroid instances
- bootstrap Magisk and Google framework settings
- check whether a running instance is actually usable
- expose a web UI for Docker management
Architecture
The repository is split into two layers:
flowchart LR
A["Local workstation<br/>Windows / Git Bash"] --> B["redroid13.sh<br/>Paramiko over SSH"]
B --> C["Remote host<br/>/home/eric/redroid-android13"]
C --> D["Docker / Podman"]
D --> E["redroid container"]
E --> F["Android 13 system image"]
F --> G["Google framework"]
F --> H["Magisk / root"]
B --> I["Portainer web panel"]
Local side
redroid13.sh is the only file you usually run from this folder. It:
- asks for the SSH password once
- connects to the server with
paramiko - executes build, launch, bootstrap, and health-check commands remotely
- resolves the best image for the server architecture
Remote side
The server repo, /home/eric/redroid-android13, contains the actual Android build and bootstrap code:
redroid.pybuilds the image layersrun_redroid.pylaunches the containerbootstrap_redroid.pyapplies the post-boot hardeningstuff/magisk.pypackages Magiskstuff/mindthegapps.pypackages Google apps/framework
Compatibility Model
The script is designed to work with both x86_64 and arm64 hosts.
Image selection
The script resolves the image automatically unless you override it.
- x86_64 host:
redroid/redroid:13.0.0_mindthegapps_houdini_magisk - arm64 host:
redroid/redroid:13.0.0_mindthegapps_magisk
You can still override the image explicitly with REDROID_IMAGE.
If your arm64 build uses a different tag, set REDROID_IMAGE_ARM64 to match it.
Runtime bridge
run_redroid.py already resolves bridge mode from the image tag when --bridge auto is used.
houdiniimages use native bridge translation for x86 apps on x86 hosts- arm64 images can stay on the default bridge path
Root handling
bootstrap_redroid.py now probes root using both of the common Magisk styles:
su root idsu 0 id
That avoids the old su -mm -c mismatch and keeps Magisk-compatible bootstrapping stable across the current image variants.
What The Script Does
The shell entrypoint supports:
- building the Android 13 image
- starting one instance
- starting multiple instances
- bootstrapping a single container
- bootstrapping all running redroid containers
- listing containers
- checking a running instance
- starting Portainer
- showing runtime info
It also resolves:
- the server architecture
- the appropriate image tag
- the right ADB / Magisk bootstrap path
Prerequisites
Local machine:
- Bash
- Python 3
paramikoinstalled for Python 3
Remote server:
- Docker or Podman
- access to
/home/eric/redroid-android13 - working ADB server
- a redroid-compatible Linux host
Quick Start
Run the script from this folder:
./redroid13.sh
The menu is interactive and covers the common workflow:
- build the image
- start one instance
- start a batch of instances
- bootstrap an instance
- list containers
- check a running instance
- start Portainer
- stop an instance
- bootstrap all redroid containers
- show runtime info
- exit
Non-Interactive Usage
The same script also supports command-style usage:
./redroid13.sh build
./redroid13.sh start
./redroid13.sh batch
./redroid13.sh bootstrap redroid13-1
./redroid13.sh bootstrap-all
./redroid13.sh list
./redroid13.sh redroid-list
./redroid13.sh check
./redroid13.sh portainer
./redroid13.sh info
./redroid13.sh stop redroid13-1
Recommended Defaults
These defaults are tuned for a stable Android 13 desktop-style setup:
REDROID_GPU_MODE=guestREDROID_ADB_INSECURE=1REDROID_DEVICE_PROFILE=pixel-7-proREDROID_ROOT_TIMEOUT=60REDROID_BOOT_TIMEOUT=120REDROID_WAIT_TCP=120
That combination prioritizes boot reliability over host-GPU speed.
Environment Variables
You can override the behavior without editing the script.
| Variable | Purpose | Default |
|---|---|---|
REDROID_SSH_HOST |
Remote server address | 192.168.2.179 |
REDROID_SSH_USER |
SSH user | eric |
REDROID_REMOTE_REPO |
Remote repo path | /home/eric/redroid-android13 |
REDROID_IMAGE |
Force a specific image | auto-select by architecture |
REDROID_IMAGE_X86 |
x86_64 image | redroid/redroid:13.0.0_mindthegapps_houdini_magisk |
REDROID_IMAGE_ARM64 |
arm64 image | redroid/redroid:13.0.0_mindthegapps_magisk |
REDROID_ARCH_PROFILE |
auto, x86_64, or arm64 |
auto |
REDROID_DEVICE_PROFILE |
Device fingerprint preset | pixel-7-pro |
REDROID_GPU_MODE |
guest, host, or auto |
guest |
REDROID_ADB_INSECURE |
Inject insecure adb boot props | 1 |
REDROID_BOOT_TIMEOUT |
Seconds to wait for Android boot | 120 |
REDROID_ROOT_TIMEOUT |
Seconds to wait for Magisk root | 60 |
REDROID_WAIT_TCP |
Seconds to wait for ADB TCP | 120 |
REDROID_DEFAULT_PORT |
First ADB port | 5570 |
REDROID_PORT_STEP |
Port step in batch mode | 1 |
REDROID_INSTANCE_PREFIX |
Instance name prefix | redroid13 |
REDROID_DEFAULT_COUNT |
Batch size prompt default | 3 |
REDROID_PORTAINER_PORT |
Portainer port | 9000 |
REDROID_DATA_PREFIX |
Host data directory prefix | /home/eric/data-redroid13 |
Multi-Instance Layout
The script uses one host data directory per instance:
/home/eric/data-redroid13-redroid13-1
/home/eric/data-redroid13-redroid13-2
/home/eric/data-redroid13-redroid13-3
Ports are assigned sequentially:
557055715572
This keeps each container isolated and makes it easy to reboot or replace a single instance.
Bootstrap Flow
The bootstrap phase does the important post-boot cleanup:
- waits for Android boot completion
- waits for Magisk root when root-only actions are required
- sets provisioning flags
- disables setup wizard if the package exists
- sets mock location for shell
- applies the selected device profile through
resetprop - applies proxy settings
- installs the optional extreme script when requested
That bootstrap logic is the part that keeps Google Play and Magisk behavior stable after first boot.
Portainer
The script can start Portainer on the remote host.
Once it is running:
- open
http://<server-ip>:9000 - use it to inspect containers, logs, volumes, and restart policies
Troubleshooting
ADB connects but shell fails
Check whether the instance actually reached a usable boot state:
./redroid13.sh check
If sys.boot_completed is not 1, the container may still be booting or the guest may have stalled.
Magisk root is unavailable
The bootstrap logic now retries root with the currently supported su syntax.
If you still do not see root:
- check the container logs on the remote host
- verify the image tag you selected
- make sure the container was started from the current repository revision
Google Play login looks broken
That usually means one of these is still wrong:
- device fingerprint
- setup wizard state
- provisioning state
- Google Play Services package state
Use ./redroid13.sh check to inspect all of those in one shot.
Host GPU causes boot issues
If a container never becomes reachable over ADB, switch back to guest GPU mode:
REDROID_GPU_MODE=guest ./redroid13.sh start
Host GPU is faster when it works, but guest GPU is the safe default for headless servers.
Notes
- This folder is a control layer, not the Android build itself.
- The actual server-side fixes live in the remote repository at
/home/eric/redroid-android13. - The goal is stability first: Magisk root, Google framework, and repeatable multi-instance startup.