Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Install Docker on Termux
KEYMAPOPTS="us us"
HOSTNAMEOPTS="-n alpine"
INTERFACESOPTS="auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
hostname alpine
"
TIMEZONEOPTS="-z UTC"
PROXYOPTS="none"
APKREPOSOPTS="http://dl-cdn.alpinelinux.org/alpine/v3.12/main http://dl-cdn.alpinelinux.org/alpine/v3.12/community"
SSHDOPTS="-c openssh"
NTPOPTS="-c busybox"
DISKOPTS="-v -m sys -s 0 /dev/sda"

Docker on Termux [in a VM]

Create a Linux VM and install Docker in it so you can (slowly) run x86 Docker containers on your Android device.

Recommended to use SSH or external keyboard to execute the following commands unless you want sore thumbs. See https://wiki.termux.com/wiki/Remote_Access#SSH

  • Install QEMU

     pkg install qemu-utils qemu-common qemu-system-x86_64-headless
    
  • Download Alpine Linux 3.12 (virt optimized) ISO

     mkdir alpine && cd $_
     wget http://dl-cdn.alpinelinux.org/alpine/v3.12/releases/x86_64/alpine-virt-3.12.3-x86_64.iso
    
  • Create disk (note it won't actually take 4GB of space, more like 500MB)

     qemu-img create -f qcow2 alpine.img 4G
    
  • Boot it up

    qemu-system-x86_64 -machine q35 -m 1024 -smp cpus=2 -cpu qemu64 \
      -drive if=pflash,format=raw,read-only,file=$PREFIX/share/qemu/edk2-x86_64-code.fd \
      -netdev user,id=n1,hostfwd=tcp::2222-:22 -device virtio-net,netdev=n1 \
      -cdrom alpine-virt-3.12.3-x86_64.iso \
      -nographic alpine.img
    
  • Login with user root (no password)

  • Setup network (press Enter to use defaults):

     localhost:~# setup-interfaces
     Available interfaces are: eth0.
     Enter '?' for help on bridges, bonding and vlans.
     Which one do you want to initialize? (or '?' or 'done') [eth0] 
     Ip address for eth0? (or 'dhcp', 'none', '?') [dhcp] 
     Do you want to do any manual network configuration? [no] 
     localhost:~# ifup eth0
    
  • Create an answerfile to speed up installation:

    localhost:~# wget https://gist.githubusercontent.com/oofnikj/e79aef095cd08756f7f26ed244355d62/raw/answerfile
    
  • Patch setup-disk to enable serial console output on boot

    localhost:~# sed -i -E 's/(local kernel_opts)=.*/\1="console=ttyS0"/' /sbin/setup-disk
    
  • Run setup to install to disk

    localhost:~# setup-alpine -f answerfile
    
  • Once installation is complete, power off the VM (command poweroff) and boot again without cdrom:

    qemu-system-x86_64 -machine q35 -m 1024 -smp cpus=2 -cpu qemu64 \
      -drive if=pflash,format=raw,read-only,file=$PREFIX/share/qemu/edk2-x86_64-code.fd \
      -netdev user,id=n1,hostfwd=tcp::2222-:22 -device virtio-net,netdev=n1 \
      -nographic alpine.img
    
  • Install docker and enable on boot:

    alpine:~# apk update && apk add docker
    alpine:~# service docker start
    alpine:~# rc-update add docker
    
  • Useful keys:

    • Ctrl+a x: quit emulation
    • Ctrl+a h: toggle QEMU console
@janeoa

This comment has been minimized.

Copy link

@janeoa janeoa commented Dec 8, 2020

Thanks for the Gist!

I am having troubles with internet connection on alpine.
wget: bad address 'mirrors.alpinelinux.org' on setup-alpine

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Dec 9, 2020

Sounds like a connectivity problem. Can you ping Google DNS (8.8.8.8) from within the VM?

@janeoa

This comment has been minimized.

Copy link

@janeoa janeoa commented Dec 9, 2020

Sounds like a connectivity problem. Can you ping Google DNS (8.8.8.8) from within the VM?

There are no interfaces in ifconfig and can't wget/ping 1.1.1.1 or 8.8.8.8 or google.com.
Tried to edit interfaces and add lo and eth0. lo showed up in ifconfig no eth0.

It might be my phone's special case :D
I have never used termux before nor qemu 🌚.

So gonna try to play around with those for some time. Thank you for your time

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Dec 10, 2020

Oh! I left out the -netdev line in the install step. I edited the gist. Without it there is no virtual network interface for the VM to configure, which would explain why there are no interfaces showing up in ifconfig!
Now alpine-setup will ask which network interface you want to configure. Choose the defaults (eth0, dhcp) and everything should work.

Enter system hostname (short form, e.g. 'foo') [localhost]: 
Available interfaces are: eth0.
Enter '?' for help on bridges, bonding and vlans.
Which one do you want to initialize? (or '?' or 'done') [eth0] 
Ip address for eth0? (or 'dhcp', 'none', '?') [dhcp] 
Do you want to do any manual network configuration? [no] 
udhcpc: started, v1.31.1
udhcpc: sending discover
udhcpc: sending select for 10.0.2.15
udhcpc: lease of 10.0.2.15 obtained, lease time 86400
Changing password for root
New password: 
@LukasRepos

This comment has been minimized.

Copy link

@LukasRepos LukasRepos commented Dec 19, 2020

When booting without cdrom it gives me this error:
BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0): Not Found BdsDxe: loading Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0xFFFF,0x0) BdsDxe: starting Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0xFFFF,0x0)

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Dec 19, 2020

When booting without cdrom it gives me this error:
BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0): Not Found BdsDxe: loading Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0xFFFF,0x0) BdsDxe: starting Boot0002 "UEFI QEMU HARDDISK QM00001 " from PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x0,0xFFFF,0x0)

This is expected. Be patient - after a few minutes it will finish booting and eventually show a login prompt.
I've updated the gist so that console output shows on first boot.

@kadrim

This comment has been minimized.

Copy link

@kadrim kadrim commented Dec 20, 2020

great gist!

Also very good, that you included the hostfwd=tcp::2222-:22 for port-forwarding. For everyone else: note that on unrooted android you can only use highports (>=1024)

Works like a charm on my stock samsung galaxy note 9 :-)

Thanks alot!

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Dec 20, 2020

Works like a charm on my stock samsung galaxy note 9 :-)

Thanks alot!

Cheers

@kamiluo

This comment has been minimized.

Copy link

@kamiluo kamiluo commented Dec 29, 2020

wow. Thanks!!! Works on Redmi Note 9.

@schnatterer

This comment has been minimized.

Copy link

@schnatterer schnatterer commented Jan 2, 2021

It's incredibly slow but it works 😄 Nice idea, thanks!

In case it's interesting to anyone: You can also access docker from outside the VM using the static docker binary and export DOCKER_HOST=ssh://root@localhost:2222.
I had to add my termux public key to /root/.ssh/authorized_keys inside the VM.

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Jan 3, 2021

It's incredibly slow but it works Nice idea, thanks!

In case it's interesting to anyone: You can also access docker from outside the VM using the static docker binary and export DOCKER_HOST=ssh://root@localhost:2222.
I had to add my termux public key to /root/.ssh/authorized_keys inside the VM.

Thanks for mentioning this! I actually compiled Docker locally on my phone and set this up just to see if it would work and was pleasantly surprised that it did. That was the reason why I added the port forwarding in the first place.

Using the pre-compiled binary certainly saves some time (and storage).

@schnatterer

This comment has been minimized.

Copy link

@schnatterer schnatterer commented Jan 3, 2021

Thanks for mentioning this! I actually compiled Docker locally on my phone and set this up just to see if it would work and was pleasantly surprised that it did. That was the reason why I added the port forwarding in the first place.

Using the pre-compiled binary certainly saves some time (and storage).

I saw the port forward and was wondering why it wasn't mentioned in the docs. Happy my comment was helpful for you!

Another hint that might save you some googling:
You can forward more ports on VM startup by appending to the -netdev user,id=n1,hostfwd=tcp::2222-:22 option, e.g. ,hostfwd=tcp::8080-:8080.

When starting a container with a port binding to one of the ports bound to the host, you can get traffic from your android host to the container.
Example:

docker run --rm -p8080:80 nginx

Will display nginx' start page on http://localhost:8080 in your android browser.

@TechComSpot

This comment has been minimized.

Copy link

@TechComSpot TechComSpot commented Jan 6, 2021

Hi, thank you for your gist.
But I can't docker pull hello-world :( does my android have to be rooted?

@kadrim

This comment has been minimized.

Copy link

@kadrim kadrim commented Jan 7, 2021

what's the output?

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Jan 7, 2021

does my android have to be rooted?

@TechComSpot no, qemu runs as a non-privileged user completely in userspace. It does not require root.
If you share the error you receive we may be able to help.

@TechComSpot

This comment has been minimized.

Copy link

@TechComSpot TechComSpot commented Jan 7, 2021

Thank you guys. I fixed it. Not what it was but docker is pulling images ;)
I pulled ubuntu image and installed tigervnc in it, but ubuntu shows no such command :( do you know what is?
Is there a way to have UI for the images with VNCViewer for example?

@jacossio

This comment has been minimized.

Copy link

@jacossio jacossio commented Jan 11, 2021

Very cool stuff. Curious to know if you've managed to bring up an aarch64 image of alpine using qemu-system-aarch64 ?
The use case would be to run a fully owned linux VM. Maybe the performance would be better?

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Jan 12, 2021

Curious to know if you've managed to bring up an aarch64 image of alpine using qemu-system-aarch64 ?

Sure - look at the raw readme, there's a commented out section with aarch64 instructions but I found it to be significantly slower than x86_64. Since both are running in full software emulation mode, it makes little difference that the underlying hardware is the same architecture as the virtual machine hardware. Give it a go though, your mileage may vary.

Regarding the use case, the guide here results in exactly what you describe - a fully owned linux VM, with root privileges, running as a non-privileged userspace process.

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Jan 12, 2021

I pulled ubuntu image and installed tigervnc in it, but ubuntu shows no such command :( do you know what is?

@TechComSpot I'm not familiar with installing TigerVNC on Ubuntu, but any guide you could find online should help you do it, like this one. I would warn that this may be unusably slow, however.

Is there a way to have UI for the images with VNCViewer for example?

If you just want a graphical environment for Termux, consider referring to this guide.

@ralphmujar

This comment has been minimized.

Copy link

@ralphmujar ralphmujar commented Jan 28, 2021

I've done all the steps, successfully installed docker and run service docker start and still got this error Cannot connect to the Docker daemon at unix:/var/run/docker.sock when I try to docker pull hello-world

@TechComSpot

This comment has been minimized.

Copy link

@TechComSpot TechComSpot commented Jan 28, 2021

@ralpmujar I was having same issue but rebooting qemu did the fix.

@ochen1

This comment has been minimized.

Copy link

@ochen1 ochen1 commented Feb 21, 2021

^, or you can start the Docker deamon manually, eg. through sudo service start dockerd / sudo dockerd

@sobaee

This comment has been minimized.

Copy link

@sobaee sobaee commented Feb 24, 2021

Thanks a lot

Just a question please:
How to uninstall all of these?

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Feb 25, 2021

Hi @sobaee, you can uninstall by uninstalling all the packages installed at the top of the instructions (pkg uninstall) and deleting the alpine directory, which includes the ISO installer and virtual machine disk file.

@fracalhub

This comment has been minimized.

Copy link

@fracalhub fracalhub commented Mar 8, 2021

Hi,
when I execute first command (pkg install qemu-utils qemu-common qemu-system-x86_64-headless) i see this errors:
E: Unable to locate package qemu-utils
E: Unable to locate package qemu-common
E: Unable to locate package qemu-system-x86_64-headless

I already tried to execute termux-setup-storage, apt upgrade, apt update.
I have an android 6 device (xperia z3compact)

@mrking89

This comment has been minimized.

Copy link

@mrking89 mrking89 commented Mar 8, 2021

Screenshot_20210308-184540_Termux

@Slypth

This comment has been minimized.

Copy link

@Slypth Slypth commented Mar 14, 2021

Hi there. I have followed all the steps so far, but am unfortunately stuck with the last few. When booting without the cdrom, after a few minutes, I finally get stuck on the following screenshot. It simply doesn't go further than this. Any ideas what to do?

(Info)
Android version: Android 10.
Phone: Hauwei Honor 8X.
Latest version of Termux installed from F-Droid.

image

@oofnikj

This comment has been minimized.

Copy link
Owner Author

@oofnikj oofnikj commented Mar 15, 2021

@mrking89 @Slypth it appears you are both facing the same issue related to the EFI shell not finding the correct path to the boot loader. It could be that some default setting changed due to a version upgrade somewhere. I'll look in to it.

@Slypth

This comment has been minimized.

Copy link

@Slypth Slypth commented Mar 15, 2021

Thank you very much. It will be great to be able to run docker on my device so that I can use it on-the-go, even if it's really slowly.

@efranelas

This comment has been minimized.

Copy link

@efranelas efranelas commented Mar 16, 2021

Thank you! I could install on Galaxy A10 Android 10 but even though the docker daemon service is running, docker client cannot connect to it via unix socket. I tried adding root to docker group in /etc/group and setting the permissions for /var/run/docker.sock to 777 but obtained no success.
Does anyone know how to fix it?

@Auus-booop

This comment has been minimized.

Copy link

@Auus-booop Auus-booop commented Mar 21, 2021

Screenshot_2021-03-21-10-10-49-514_com termux

Are it's oke? I installed on Xiaomi resmi 4a😅
Sorry if this question having newbie's sign.

@quyetvk

This comment has been minimized.

Copy link

@quyetvk quyetvk commented Mar 22, 2021

@Auus-booop

Are it's oke? I installed on Xiaomi resmi 4a😅

I think you missed an action at step "localhost:~# setup-alpine -f answerfile".
You should select "yes" if system warning that a disk is erased. Default is "NO".

@Slypth

This comment has been minimized.

Copy link

@Slypth Slypth commented Mar 23, 2021

Thank you very much, @quyetvk! You solved the problem that I was having. I can only assume that @mrking89 was having the same problem too. All it took was for me to delete the alpine directory and start over. When I got to the question in the installation asking if I wanted to erase the disk, choosing "yes" is the right answer. Everything ran smoothly afterwards. My problem was that I kept choosing "no."

@oofnikj, if you could please update the guide to include this into it, that would be really helpful for other users.
If it is also possible to perhaps put this in the answerfile, that would be great! Thanks a lot, everyone!

@egandro

This comment has been minimized.

Copy link

@egandro egandro commented Apr 4, 2021

I created a full automatic setup script including ssh: https://github.com/egandro/docker-qemu-arm/

It works on Android with Termux and Raspberry Pi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment