Skip to content

Instantly share code, notes, and snippets.

@oofnikj
Last active October 3, 2024 16:44
Show Gist options
  • Save oofnikj/e79aef095cd08756f7f26ed244355d62 to your computer and use it in GitHub Desktop.
Save oofnikj/e79aef095cd08756f7f26ed244355d62 to your computer and use it in GitHub Desktop.
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
@LeftandRights
Copy link

LeftandRights commented Aug 18, 2023

Perhaps the issue might be located within the QEMU starting command itself. You need to specify the hostfwd flag along with the port you intend to use. For example, use -hostfwd=tcp::9000-:9001. What this flag does is to forward TCP traffic from port 9000 on the host to port 9001 on the guest. In other words, any incoming traffic directed at port 9000 on the host will be redirected to port 9001 within the virtual machine.

I don’t know if it is right because if I have more services with different ports?

I don't know if there's a better way to do this, but if you want to forward multiple ports, you could've use the hostfwd flag multiple times. This is how the command would looks like -hostfwd=tcp::8080-:80,hostfwd=tcp::9000-:8081. This is how i usually forward ports on QEMU so, hope it helps.

@Petrik-a-dost
Copy link

-hostfwd=tcp::8080-:80 -hostfwd=tcp::9000-:8081

if I use this command:
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 -hostfwd=tcp::8080-:80 -hostfwd=tcp::9000-:8081 -device virtio-net,netdev=n1 -nographic alpine.img

I gets this message:
qemu-system-x86_64: -hostfwd=tcp::2222-:22: invalid option

@Petrik-a-dost
Copy link

@LeftandRights maybe I think it looks like that portforwarding between Termux and VM Alpine not working because If I try ping in termux to vm alpine (ping 10.0.2.15) I get icmp_seq=10 Time to live exceeded, but in VM Alpine is eth0: 10.0.2.15. What do you mean?

@LeftandRights
Copy link

@LeftandRights maybe I think it looks like that portforwarding between Termux and VM Alpine not working because If I try ping in termux to vm alpine (ping 10.0.2.15) I get icmp_seq=10 Time to live exceeded, but in VM Alpine is eth0: 10.0.2.15. What do you mean?

Although it shows 10.0.2.15 on the VM, it actually forwarded to your machine IPv4 address (192.168.1.32)

@Petrik-a-dost
Copy link

@LeftandRights maybe I think it looks like that portforwarding between Termux and VM Alpine not working because If I try ping in termux to vm alpine (ping 10.0.2.15) I get icmp_seq=10 Time to live exceeded, but in VM Alpine is eth0: 10.0.2.15. What do you mean?

Although it shows 10.0.2.15 on the VM, it actually forwarded to your machine IPv4 address (192.168.1.32)

OK, if I try ping from VM Alpine to Termux so in alpine:~# ping 192.168.1.32 I get: 64 bytes from 192.168.1.32: seq=2 ttl=255 time=6.812 ms. In this case it looks ok

@Petrik-a-dost
Copy link

@LeftandRights so this mean that I can from VM Alpine to Termux but I cann't from Termux to VM Alpine?

@LeftandRights
Copy link

LeftandRights commented Aug 20, 2023

-hostfwd=tcp::8080-:80 -hostfwd=tcp::9000-:8081

if I use this command: 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 -hostfwd=tcp::8080-:80 -hostfwd=tcp::9000-:8081 -device virtio-net,netdev=n1 -nographic alpine.img

I gets this message: qemu-system-x86_64: -hostfwd=tcp::2222-:22: invalid option

Sorry for the previous comment, the hostfwd flag should be used along with the netdev flag which turns out be something like this
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,hostfwd=tcp::8080-:80,hostfwd=tcp::9000-:8081 -device virtio-net,netdev=n1 -nographic alpine.img

@valorisa
Copy link

When I launch Alpine with QEMU, I obtain this :

" Starting networking ... * lo ... [ ok ]

  • docker0 ...Cannot find device "docker0"
    Cannot find device "docker0"
    Device "docker0" does not exist.
    [ ok ]
  • eth0 ... [ ok ]
  • Seeding random number generator ... * Seeding 256 bits and crediting
  • Saving 256 bits of creditable seed for next boot
    [ ok ] "

@whyakari
Copy link

got internet error. so what I did:
vi /etc/resolv.conf

nameserver 8.8.8.8

:wq

@apchhi
Copy link

apchhi commented Dec 26, 2023

To avoid the connection problem that occurred with the authors of the posts above, you need to do the following:

  1. In the interface setup item localhost:~# setup-interfaces, select 2 items and 3 type "yes" instead of [no]
    Do you want to do any manual network configuration? [no] yes
  2. In the document that opens, paste this:
    auto lo
    iface lo inet loopback
    auto eth0
    iface eth0 inet static
    address 192.168.1.10
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 1.1.1.1
  3. Check:
    cat /etc/network/interfaces
  4. localhost:~# ifup eth0
  5. Check this file:
    cat /etc/resolve.conf
  6. If there is no such thing, then insert:
    echo "nameserver 192.168.1.1 nameserver 1.1.1.1" > /etc/resolv.conf
  7. localhost:~# /etc/init.d/networking restart
  8. if there are no errors, everything is ok

@shi-ivam
Copy link

shi-ivam commented Jan 7, 2024

echo "nameserver 192.168.1.1
nameserver 1.1.1.1" > /etc/resolv.conf

This works

@AntonyZ89
Copy link

Hello! 👋

I forked @egandro's qemu-docker-arm (great work!), did some refactoring to work with the latest version of Alpine (3.19) and added to the README @schnatterer's idea to connect and use docker in your terminal using ssh! Creating a great experience to use docker without needing root! 😄

repo: https://github.com/AntonyZ89/docker-qemu-arm

using docker compose to up my postgresql + redis:

Screen_Recording_20240118_144445_Termux-ezgif.com-crop-video.mp4

@mohit6350
Copy link

Thank you good sir !

@AlbertWang2018
Copy link

i have no internet why?

localhost:# ifup eth0 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 localhost:# wget https://gist.githubusercontent.com/oofnikj/e79aef095cd08756f7f 26ed244355d62/raw/answerfile wget: bad address 'gist.githubusercontent.com' edit: This network setting work for me: localhost: # echo -e "auto lo\niface lo inet loopback\nauto eth0\niface eth0 inet dhcp" > /etc/network/interfaces localhost: # /etc/init.d/networking restart localhost:~# echo nameserver 1.1.1.1 > /etc/resolv.conf nameserver 8.8.8.8 does not work for me

Thanks for solving my problem. For me other problem is need modify /etc/apk/repositories enable community source, delete # in '#http://dl-cdn.alpinelinux.org/alpine/v3.12/community', otherwise run 'apk add docker' with error 'required by: world[docker-compose]'.

@zzduci
Copy link

zzduci commented Feb 23, 2024

I tried running a Flask server in it and listen to port 5000 and host 0.0.0.0 which supposed to be accessible to all devices that connected to the same router. But in this case i can't even access it through my browser. Feel free to reply, any help will be appreciated.

qemu-system-x86_64 -machine q35 -m 1024 -smp cpus=2 -cpu qemu64
-drive if=pflash,format=raw,read-only=on,file=$PREFIX/share/qemu/edk2-x86_64-code.fd
-netdev user,id=n1,hostfwd=tcp::2222-:22,hostfwd=tcp::9000-:9000,hostfwd=tcp::4567-:4567,hostfwd=tcp::5344-:5344 -device virtio-net,netdev=n1
-cdrom alpine-virt-3.12.3-x86_64.iso -nographic alpine.img

like this ,portainer is working now

@gd03champ
Copy link

This is crazy!! Spinning up a vm in my mobile and running docker in it 🚀

@egandro
Copy link

egandro commented Apr 26, 2024

I updated my installer: https://github.com/egandro/docker-qemu-arm

  • latest (stable) alpine 3.19
  • that means latest docker + docker compose
  • mitigation for (well known) alpine dns and ipv4/v6 issues

Please report issues here: https://github.com/egandro/docker-qemu-arm/issues

@valorisa
Copy link

valorisa commented May 4, 2024

Thanks for updated to 3.19.1

@raj-sharma-git
Copy link

raj-sharma-git commented May 12, 2024

I am trying to install with the aarch64 qemu but keeps getting
/dev/sda is not a block device suitable for partitioning.

All the step went fine but getting error at the Disk & Install step, looks like it is not able to find the disk.
which I created using:
qemu-img create -f qcow2 alpine.img 20G

I am using below command to boot:
qemu-system-aarch64 -machine virt -m 2048 -smp cpus=2 -cpu max
-drive if=pflash,format=raw,read-only,file=$PREFIX/share/qemu/edk2-aarch64-code.fd
-netdev user,id=n1,hostfwd=tcp::2222-:22 -device virtio-net,netdev=n1
-cdrom alpine-virt-3.19.1-aarch64.iso
-nographic alpine.img

@egandro
Copy link

egandro commented May 14, 2024

@raj-sharma-git I have a question.

Is there a special reason you want to run arm 64? It is still not accelerated - far slower then x86_64 ( I read about 2x or 4x slower - not sure about this). Do you "need" it?

I consider finding out how that works - I still don't understand the reason.

@raj-sharma-git
Copy link

I thought that the performance would be better because it operates on the same architecture as the phone's processor. My assumption was that it would opt for virtualization instead of emulation, leading to superior performance.

@Abdullrahman-Dawaliby
Copy link

Abdullrahman-Dawaliby commented May 28, 2024

Guys do you know about proot-distro and ubuntu distro? It's much lighter and faster than qemu and supports docker not sure about alpine

Edit: forget that, it has errors with cgroups and I didn't know how to fix it

@egandro
Copy link

egandro commented Jun 3, 2024

I thought that the performance would be better because it operates on the same architecture as the phone's processor. My assumption was that it would opt for virtualization instead of emulation, leading to superior performance.

If you "need" arm 64 docker and can give me a good reason why, I might consider adding this to my repo. I really see no point at the moment. You might have. That's why I am asking you.

@egandro
Copy link

egandro commented Jun 3, 2024

Guys do you know about proot-distro and ubuntu distro? It's much lighter and faster than qemu and supports docker not sure about alpine

Not true: https://en.wikipedia.org/wiki/Alpine_Linux

Alpine Linux is a Linux distribution designed to be small, simple, and secure. It uses musl, BusyBox, and OpenRC instead of the more commonly used glibc, GNU Core Utilities, and systemd.This makes Alpine one of few Linux distributions not to be based on the GNU Core Utilities.

@egandro
Copy link

egandro commented Jun 28, 2024

I updated to alpine 3.20

@orangeed
Copy link

  Error: Could not retrieve NBP file size from HTTP server.

  Error: Server response timeout.
BdsDxe: failed to load Boot0004 "UEFI HTTPv4 (MAC:525400123456)" from PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)/Uri(): Not Found

what this?

@orangeed
Copy link

_PXE-E16:未收到有效报价。BdsDxe :无法从 PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0.0 加载 Boot0003“UEFI PXEv4 (MAC:525400123456)”:未找到
Did you solve it?

@egandro
Copy link

egandro commented Jul 25, 2024

  Error: Could not retrieve NBP file size from HTTP server.

  Error: Server response timeout.
BdsDxe: failed to load Boot0004 "UEFI HTTPv4 (MAC:525400123456)" from PciRoot(0x0)/Pci(0x2,0x0)/MAC(525400123456,0x1)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)/Uri(): Not Found

what this?

I think the Alpine version that is refered in this post is a bit outdated. Try using 3.19 or 3.20

@orangeed
Copy link

orangeed commented Jul 25, 2024 via email

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