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.
2
Answers
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).
Where
$ip
contains the address of your docker container's bridge ip address.This repo helped me figure it out
You have, for connecting to the Android emulator running in a Docker container from the host machine:
You have already forwarded the necessary ports in your Docker Compose file. The ports 5554 and 5555 should allow connections to the emulator from the host.
To connect to the emulator, use the command
adb connect localhost:5555
on your host machine. However, as you mentioned, you are unable to establish a connection. The issue might be related to the network configuration or how the emulator is set up within the Docker container.Make sure the Docker container’s network configuration allows for inbound connections on the forwarded ports. You can test this by trying to connect to other services running in the Docker container (if any) on different ports.
Make sure that the ADB server is running on your host machine. You can start it with
adb start-server
.Inside the Docker container, check if the emulator is running and listening on the correct ports. You can use
netstat -tuln | grep 5554
to verify this. Make sure no firewall rules are blocking the connection on your host machine. Check the logs of the Docker container and the emulator for any errors or warnings that might indicate the problem.From the OP‘s answer
So, merely forwarding ports in the Docker Compose file is not sufficient for establishing a successful connection to the Android emulator.
The OP resolved the issue by using
socat
to create a bridge between the host machine and the emulator within the Docker container.The
socat
commands listen on TCP and UDP ports 5554 and 5555 on the host machine and forward these to the corresponding ports on the Docker container, effectively creating a tunnel for the ADB to connect through.The
$ip
variable in thesocat
command should be set to the Docker container’s bridge IP address. That step was critical in allowing the ADB on the host to communicate with the emulator running inside the Docker container.