7

I successfully dockerized my nodejs app running on a Beaglebone black. But now I'd like to access to the CAN from within the docker container but it doesn't work.

Note that I successfully configured the CAN ports in the host and candump shows it works.

$ candump can1
  can1  18FF30D0   [8]  00 00 00 00 00 00 00 00
  can1  18FF02D0   [4]  00 00 00 00
  can1  18FF21D0   [3]  00 00 00
  can1  18FF3CD0   [4]  00 7D 28 7D
  can1  18FF30D0   [8]  00 03 00 00 00 00 00 00
  can1  18FF02D0   [4]  00 00 00 00

I build socketcan node module in my Dockerfile as follows:

 #If you don't have node/npm already, add that first
RUN apk add --no-cache nodejs

# Add the necessary build and runtime dependencies (see https://stackoverflow.com/questions/36202095/node-serialport-failing-on-alpine-linux)
RUN apk add --no-cache make gcc g++ python3 linux-headers udev

#RUN apk add --no-cache --virtual .gyp python3 make g++
RUN  npm install 

Once I run my app from the container, I get the following exception:

 -- -  Canbus:can0: switched to channel "can0"…
Pepsr v2.1.192 5:36:40 PM  [pepsr-iingenierie]  -- -  Canbus:can0: cancel CAN as other channel "can0" doesn’t work either
Pepsr v2.1.192 5:36:40 PM  [pepsr-iingenierie]  -- -  Canbus:can0: Error: Error while creating channel
    at Object.exports.createRawChannel (/home/debian/Desktop/devel/iot/node_modules/socketcan/socketcan.js:38:12)
    at Canbus._connect (/home/debian/Desktop/devel/iot/pepsr.ddk.protocol.canBus.js:308:34)
    at Canbus.connect (/home/debian/Desktop/devel/iot/pepsr.module.js:272:9)
    at Object.<anonymous> (/home/debian/Desktop/devel/iot/pepsr.js:608:20)
    at Module._compile (internal/modules/cjs/loader.js:1015:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1035:10)
    at Module.load (internal/modules/cjs/loader.js:879:32)
    at Function.Module._load (internal/modules/cjs/loader.js:724:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)
    at internal/main/run_main_module.js:17:47 
Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95

2 Answers2

4

Thanks to the contributors who led me to a solution.

I finally found that the easiest way to let the container access to the host CAN bus is to use the --network parameter as follows:

$ docker run --rm --network=host <your image>
Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95
1

Forwarding network interfaces to Docker is more or less described here: Sharing virtual network with docker container

Tarmo
  • 3,728
  • 1
  • 8
  • 25
  • Got it. But… i have no idea how to find the /dev/canx equivalent on my debian host running on a Beaglebone black witht the cape comm2. Any idea? – Stéphane de Luca Sep 08 '21 at 13:48
  • 1
    The beaglebone CAN shield is a network device. You can find it using ifconfig. – Shabbir Hussain Sep 08 '21 at 14:02
  • 1
    Ah, sorry - I didn't know it's a network interface. In this case it's a bit more involved. See https://stackoverflow.com/questions/63019226/sharing-virtual-network-with-docker-container – Tarmo Sep 08 '21 at 14:07
  • I see can1 with the ifconfig but how should I do to provide an absolute path to can1 as requested by --device? (/dev/can1 does not exist) – Stéphane de Luca Sep 08 '21 at 14:10
  • 1
    Disregard my earlier answer, it applies only to device files. Network interfaces don't work that way. Check the link I pasted. – Tarmo Sep 08 '21 at 14:11