DEV Community

Cover image for Running adb in a rootless Podman Distrobox container
Archer Allstars
Archer Allstars

Posted on • Edited on

Running adb in a rootless Podman Distrobox container

adb stands for Android Debug Bridge. It's a part of SDK Platform Tools, which is bundled with Android Studio.

For Linux users, they might want to use adb with scrcpy (https://github.com/Genymobile/scrcpy), which is a very powerful tool for controlling Android devices from PC. Installing scrcpy from the distro's repo would bring in adb by default, so it's not necessary to download adb directly from Google.

Why would anyone use adb in a container?

Like most apps that anyone would want to run in a container:

  • It doesn't pile up your system with a ton of packages/dependencies.
  • You always get the latest official release of apps, regardless of your Linux distro.
  • You can easily delete all the app data and its configurations.
  • It works with immutable OSes very well.
  • Minimizing the apps' system access through a rootless environment.
  • Maybe more. 😎

Note, Distrobox gives you a convenient over raw Podman/Docker setup, and it also integrates very well in the system. But if you want the absolute security, please consider setting up a rootless Podman container without using Distrobox. However, I will go with Distrobox, as I think a rootless Distrobox container already gives you a sane amount of security-convenient ratio.

👉️ Table of contents:

  1. Know Your Device
  2. udev Rules Setup on the Host
  3. Preparing the Container
  4. Testing adb
  5. Automatically Update the Container

1. Know Your Device

You can identify your device easily with:

lsusb
Enter fullscreen mode Exit fullscreen mode

It will list all USB related devices. Look for a line that's corresponding to your Android device. For example:

Bus 001 Device 009: ID 1234:5678 Google Inc. Nexus/Pixel Device (charging + debug)
Enter fullscreen mode Exit fullscreen mode

The important part is your device ID, which is 1234:5678 in this example. We'll use this ID in the next step.


2. udev Rules Setup on the Host

In /etc/udev/rules.d/51-android.rules I put:

SUBSYSTEM=="usb", ATTR{idVendor}=="1234", ATTRS{idProduct}=="5678", MODE="0666", GROUP="yourusername"
Enter fullscreen mode Exit fullscreen mode
  • If yours doesn't have 51-android.rules in /etc/udev/rules.d/, please create a new one.
  • Replace ATTR{idVendor}=="1234" and ATTRS{idProduct}=="5678" with your real device ID.
  • Replace yourusername with your real username.

3. Preparing the Container

3.1. Install Distrobox and Podman on the Host

For example, on openSUSE Tumbleweed:

sudo zypper install distrobox podman
Enter fullscreen mode Exit fullscreen mode

3.2. Configure Distrobox to use Podman

echo 'container_manager="podman"' > ~/.config/distrobox/distrobox.conf
Enter fullscreen mode Exit fullscreen mode

3.3. Create a New Distrobox Container for adb

distrobox create -i docker.io/library/archlinux:latest -n adb-dbx -H ~/distrobox/adb-dbx --volume /dev/bus/usb/:/dev/bus/usb --volume /etc/udev/rules.d/:/etc/udev/rules.d --additional-packages "adwaita-cursors" 
Enter fullscreen mode Exit fullscreen mode

I use Arch container image because:

  • It's a rolling image, so every necessary package or dependency would always be updated.
  • It really depends on your needs. If you plan to use this container with scrcpy, the best container for adb would be Arch, since you will get all the codecs from the main repo. If you plan to use this container as a dev box, Tumbleweed image would be better because Chrome is not available officially on Arch. But if you only want to run adb, the container image wouldn't matter much.

I volume /dev/bus/usb/ and /etc/udev/rules.d/ in the container because they're needed for adb to work.


4. Testing adb

adb devices
Enter fullscreen mode Exit fullscreen mode

This should return your device properly. If it's not, please check whether you have adb process already running in the background. In that case, please end the process first.


5. Automatically Update the Container

We can use systemd's service and timer to update/upgrade all Distrobox's containers like this:

dbx-upgrade.service

[Unit]
Description=Upgrade all rootless Distrobox containers.
RequiresMountsFor=/run/user/1000/containers

[Service]
Type=exec
ExecStart=-bash -c "distrobox-upgrade --all"
Restart=on-failure
RestartSec=60
TimeoutStopSec=5min
RemainAfterExit=yes
Enter fullscreen mode Exit fullscreen mode

Save this file as ~/.config/systemd/user/dbx-upgrade.service.

dbx-upgrade.timer

[Unit]
Description=Run distrobox-upgrade --all daily.

[Timer]
OnCalendar=daily
RandomizedDelaySec=5min
Persistent=true

[Install]
WantedBy=timers.target
Enter fullscreen mode Exit fullscreen mode

Save this file as ~/.config/systemd/user/dbx-upgrade.timer.

Enable the Timer

systemctl --user daemon-reload && systemctl --user enable dbx-upgrade.timer
Enter fullscreen mode Exit fullscreen mode

Cover Photo by Edho Fitrah on Unsplash

Top comments (0)