Use ADB to Connect to Your Android Device From a Docker Container

You may have a use-case where you want to write software to manipulate an Android device using a system or set of tools that are not natively available from your current system. However, you might be able to expose this as a Docker image. For example, your device is (or will be) connected to a Windows machine and you really want to or need to use Linux tools.

No problem. ADB implicitly uses a client-server model: The ADB tool (on your system) connects to the ADB server (runs in the background on your system) which interacts with the ADB daemon (runs on your device). This means that we can forward requests from ADB on the command-line in the guest container in Docker to the ADB server on the host system.

The ADB client and server have to be at the same version, or the client will indiscriminately kill/restart your ADB server. So, as I am currently running Ubuntu 14.04 on my host system, I will do the same in Docker.

First, I will make sure the ADB server is running on my host system. Most of the subcommands that will automatically start the local server, but I will start it directly:

$ adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *

Now, I will start a container in Docker with Ubuntu 14.04 and automatically install ADB before dropping to a prompt. Note that we are passing “–network=host” in order to share the host’s network identity:

$ docker run -i -t --network=host ubuntu:14.04 /bin/bash -c "sudo apt-get update && sudo apt-get install -y android-tools-adb && /bin/bash"

Eventually, you will end-up at the prompt. Just do something simple like enumerating the devices:

root@mlll2664:/# adb devices
List of devices attached 
05157df572841820 device

The “mlll2664” hostname, represented in the prompt in the Docker container, is, actually, the same hostname as my host system.

So, there you go. Not too painful.

 

Listing Available Package Versions in Ubuntu: The “Madison” Subcommand

There is an unlisted subcommand to apt-cache called “madison”. This will simply list all available versions:

$ apt-cache madison git
git | 1:2.11.0-2~ppa0~ubuntu14.04.1 | http://ppa.launchpad.net/git-core/ppa/ubuntu/ trusty/main amd64 Packages
git | 1:1.9.1-1ubuntu0.3 | http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
git | 1:1.9.1-1ubuntu0.3 | http://security.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
git | 1:1.9.1-1 | http://us.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages
git | 1:1.9.1-1 | http://us.archive.ubuntu.com/ubuntu/ trusty/main Sources
git | 1:1.9.1-1ubuntu0.3 | http://us.archive.ubuntu.com/ubuntu/ trusty-updates/main Sources
git | 1:1.9.1-1ubuntu0.3 | http://security.ubuntu.com/ubuntu/ trusty-security/main Sources

In all likelihood this will work under Debian, too.

Environment Variables Under SSH

It’s a fairly important point that if you want to define global environment variables on an Ubuntu host that will be accessible from a command executed via SSH, OpenSSH provides few options and most blogs will give users incorrect advice.

It turns out that adding variables to /etc/profile or /etc/profile.d/* is patently incorrect.

If you want to add an environment variable that any script for any user can see when executed via SSH (“ssh <user>@<host> <command>“), add it to /etc/environment. It’s similar to ~/.ssh/environment (if that’s turned-on with PermitUserEnvironment), but global.