Running Docker using QEMU on an Android Device

In a previous exercise. We installed Linux on an Android device. We then installed some popular software used by developers and accessed them remotely. But that environment had limitations. Such as not being able to use Docker.

In this exercise, we'll install Redis on an Android device. But we'll do it using Docker and Portainer. We'll achieve this with the help of QEMU to emulate an x86-64 machine running Alpine Linux.

The basic steps involve:
  • Installing Termux
  • Installing QEMU
  • Installing Alpine Linux
  • Installing Portainer
  • Installing Redis
  • Testing Remote Access

Right from the outset, it should be noted that this setup takes quite a hit in performance. At least in comparison to the previous exercise. But it's all for fun. So let's get started.

Installing Termux

What is Termux? Taken directly from the project's homepage. "Termux is an Android terminal emulator and Linux environment app that works directly with no rooting or setup required."

You install Termux directly from the Google Play Store. This version of Termux will not be receiving further updates due to increasing Android restrictions. But for our purpose, it should be fine.

If you find the steps in this article are not working for you. You can try installing the latest version of Termux from F-Droid(Free and Open Source Android App Repository).

Once you have Termux installed. Open the app to access its terminal.

Update and upgrade existing packages.
pkg update && pkg upgrade

Installing SSH Server - Optional

This next step is optional. But it will make things easier. Install an SSH server and log in remotely from a computer.
pkg install openssh
To log in using SSH. We'll need a user, password, and the internal IP address of your Android device. For this article, it is u0_a260, motootspassword, and 192.168.0.68. Get the user.
whoami
Set the password.
passwd
Get the IP address.
ifconfig
If you're having trouble identifying your IP address. You can always go into the Android Wi-Fi settings. It will be available under the network you are currently connected to.

Start the SSH server.
sshd
Open a terminal from your computer and log into Termux on the Android device.
ssh u0_a260@192.168.0.68 -p 8022

Installing QEMU

Install QEMU.
pkg install qemu-system-x86-64-headless qemu-utils
If you're curious as to why we're using x86-64. After doing some light testing against an ARM aarch64 variant. It performed noticeably better. It might be a fun project to see how it performs for you.

Installing Alpine Linux

To keep things light, we'll download and install Alpine Linux. We'll use Wget for downloading.
pkg install wget
wget https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/x86_64/alpine-virt-3.13.2-x86_64.iso    
Create a disk image and boot up our VM for installation.
qemu-img create -f qcow2 alpine.qcow2 7G
This will create a 7GB image in qcow2 format. This will bring advantages such as compression. You can try something like raw if you want to maximize performance.
qemu-system-x86_64 -smp 2 -m 2048 \
-drive file=alpine.qcow2,if=virtio \
-netdev user,id=n1,hostfwd=tcp::6379-:6379,hostfwd=tcp::9000-:9000 \
-device virtio-net,netdev=n1 \
-cdrom alpine-virt-3.13.2-x86_64.iso -boot d \
-nographic
Here we're setting the number of cores to 2. And memory to 2GB.

Then we have some disk and network configuration. Since we'll be installing Portainer and Redis, we need to map some ports. The mapping isn't needed in this step. But it's included here to keep the boot commands consistent.

Finally, we specify 'boot d' to boot from the CDROM drive containing the image we downloaded.

After a while, you'll be greeted with a login prompt. Log in with root and start the setup process.
setup-alpine
Choose your keyboard layout and variant. For this exercise, we'll use us for both.

To keep things simple. Hit return to accept the defaults for everything until asked about SSH. At which point, enter none.

Next, you'll be asked to select a disk and how to use it. There should only be one disk available. Select vda for the disk and sys for how to use it.

Finally, enter y to erase the disk and continue. Once completed, use the poweroff command to exit.

Once again boot up Alpine Linux and log in. But this time omit the CDROM drive.
qemu-system-x86_64 -smp 2 -m 2048 \
-drive file=alpine.img,if=virtio \
-netdev user,id=n1,hostfwd=tcp::6379-:6379,hostfwd=tcp::9000-:9000 \
-device virtio-net,netdev=n1 \
-nographic
Alpine Linux is ready to use.

Installing Docker

To install Docker, we need to make the community repository available. Use Nano to edit the list of repositories.
apk add nano
nano /etc/apk/repositories
Find and uncomment the community repository.

Install Docker. And start the Docker service.
apk add docker
service docker start
Docker is now ready to use.

Installing Portainer

Install Portainer.
docker run -d -p 9000:9000 --name=my-portainer -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
Once Portainer is up and running. Access the UI by opening a browser to http://your-ip:9000.

Create the administrator and log in.


Connect to the Local Docker environment.


Once connected. Select the local endpoint. Then select the Container option. We'll install Redis from here.

Installing Redis

From Portainers Container page. Select Add container.

Name it my-redis. We'll use the Alpine image to make the installation faster. Enter redis:alpine in the Image section.

Make port 6379 available by adding an entry to the Manual network port publishing section. Enter 6379 for both host and container.




Finally, click on the Deploy the container button. After a while, you should see a success message.

Redis is ready to use.

Testing Remote Access

To test remote access. You'll need the Android device's IP address and port number for Redis.

If you didn't skip the optional portion of this article. You already have the IP address needed. Otherwise, go to that section to obtain your device's IP address.

Use your favorite tool to test remote connections from your computer. Or use this companion Spring Boot application. Instruction can be found in the README file.

That's all for this exercise. A video version is available on YouTube.

Comments

  1. Thank you for this tutorial. Very usefull! But please change the command:

    qemu-system-x86_64 -smp 2 -m 2048 \
    -drive file=alpine.img,if=virtio \
    -netdev user,id=n1,hostfwd=tcp::6379-:6379,hostfwd=tcp::9000-:9000 \
    -device virtio-net,netdev=n1 \
    -nographic

    to:

    qemu-system-x86_64 -smp 2 -m 2048 \
    -drive file=alpine.qcow2,if=virtio \
    -netdev user,id=n1,hostfwd=tcp::6379-:6379,hostfwd=tcp::9000-:9000 \
    -device virtio-net,netdev=n1 \
    -nographic

    (you use -drive file=alpine.qcow2. it doesnt work with -drive file=alpine.img)

    Also the newest version of alpine (3.17.0) works noticibly slower, atleast in my experience

    ReplyDelete
  2. Hi!
    After "setup-alpine"
    ...
    How would you like to use it? ('sys', 'data', 'lvm' or '?' for help) [?] sys
    ERROR: unable to select packages:
    sfdisk (no such package):
    required by: world[sfdisk]
    syslinux (no such package):
    required by: world[syslinux]

    ReplyDelete
    Replies
    1. I had the same problem. Solution is describe here https://stackoverflow.com/a/76242338/22000453. It's DNS problem.

      Delete
  3. When I wget alpine iso file, I get 404 not Found and cannot process further. D/L address is resolved and connected, I have tried to use mirror address but still fail. Can you help?

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Use this command if can't pull docker image: ip link set dev eth0 mtu 1400

    ReplyDelete

Post a Comment

Popular posts from this blog

MySQL, MongoDB, RabbitMQ, and Redis on an Android Device