DockerコンテナからPCと有線接続したAndroidスマホにADBコマンドを実行する方法

## 初めに

今回、DockerコンテナからadbコマンドでPCにUSBケーブルで接続しているスマホを操作する機能が必要でしたので、環境構築を行いました。

## 環境

- 必要
    - usbipd
    - Docker Desktop for Windows
    - Androidスマホ（デバッグモードをオンにできるもの）
    - Windows PC
　
- 試した環境
    - usbipd 4.3.0-70
    - Docker Desktop for Windows 4.30.0(仮想環境はWSL)
    - Android 14および15
    - Windows 11
    
## 本題
    
### DockerでPythonコンテナを建てる
    
自身のプロジェクトでは他のコンテナも必要なため、docker-composeを使って設定し、DockerfileでADBツールをPythonコンテナ内にインストールします。

docker-compose.yml
```Dockerfile
    version: '3'
    
     backend:
        build: .
        container_name: backend
        volumes:
          - ./opt:/opt # 任意
          - /dev/bus/usb:/dev/bus/usb  # USBデバイスへのアクセスに必要
        privileged: true # USBデバイスへのアクセスに必要
        tty: true # USBデバイスへのアクセスに必要
        stdin_open: true # USBデバイスへのアクセスに必要
        ports:
          - 5000:5000
        devices:
          - "/dev/bus/usb:/dev/bus/usb" # USBデバイスへのアクセスに必要
        environment:
          - ADB_SERVER_PORT=5037 
          - HOST_PATH=${HOST_PATH}
          - DB_HOST=db
          - DB_PORT=3306
          - DB_USER=${DB_USER}
          - DB_PASS=${DB_PASS}
          - ROOT_PASS=${ROOT_PASS}
```
Dockerfile
```Dockerfile
FROM python:3.11

# ADBをインストール
RUN apt-get update && apt-get install -y android-tools-adb &&  \
    apt install sqlite3
    
COPY /opt/requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

{省略}
```
コンテナを立ち上げます。    
```text
docker-compose up -d --build
```
### PCにusbipdをインストール（未インストールの場合のみ）
    
usbipdの使い方やインストール手順は、以下のMicrosoft公式ドキュメントを参照してください：
https://learn.microsoft.com/ja-jp/windows/wsl/connect-usb
    
以下は簡易的な手順です：

 1.管理者権限でPowershellを開き、以下のコマンドを実行します。  
```text
winget install --interactive --exact dorssel.usbipd-win
```

 2.インストール後、Powershellを再起動し、以下のコマンドでインストールが成功しているか確認します。

```text
usbipd --version
```

### スマホをDockerと接続する

1.開発者モードを有効にし、デバッグモードをオンにしたスマホをPCに接続します。

 - 開発者モードの有効化手順：https://developer.android.com/studio/debug/dev-options?hl=ja
 - スマホに表示されるUSB接続の許可ポップアップは忘れずに許可してください

2.usbipd list コマンドを実行し、接続するスマホの BUSID を確認します。
（例：Pixel 7aを接続）

```text
usbipd list
```

```text
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    18d1:4ee7  Pixel 7a                                                      Shared
1-6    5986:1198  Integrated Camera, Camera DFU Device                          Not shared
1-9    10a5:d805  FPC Fingerprint Reader                                        Not shared
1-10   8087:0033  インテル(R) ワイヤレス Bluetooth(R)                           Not shared
```

3.管理者権限で以下を実行し、スマホを共有可能にします。

※PC環境で接続デバイスをFlutterなどで接続している場合は -fをつけたほうがいいです。

```
usbipd bind --busid 1-1
```

WSL環境の場合、以下のコマンドでUSBデバイスを接続します。

```
usbipd attach --wsl --busid 1-1
```

Pythonコンテナ内に入り、以下を実行して接続を確認します。
Pixel 7aが確認できます！

```
adb devices -l
```

```text
List of devices attached
33021JEHN10712         device product:lynx model:Pixel_7a device:lynx transport_id:1
```

## 最後に

Dockerとスマホの接続は一見難しそうですが、意外とシンプルな手順で実現できました。
adb コマンドを使うことで、Pythonコンテナからスマホの写真を取得したり、データを送信したりといった操作が可能です。ぜひ活用してみてください。

---
間違いや改善点があればコメントいただけると嬉しいです！

## 参考

https://learn.microsoft.com/ja-jp/windows/wsl/connect-usb

https://www.baeldung.com/ops/docker-access-host-devices?utm_source=chatgpt.com

https://armadillo.atmark-techno.com/blog/10899/4191?utm_source=chatgpt.com