Get Raspi's CPU temperature within Docker container

I’ve build a little ASP.NET Core application for my Raspberry Pi 4 which lets me control a fan (see here). The app is deployed as a small self-contained Linux application running on bare metal of my Raspi.

For measuring the temperature, I’m calling vcgencmd measure_temp on the Raspi which gives me the actual temperature.

For various reasons, I’d prefer to run this app within a Docker container:

  • No more manual service registration within Linux, Docker feature --restart-always handles this.
  • No more downloading the latest release from GitHub, extracting and marking the app as executable.

But I have no clue how I can retrieve the Raspi’s temperature from within a container.

I already tried to map the Raspi’s directory /usr/bin/ and /opt/vc/bin/ into a Docker container and call vcgencmd from inside – but that simply fails due to missing dependencies.
And I already found an answer on Stack Overflow suggesting to create a named pipe on the Raspi and then consume this pipe from within the container. But this removes the beauty of a container if I have to setup something like a named pipe.

So long story short: is there any way to get the Raspi’s current CPU temperature from within a Docker container?

Thx!

Asked By: mu88

||

If we just mount /opt/vc inside a container…

docker run -it --rm -v /opt/vc:/opt/vc debian:stretch /opt/vc/bin/vcgencmd measure_temp

…it fails with:

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

Where do we find libvchiq_arm.so? We can use ldd to find out:

$ ldd /opt/vc/bin/vcgencmd
        linux-vdso.so.1 (0x7efe7000)
        /usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76f79000)
        libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x76f52000)
        libvcos.so => /opt/vc/lib/libvcos.so (0x76f39000)
        libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76f0f000)
        libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76efc000)
        librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x76ee5000)
        libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76d97000)
        /lib/ld-linux-armhf.so.3 (0x76f8e000)

This shows us that vcgencmd wants two libraries that can be found in /opt/vc/lib. These are available in the container, but the container environment doesn’t know to look for them in /opt/vc/lib. We can fix that by setting LD_LIBRARY_PATH:

docker run -it --rm -v /opt/vc:/opt/vc -e LD_LIBRARY_PATH=/opt/vc/lib debian:stretch /opt/vc/bin/vcgencmd measure_temp

Which fails with:

VCHI initialization failed

Great, we’ve solved the missing library problem! I suspect that vcgencmd is looking for a device that isn’t available in the container. We can figure out what that is by running vcgencmd on the host under the control of strace:

strace -o /tmp/trace  -f -s 80 /opt/vc/bin/vcgencmd measure_temp

Now we look for /dev in /tmp/trace, and we find:

6868  openat(AT_FDCWD, "/dev/vchiq", O_RDWR|O_LARGEFILE) = 3

So we need to expose /dev/vchiq inside the container. We can do that with the --device option:

docker run -it --rm -v /opt:/opt -e LD_LIBRARY_PATH=/opt/vc/lib --device /dev/vchiq debian:stretch /opt/vc/bin/vcgencmd measure_temp

Which now reports:

temp=69.3'C

We have successfully run vcgencmd inside a container.

Answered By: larsks

The answer by @larsks, is great. However, now in the RaspberryPI 4 with Debian 11 (bulleye) aarch64, they have placed vcgencmd from /opt/vc/bin/vcgencmd to /usr/bin/vcgencmd. In consequence, here is the updated version of mu88 solution:

docker run -it --rm -v /usr:/usr -e LD_LIBRARY_PATH=/usr/lib --device /dev/vchiq debian:stretch /usr/bin/vcgencmd measure_temp
Answered By: Raziel Amador Ríos
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.