Search code examples
node.jsdockerubuntunode-serialport

Is it possible to use npm serialPort from within a docker container?


I have a node project, running in a docker container from ubuntu, and the host machine is also ubuntu.

In my node project (written in typescript), I'm trying to use the npm serialport library.

https://www.npmjs.com/package/serialport

I have the lines:

include * as serialport from 'serialport'

// further down

serialport.list((err, list) => {

    // after checking for errors
    console.log(list);

});

Now if I just run this code on the host machine, I get a list of results with plenty of information. For example, for one device:

{ manufacturer: 'Prolific Technology Inc.',
serialNumber: undefined,
pnpId: 'usb-Prolific_Technology_Inc._USB-Serial_Controller-if00-port0',
locationId: undefined,
vendorId: '067b',
productId: '2303',
comName: '/dev/ttyUSB0' }

But when I run the same code in a docker container, I get the following:

{ manufacturer: undefined,
 serialNumber: undefined,
 pnpId: undefined,
 locationId: undefined,
 vendorId: undefined,
 productId: undefined,
 comName: '/dev/ttyUSB0' }

As you can see, most of the information returns as undefined.

This is done giving the docker container privileged status and access to the /dev volume. For example in docker-compose

myapp:
 image: myappimage
 ports: 8999:8999
 volumes:
   - /dev:/dev
   - ./:/myappdir
 privileged: true
 command: ./scripts/runApp.sh

Or running

docker run --privileged -v /dev:/dev -v /path/to/my/app:/app node:4.4.0 ./scripts/runApp.sh

The application runs, and detects what serial ports are available at /dev, but the device information is not retrieved.

This link:

Docker container can't see a serial port device

Suggests that it might not even be possible to do this, at least not for mac. Is it possible on a linux machine?

Any help would be greatly appreciated.


Solution

  • Just in case anybody else has the same issue, I'll post the solution I found here:

    Digging into the linux bindings for node serialport, I saw that 'udevadm info -e' is used to get all the devices. Running that command within the container gave less information than on the host, but this is what gave me the googleable information I needed to find this page:

    udevadm does not show all attributes inside a docker container

    That one page gave me two solutions! First, to use /run/udev:/run/udev:ro in the volumes section to serialport to work, and then to use network_mode:'host' to detect changes when devices are plugged in (I use node usb-detection for that).

    So in my docker-compose file I now have:

    myapp:
      image: myappimage
      ports: 8999:8999
      network_mode: "host"
      volumes:
        - /dev:/dev
        - ./:/myappdir
        - /run/udev:/run/udev:ro
      privileged: true
      command: ./scripts/runApp.sh