|
| 1 | +--- |
| 2 | +title: Using USB/IP with Docker Desktop |
| 3 | +linkTitle: USB/IP support |
| 4 | +weight: 80 |
| 5 | +description: How to use USB/IP in Docker Desktop |
| 6 | +keywords: usb, usbip, docker desktop, macos, windows, linux |
| 7 | +toc_max: 3 |
| 8 | +aliases: |
| 9 | +- /desktop/usbip/ |
| 10 | +--- |
| 11 | + |
| 12 | +> [!NOTE] |
| 13 | +> |
| 14 | +> This guide applies to all Docker Desktop backends apart from WSL2. |
| 15 | +
|
| 16 | +This guide explains how to use USB/IP in Docker Desktop. USB/IP enables you to share USB devices over the network, which can then be accessed from within Docker containers. This guide will specifically focus on sharing USB devices connected to the machine you run Docker Desktop on. |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +- Docker Desktop version 4.35 or later installed and configured to use a backend other than WSL2 |
| 21 | + |
| 22 | +## Steps to Use USB/IP |
| 23 | + |
| 24 | +### 1. Run a USB/IP server |
| 25 | + |
| 26 | +To use USB/IP, you need to run a USB/IP server. For this guide, the implementation provided by [jiegec/usbip](https://github.com/jiegec/usbip) will be used. Follow these steps: |
| 27 | + |
| 28 | +1. Clone the repository: |
| 29 | + |
| 30 | + ```bash |
| 31 | + git clone https://github.com/jiegec/usbip |
| 32 | + cd usbip |
| 33 | + ``` |
| 34 | + |
| 35 | +2. Run the emulated HID (Human Interface Device) device example: |
| 36 | + |
| 37 | + ```bash |
| 38 | + env RUST_LOG=info cargo run --example hid_keyboard |
| 39 | + ``` |
| 40 | + |
| 41 | +### 2. Start a privileged Docker container |
| 42 | + |
| 43 | +To attach the USB device, start a privileged Docker container with the PID namespace set to `host`: |
| 44 | + |
| 45 | +```bash |
| 46 | +docker run --rm -it --privileged --pid=host alpine |
| 47 | +``` |
| 48 | + |
| 49 | +### 3. Enter the mount namespace of PID 1 |
| 50 | + |
| 51 | +Inside the container, enter the mount namespace of the `init` process to gain access to the pre-installed USB/IP tools: |
| 52 | + |
| 53 | +```bash |
| 54 | +nsenter -t 1 -m |
| 55 | +``` |
| 56 | + |
| 57 | +### 4. Use USB/IP tools |
| 58 | + |
| 59 | +Now you can use the USB/IP tools as you would on any other system. |
| 60 | + |
| 61 | +#### a. List USB devices |
| 62 | + |
| 63 | +To list exportable USB devices from the host: |
| 64 | + |
| 65 | +```bash |
| 66 | +usbip list -r host.docker.internal |
| 67 | +``` |
| 68 | + |
| 69 | +Expected output: |
| 70 | + |
| 71 | +```console |
| 72 | +Exportable USB devices |
| 73 | +====================== |
| 74 | + - host.docker.internal |
| 75 | + 0-0-0: unknown vendor : unknown product (0000:0000) |
| 76 | + : /sys/bus/0/0/0 |
| 77 | + : (Defined at Interface level) (00/00/00) |
| 78 | + : 0 - unknown class / unknown subclass / unknown protocol (03/00/00) |
| 79 | +``` |
| 80 | + |
| 81 | +#### b. Attach a USB device |
| 82 | + |
| 83 | +To attach a specific USB device, or the emulated keyboard in this case: |
| 84 | + |
| 85 | +```bash |
| 86 | +usbip attach -r host.docker.internal -d 0-0-0 |
| 87 | +``` |
| 88 | + |
| 89 | +#### c. Verify device attachment |
| 90 | + |
| 91 | +After attaching the emulated keyboard, check the `/dev/input` directory for the device node: |
| 92 | + |
| 93 | +```bash |
| 94 | +ls /dev/input/ |
| 95 | +``` |
| 96 | + |
| 97 | +Example output: |
| 98 | + |
| 99 | +```console |
| 100 | +event0 mice |
| 101 | +``` |
| 102 | + |
| 103 | +### 5. Use the attached device in another container |
| 104 | + |
| 105 | +While the initial container remains running (to keep the USB device operational), you can access the attached device in another container. For example: |
| 106 | + |
| 107 | +1. Start a new container with the attached device: |
| 108 | + |
| 109 | + ```bash |
| 110 | + docker run --rm -it --device "/dev/input/event0" alpine |
| 111 | + ``` |
| 112 | + |
| 113 | +2. Install a tool like `evtest` to test the emulated keyboard: |
| 114 | + |
| 115 | + ```bash |
| 116 | + apk add evtest |
| 117 | + evtest /dev/input/event0 |
| 118 | + ``` |
| 119 | + |
| 120 | +3. Interact with the device, and observe the output: |
| 121 | + |
| 122 | + Example output: |
| 123 | + |
| 124 | + ```console |
| 125 | + Input driver version is 1.0.1 |
| 126 | + Input device ID: bus 0x3 vendor 0x0 product 0x0 version 0x111 |
| 127 | + ... |
| 128 | + Properties: |
| 129 | + Testing ... (interrupt to exit) |
| 130 | + Event: time 1717575532.881540, type 4 (EV_MSC), code 4 (MSC_SCAN), value 7001e |
| 131 | + Event: time 1717575532.881540, type 1 (EV_KEY), code 2 (KEY_1), value 1 |
| 132 | + Event: time 1717575532.881540, -------------- SYN_REPORT ------------ |
| 133 | + ... |
| 134 | + ``` |
| 135 | + |
| 136 | +### Notes |
| 137 | + |
| 138 | +- The initial container must remain running to maintain the connection to the USB device. Exiting the container will stop the device from working. |
| 139 | +- You can repeat the process to attach and use additional USB devices as needed. |
| 140 | +- The Docker Desktop VM kernel image comes pre-configured with drivers for many common USB devices, but we can not guarantee every possible USB device will work with this setup. |
0 commit comments