Docker容器内连接Android设备

最近使用docker来运行自动化,由于appium服务是放在docker容器内部,而设备是连接在电脑上,那么如何实现容器内部的appium服务连接到宿主机电脑设备呢?

环境准备

宿主机安装adbkit

1
sudo npm i -g adbkit  

设备连接

启动adbkit

宿主机启动adbkit

1
adbkit usb-device-to-tcp -p $port $serial

通过上述命令启动手机,其中port表示监控的端口,serial是手机的udid,可通过adb devices命令查看。

连接母机

首先在容器内部安装好adb 环境,容器可以基于centos7基础镜像创建,在容器中连接母机及指定手机udid(需要指定连接哪个手机)

1
adb connect $ip:$serial

这里的ip是母机的ip,为了方便docker提供了专门的标志表示母机的ip:host.docker.internal,这样就需要每次启动查询ip了。修改后为:

1
adb connect host.docker.internal:$port

按上述步骤在母机启动adbkit并在容器中连接母机后,即可在母机通过adb devices 查看连接的手机, 需要注意的是使用host.docker.internal作为ip

注意

adb连接手机默认使用的是5037,母机与容器交互的接口无法在使用该端口,需要选择其他端口

踩坑

adbkit连接失败

本地host设置错误时,adbkit连接设备时可能会出现如下报错:

1
2
3
4
5
6
mac@sutune0223 ~ % adbkit usb-device-to-tcp -p 7788 46FDU19409009319
Connect with `adb connect localhost:7788`
An error occured: getaddrinfo ENOTFOUND localhost
An error occured: getaddrinfo ENOTFOUND localhost
An error occured: getaddrinfo ENOTFOUND localhost
An error occured: getaddrinfo ENOTFOUND localhost

解决方案:本地设置127.0.0.1的Host。

1
127.0.0.1	localhost

重启容器环境变量失效

容器配置的环境变量重启时失效问题,导致需要手动重新source /etc/profile 解决方案如下:

  1. /etc/bashrc 中增加环境刷新命令 source /etc/profile
1
2
3
4
....
fi
# vim:ts=4:sw=4
source /etc/profile
  1. /root/.bashrc中添加source /etc/profile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

# 直接在这里新增上面提到的刷新代码
source /etc/profile


容器加载时会先从/root/.bashrc 中加载环境变量,而/root/.bashrc 实际调用的是/etc/bashrc,因此在/etc/bashrc 文件中加入刷新命令,可以使容器每次加载时都会自动刷新环境变量,因此解决重启环境变量失效的问题。并且不会因非root用户登录造成不可用

参考