31

I have created a Docker image which contains the Android SDK and am trying to expose my Android phone in a container running this image. So I used the --privileged flag and mounted the USB devices as follows:

$ docker run --privileged -v /dev/bus/usb:/dev/bus/usb -d -P my-android:0.0.1

However, when I run ADB devices, it does not show me the USB device:

ubuntu@d56b666be455:~/Android/Sdk/platform-tools$ ./adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached

ubuntu@d56b666be455:~/Android/Sdk/platform-tools$

lsusb inside the container lists the device:

ubuntu@d56b666be455:~$ lsusb
...
Bus 002 Device 017: ID 04e8:6866 Samsung Electronics Co., Ltd GT-I9300 Phone [Galaxy S III] (debugging mode)

The device is however visible on the host:

⇒  ./adb devices
List of devices attached
4d11abcd65b74045    device

Host OS

$ uname -a
Linux ananya 3.16.0-33-generic #44~14.04.1-Ubuntu SMP Fri Mar 13 10:33:29 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

Docker version

$ docker --version
Docker version 1.5.0, build a8a31ef

What could be the issue?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
buzypi
  • 1,522
  • 1
  • 12
  • 15
  • 5
    I don't think the adb daemon running in the device can be connected to two adb servers. Try disconnecting it from your host machine's adb and then connect it to the docker's adb. – jlhonora Apr 10 '15 at 14:19
  • For a solution without `--privileged` see [this answer](https://stackoverflow.com/a/24231872/875020) – x29a Dec 14 '20 at 22:02

7 Answers7

21

I don't think the ADB daemon running on the device can be connected to two ADB servers. Try disconnecting it from your host machine's ADB and then connect it to the Docker container's ADB.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jlhonora
  • 10,179
  • 10
  • 46
  • 70
  • 3
    After using this for some time now, I see that the adb daemon starts automatically on host and this prevents connecting with the Docker container. If you kill the adb daemon in the host, then the Docker container's adb daemon is able to communicate with the phone. – buzypi Jun 25 '15 at 05:23
  • 1
    I dont have ADB server running on host but ADB server on docker can't see the device yet. – hldev Apr 25 '22 at 18:10
15

While I was trying the same, I ran into some other problems related to that, which I would like to share so that others may save their time:

Problem 1: lsusb was not installed in the container

In my case lsusb was not installed, so I installed it with the below command:

apt-get update
apt-get install usbutils

Problem 2: not able to see the device even after lsusb and ADB SDK installation

You need to restart your container with the -v option, and yes don't forget to kill the ADB server as stated in one of the answers.

On the host:

adb-kill server
docker run -ti -d --privileged -v /dev/bus/usb:/dev/bus/usb   container_name

In case someone wanted do it from scratch, I have written a blog post on it:

How to connect ADB devices to Linux container

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
pankaj mishra
  • 2,555
  • 2
  • 17
  • 31
  • 7
    "I found this URL pretty useful"...coming from someone who wrote said URL, seems *VERY SUSPICIOUS*. You should disclose your affiliation to your blog post. – Blue Feb 27 '18 at 07:59
  • 1
    @FrankerZ i have written this blog, if you think this violates any SO norm , i can remove the url – pankaj mishra Feb 27 '18 at 08:05
  • 2
    Writing the blog, and linking to it is not against SO policy. Linking to it, and NOT disclosing you're the author, is an issue. Also, use capital i's. – Blue Feb 27 '18 at 09:04
  • 3
    Your +10 points is the command: `adb-kill server` for avoid the host of docker block the adb from the cotainer. – tres.14159 Apr 03 '19 at 13:47
  • The URL is now http://learningbysimpleway.blogspot.com/2018/02/how-to-connect-adb-devices-to-linux.html – mikebridge Nov 16 '20 at 21:18
  • shouldn't it be adb kill-server instead of adb-kill server? – York Yang Sep 01 '23 at 04:09
9

This doesn't answer the exact question you were asking, but does address what you were trying to accomplish - connecting to an android device connected to a docker host from an adb client running inside a docker container. I'm including this for anyone trying to accomplish the same thing (like I was).

The adb client supports a -H option which tells it where to find the adb server to connect to. Docker supports the hostname "host.docker.internal" which always maps to the IP address of the docker host. Assuming your device is connected to the docker host, you can do the following to get your containerized adb client to connect to the adb server running on the docker host:

adb -H host.docker.internal devices

Accomplishes the goal without having to mount the USB ports.

Reference: https://developer.android.com/studio/command-line/adb

Update: I recently learned that host.docker.internal is only supported on Docker for Mac in versions 18.0 and above.

RChavez
  • 91
  • 1
  • 3
  • 1
    Would you mind explaining more details about `host.docker.internal` ? I've tried `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_id` to get container's IP address, then tried `adb -H 172.xx.x.x devices`, I got this error `** Cannot start server on remote host error: cannot connect to daemon`. – Corey May 14 '19 at 06:21
  • 1
    @Corey , I've run across that error. In my case, that error was due to the adb-server not already running on the host machine (172.xx.x.x). adb is actually two components, a client and a server and usually run on the same host, and if the server isn't running then the client will start it and then connect to it. Because they're on separate servers, you'll need to start the server manually on the docker host with "adb start-server". Hope that helps. – RChavez May 15 '19 at 19:50
  • Curiously this worked first time. Windows 10 host, just had to make sure the host side server was running beforehand. –  Apr 15 '20 at 10:09
  • 1
    @Corey I had to kick-start the daemon on the host (Windows) , is as easy as just running adb devices on host and waiting slightly for the server piece to start. I'm running my container "elevated", if that helps, otherwise totally vanilla I installed Docker yesterday. –  Apr 15 '20 at 10:29
  • It makes my adb segment fault which is so weird. I am using windows as host. – tigertang Jun 12 '20 at 06:38
  • After spending two days trying to connect from docker to a hosted emulator, this was the definitive answer! Thanks @RChavez! – Freddy Jan 18 '22 at 02:48
  • This solution works fine on a windows host, but in the case the host of the docker is a mac, it doesn't work. list devices is okay, but the install command stuck in my case – thibsc Mar 17 '23 at 16:28
3

Running with just --privileged -v /dev/bus/usb:/dev/bus/usb did not work for me. I tried forwarding the adb daemon's listening port using -p 5037:5037, but that did not help either.

It worked only after I added --net host. This means the host machine's net interfaces are exposed to the docker so use it if you are fine with that. Maybe there are more ports that needed to be forwarded other than 5037....

Robert Columbia
  • 6,313
  • 15
  • 32
  • 40
Wildsheep
  • 31
  • 2
  • Only 5037 is needed. For example, `ssh -N -L 0.0.0.0:5037:127.0.0.1:5037 $host` is only needed to forward adb through ssh tunnel. – tigertang Jun 12 '20 at 06:40
  • Killing the host server and restarting it in the container worked great for me, nice tip! – RoraΖ May 24 '22 at 14:06
1

This works for me.

  • Set your devices in PPT mode
  • (optionaly) Check if the devices is available localy $ adb devices

I try with many options and only one works. Using --network flag as the next example

  • Run container

$ docker run -it --net host ubuntu bash

output:

List of devices attached
464e128 device

I used this Dockerfile. Is for flutter projects

0

Update:

I ended up using --privileged and -v to map the whole of /dev/bus/usb and patching adb to accept one environment variable to specify the root USB device tree - /dev/bus/usb/001 etc.

This allowed us to use different USB busses for different containers for different groups of the same phone, and another environment variable patch allowed different VID:PID lists for different types of phone.


We're trying to allocate different USB buses to different Docker containers running TeamCity clients.

Each container needs ANDROID_ADB_SERVER_PORT setting to a different port (because we're not using segregated networking).

The host machine can't run adbd, because only one adbd can talk to a phone at any given time.

Each container gets one of the /dev/bus/usb/xxx directories, so we can plug phones into particular containers.

We have to synchronise the /dev/bus/usb/xxx directory every few seconds, to allow hot-plugging and reboots - just a shell loop on the host that runs tar cf devxxx.tar /dev/bus/usb/xxx, docker cp to transfer it, then docker exec to untar inside the container's /tmp, diff to detect nodes to delete, and mv -n to move new nodes in.


In fact, because we're running on Linux, we can probably just set up udev scripts, per Howto run a script when a USB device is pluged in.

android.weasel
  • 3,343
  • 1
  • 30
  • 41
0

Excuse me for offtop. But I cannot answer to this question so I write it down here.

I am using ubuntu:18.04 and tried to connect my Samsung Galaxy A3 2016 and debug it with ADB. Devices was unauthorized and no dialog popped up on the screen!

How I solved the problem:

I was interested will the problem still occure inside a Docker container? The answer was "No!".

  1. Inside a Docker container, that I invoked with following: (this is the answer for this topic :) )

    docker run --name android-adb -it -d --privileged -v /dev/bus/usb:/dev/bus/usb ubuntu:16.04 bash
    
  2. I downloaded platform-tools (distribution with ADB). Added its path to environment. And restarted bash

  3. After restarting ADB server inside Docker container AND killing ADB server on host machine. I found out that confirmation dialog appeared on the smartphone's screen!

So on the host machine the problem was in .android directory I think. Just move it to .android-backup. The next adb start-server command will create new one. Also I replaced platform-tools folder with most recent

zetyquickly
  • 176
  • 6
  • 1
    There is no point in explicitly mounting `/dev/bus/usb:/dev/bus/usb`, `--privileged` will run the container as root user which has access to everything on host already. – hldev Apr 25 '22 at 16:05