Search code examples
androiddockerandroid-emulatordocker-network

Connecting to Android Emulator running inside docker container from host


I have a docker container that is running Ubuntu which in turn is running a headless instance of the Android emulator. I'd like to be able to connect to this emulator from the host machine running the docker container. I have the following docker compose file:

tests:
    image: android-emulator-base:latest
    container_name: tests
    tty: true
    ports:
      - 5555:5555
      - 5554:5554
    networks:
      - mynet
    devices:
      - /dev/net/tun
    volumes:
      - /etc/resolv.conf:/run/resolv.conf
    privileged: true
    environment:
      - NETWORK_MODE=bridge
networks:
  mynet:
    driver: bridge

I've created a bridge and tap interface in the ubuntu docker container to allow the android emulator to talk to other devices on the bridge network. The Ubuntu docker container's ip a output is as follows:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 02:42:ac:14:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.20.0.4/16 brd 172.20.255.255 scope global br0
       valid_lft forever preferred_lft forever
3: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN group default qlen 1000
    link/ether ea:d1:06:a5:34:c9 brd ff:ff:ff:ff:ff:ff
41: eth0@if42: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default 
    link/ether 02:42:ac:14:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0

I then start the Android emulator with emulator -avd emulator -no-window -no-audio -port 5554 -skip-adb-auth -no-boot-anim -gpu off -net-tap tap0 &.

But when I try and connect to the Android emulator from the host machine with adb connect localhost:5555 the connection fails to connect.

I see a lot of people online suggesting that I use host network configuration for the docker container hosting the android emulator - which does solve this problem - but for reasons outside the scope of this question using the host network is not an option. I should also mention that projects like docker-android are not an option for me because I need ARM machines.

Why isn't this working? It seems like if the docker container is being configured to forward ports 5555 and 5554 that the Android emulator should be accessible from the host machine.


Solution

  • Okay, so for anyone who might have the same issue and stumbles upon this:

    In my original post I was 95% of the way there but just forwarding the ports in your docker compose file isn't enough, you also need to execute the following lines (or add them to your entrypoint script).

    socat tcp-listen:5554,bind=$ip,fork tcp:127.0.0.1:5554 &
    socat tcp-listen:5555,bind=$ip,fork tcp:127.0.0.1:5555 &
    
    socat udp-listen:5554,bind=$ip,fork udp:127.0.0.1:5554 &
    socat udp-listen:5555,bind=$ip,fork udp:127.0.0.1:5555 &
    

    Where $ip contains the address of your docker container's bridge ip address.

    This repo helped me figure it out