Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
ANDROID_VERSION=30
GAPPS_VERSION=11
DNS=one.one.one.one
RAM_SIZE=4096
SCREEN_RESOLUTION=1080x1920
SCREEN_DENSITY=320
ROOT_SETUP=0
GAPPS_SETUP=0
4 changes: 3 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
FROM ubuntu:20.04
ARG ANDROID_VERSION=30
ENV ANDROID_VERSION=${ANDROID_VERSION}

# Install necessary packages
RUN apt-get update && \
Expand Down Expand Up @@ -44,7 +46,7 @@ RUN mkdir /root/.android/ && \


# Detect architecture and set environment variable
RUN yes | sdkmanager --sdk_root=$ANDROID_HOME "emulator" "platform-tools" "platforms;android-30" "system-images;android-30;default;x86_64"
RUN yes | sdkmanager --sdk_root=$ANDROID_HOME "emulator" "platform-tools" "platforms;android-${ANDROID_VERSION}" "system-images;android-${ANDROID_VERSION};default;x86_64"
# remove /opt/android-sdk/emulator/crashpad_handler
RUN rm -f /opt/android-sdk/emulator/crashpad_handler
# RUN if [ "$(uname -m)" = "aarch64" ]; then \
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,16 @@ scrcpy -s localhost:5555
| `SCREEN_DENSITY` | Screen pixel density in DPI | device default |
| `ROOT_SETUP` | Set to `1` to enable rooting and Magisk. Can be turned on after the first start but cannot be undone without recreating the data volume. | `0` |
| `GAPPS_SETUP` | Set to `1` to install PICO GAPPS. Can be turned on after the first start but cannot be undone without recreating the data volume. | `0` |
| `ANDROID_VERSION` | Android API version to emulate (30 = Android 11, 31 = Android 12, 33 = Android 13, 34 = Android 14, 35 = Android 15, 36 = Android 16). Also enables multi-version support. | `30` |
| `GAPPS_VERSION` | GAPPS version to download. Default behavior derives from ANDROID_VERSION. | `11` |
| `DATA_PARTITION_SIZE` | Data partition size for internal storage (e.g., `4G`, `8G`, `16G`). Default is 4G. | `4G` |


## 🔄 **First Boot Process**

The first time you start the container, it will perform a comprehensive setup process that includes:

1. **AVD Creation:** Creates a new Android Virtual Device running Android 30 (Android 11)
1. **AVD Creation:** Creates a new Android Virtual Device using the Android version configured via ANDROID_VERSION (default 30 – Android 11). This value selects the platform image (e.g., android-${ANDROID_VERSION}) for the AVD and SDK downloads.
2. **PICO GAPPS Installation** (when `GAPPS_SETUP=1`): Adds essential Google services.
3. **Rooting the Device** (when `ROOT_SETUP=1`): Performs multiple reboots to:
- Disable AVB verification
Expand Down
6 changes: 5 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,23 @@ services:
image: shmayro/dockerify-android:latest
build:
context: .
env_file:
- .env
ports:
- "5555:5555"
volumes:
- ./data:/data
- ./extras:/extras
environment:
ANDROID_VERSION: 30
DNS: one.one.one.one
# RAM_SIZE: 4096
# Optional screen resolution in WIDTHxHEIGHT format
#SCREEN_RESOLUTION: 720x720
# Optional screen density (dpi)
#SCREEN_DENSITY: 227
# Data partition size (e.g., 4G, 8G, 16G)
#DATA_PARTITION_SIZE: 4G
ROOT_SETUP: 0 # set to 1 to enable rooting
GAPPS_SETUP: 0 # set to 1 to install PICO GAPPS
privileged: true
Expand All @@ -38,4 +43,3 @@ services:
adb connect dockerify-android:5555 &&
npm start
"

64 changes: 49 additions & 15 deletions first-boot.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash

# Android version and GAPPS version handling (defaults kept backward compatible)
ANDROID_VERSION=${ANDROID_VERSION:-30}
GAPPS_VERSION=${GAPPS_VERSION:-11}

bool_true() {
case "${1,,}" in
1|true|yes) return 0 ;;
Expand Down Expand Up @@ -44,30 +48,60 @@ prepare_system() {
install_gapps() {
prepare_system
echo "Installing GAPPS ..."
wget https://sourceforge.net/projects/opengapps/files/x86_64/20220503/open_gapps-x86_64-11.0-pico-20220503.zip/download -O gapps-11.zip
unzip gapps-11.zip 'Core/*' -d gapps-11 && rm gapps-11.zip
rm gapps-11/Core/setup*
lzip -d gapps-11/Core/*.lz
for f in gapps-11/Core/*.tar; do
tar -x --strip-components 2 -f "$f" -C gapps-11
# Determine GAPPS date and API tag based on Android version.
case "$ANDROID_VERSION" in
30)
GAPPS_DATE_FROM_VER="20220503"; GAPPS_API_TAG="11.0"; GAPPS_DIR="gapps-11" ;;
31)
GAPPS_DATE_FROM_VER="20230105"; GAPPS_API_TAG="12.0"; GAPPS_DIR="gapps-12" ;;
33)
GAPPS_DATE_FROM_VER="20220824"; GAPPS_API_TAG="13.0"; GAPPS_DIR="gapps-13" ;;
34)
GAPPS_DATE_FROM_VER="20230601"; GAPPS_API_TAG="14.0"; GAPPS_DIR="gapps-14" ;;
35)
GAPPS_DATE_FROM_VER="20240415"; GAPPS_API_TAG="15.0"; GAPPS_DIR="gapps-15" ;;
36)
GAPPS_DATE_FROM_VER="20250105"; GAPPS_API_TAG="16.0"; GAPPS_DIR="gapps-16" ;;
*)
GAPPS_DATE_FROM_VER="20220503"; GAPPS_API_TAG="11.0"; GAPPS_DIR="gapps-11" ;;
esac

# Allow override via GAPPS_VERSION, but keep defaults aligned with ANDROID_VERSION.
if [[ "$GAPPS_VERSION" =~ ^[0-9]+$ ]]; then
if [ "$GAPPS_VERSION" -ge 12 ]; then
GAPPS_API_TAG="12.0"; GAPPS_DATE_FROM_VER="20230105"; GAPPS_DIR="gapps-12"
fi
fi

OPEN_GAPPS_ARCHIVE="open_gapps-x86_64-${GAPPS_API_TAG}-pico-${GAPPS_DATE_FROM_VER}.zip"
GAPPS_URL="https://sourceforge.net/projects/opengapps/files/x86_64/${GAPPS_DATE_FROM_VER}/${OPEN_GAPPS_ARCHIVE}/download"
ZIP_FILE="gapps-${GAPPS_API_TAG%%.*}.zip"

wget "$GAPPS_URL" -O "$ZIP_FILE"
unzip "$ZIP_FILE" 'Core/*' -d "$GAPPS_DIR" && rm "$ZIP_FILE"
rm -f "$GAPPS_DIR/Core/setup*" || true
lzip -d "$GAPPS_DIR/Core/*.lz" || true
for f in "$GAPPS_DIR/Core/*.tar"; do
tar -x --strip-components 2 -f "$f" -C "$GAPPS_DIR"
done
adb push gapps-11/etc /system
adb push gapps-11/framework /system
adb push gapps-11/app /system
adb push gapps-11/priv-app /system
rm -r gapps-11
adb push "$GAPPS_DIR/etc" /system
adb push "$GAPPS_DIR/framework" /system
adb push "$GAPPS_DIR/app" /system
adb push "$GAPPS_DIR/priv-app" /system
rm -r "$GAPPS_DIR" || true
touch /data/.gapps-done
}

install_root() {
adb wait-for-device
echo "Root Script Starting..."
# Root the AVD by patching the ramdisk.
# Root the AVD by patching the ramdisk for the configured Android version.
git clone https://gitlab.com/newbit/rootAVD.git
pushd rootAVD
sed -i 's/read -t 10 choice/choice=1/' rootAVD.sh
./rootAVD.sh system-images/android-30/default/x86_64/ramdisk.img
cp /opt/android-sdk/system-images/android-30/default/x86_64/ramdisk.img /data/android.avd/ramdisk.img
# Use the dynamic Android version for ramdisk patching
./rootAVD.sh system-images/android-${ANDROID_VERSION}/default/x86_64/ramdisk.img
cp /opt/android-sdk/system-images/android-${ANDROID_VERSION}/default/x86_64/ramdisk.img /data/android.avd/ramdisk.img
popd
echo "Root Done"
sleep 10
Expand Down Expand Up @@ -102,7 +136,7 @@ if [ -f /data/.first-boot-done ]; then
fi

echo "Init AVD ..."
echo "no" | avdmanager create avd -n android -k "system-images;android-30;default;x86_64"
echo "no" | avdmanager create avd -n android -k "system-images;android-${ANDROID_VERSION};default;x86_64"

[ "$gapps_needed" = true ] && install_gapps && [ "$root_needed" = false ] && adb reboot
[ "$root_needed" = true ] && install_root
Expand Down
3 changes: 3 additions & 0 deletions start-emulator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ if [ -f "$CONFIG_FILE" ]; then
if [ -n "$SCREEN_DENSITY" ]; then
update_config "hw.lcd.density" "$SCREEN_DENSITY"
fi
if [ -n "$DATA_PARTITION_SIZE" ]; then
update_config "hw.dataPartition.size" "$DATA_PARTITION_SIZE"
fi
fi

# Start the emulator with the appropriate ramdisk.img
Expand Down