6

I've been trying out my Node.js app on a Raspberry Pi 3 Model B using Docker and it runs without any troubles.

The problem comes when an app dependency (raspicam) requires raspistill to make use of the camera to take a photo. Raspberry is running Debian Stretch and the pi camera is configured and tested. But I cant access it when running the app via Docker.

Basically, I build the image with Docker Desktop on a win10 64bit machine using this Dockerfile:

FROM arm32v7/node:10.15.1-stretch

ENV PATH /opt/vc/bin:/opt/vc/lib:$PATH

RUN echo "/opt/vc/lib" > /etc/ld.so.conf.d/00-vcms.conf \
    && ldconfig

# Create the app directory
ENV APP_DIR /home/app
RUN mkdir $APP_DIR
WORKDIR $APP_DIR

# Copy both package.json and package-lock.json
COPY package*.json ./

# Install app dependencies
RUN npm install

# Bundle app source
COPY . .

EXPOSE 3000

CMD ["npm", "start"]

Then in the Raspberry, if I pull the image and run it with:

docker run --privileged --device=/dev/vchiq -p 3000:3000 [my/image:latest]

I get:

Error: spawn /opt/vc/bin/raspistill ENOENT

After some researching, I also tried running with:

docker run --privileged -v=/opt/vc/bin:/opt/vc/bin --device=/dev/vchiq -p 3000:3000 [my/image:latest]

And with that command, I get:

stderr: /opt/vc/bin/raspistill: error while loading shared libraries: libmmal_core.so: cannot open shared object file: No such file or directory

Can someone share some thoughts on what changes do I have to make to the Dockerfile so that I'm able to access the pi camera from inside the Docker container? Thanks in advance.

pgrodrigues
  • 2,083
  • 1
  • 24
  • 28
  • If you need to run a `--privileged` container with access to host devices and host binaries, it will be easier and no less safe to not use Docker at all. The `/opt/vc` tree is empty in your Docker image and when you run `ldconfig` it has no effect. – David Maze Feb 23 '19 at 17:21
  • @DavidMaze I only run with `--privileged` because I couldn't find another way to access GPIO, not even with `--device=/dev/gpiomem`. – pgrodrigues Feb 24 '19 at 18:43
  • Where is this file `/opt/vc/bin/raspistill` supposed to be? Is it already in your Raspberry or do you want to take this file from inside the image to the Raspberry folder using volumes? – Manish Dash Feb 27 '19 at 09:40
  • @ManishDash on my Raspberry I have access to that directory and raspistill is there. – pgrodrigues Feb 27 '19 at 20:20
  • @user3632710 Did you solve it? – Anton Bärwald Mar 07 '19 at 13:34
  • @AntonBärwald, I still have to try using the rpi-raspbian image from balena. I plan to do so this weekend following this tutorial: https://www.balena.io/docs/learn/getting-started/raspberrypi3/nodejs/ . The plan was to build a simple Dockerfile myself with only the stuff needed to run the app on raspbian but I'm already spending too much time on this research so I'll just try out balena. – pgrodrigues Mar 07 '19 at 20:31

2 Answers2

1

Try replace this from the Dockerfile:

RUN echo "/opt/vc/lib" > /etc/ld.so.conf.d/00-vcms.conf \
&& ldconfig

With the following:

ADD 00-vmcs.conf /etc/ld.so.conf.d/
RUN ldconfig

And create the file 00-vmcs.conf:

/opt/vc/lib

Edit:

If it still doesn't work, try loading a Raspbian Docker image for example balenalib/rpi-raspbian:

FROM balenalib/rpi-raspbian
Anton Bärwald
  • 798
  • 1
  • 6
  • 15
1

I've had the same problem trying to work with camera interface from docker container. With suggestions in this thread I've managed to get it working with the below dockerfile.

FROM node:12.12.0-buster-slim

EXPOSE 3000

ENV PATH="$PATH:/opt/vc/bin"

RUN echo "/opt/vc/lib" > /etc/ld.so.conf.d/00-vcms.conf

COPY "node_modules" "/usr/src/app/node_modules"
COPY "dist" "/usr/src/app"

CMD ldconfig && node /usr/src/app/app.js

There are 3 main points here:

  1. Add /opt/vc/bin to your PATH so that you can call raspistill without referencing the full path.
  2. Add /opt/vc/lib to your config file so that raspistill can find all dependencies it needs.
  3. Reload config file (ldconfig) during container's runtime rather than build-time.

The last point is the main reason why Anton's solution didn't work. ldconfig needs to be executed in a running container so either use similar approach to mine or go with entrypoint.sh file instead.

Miczi
  • 136
  • 1
  • 6