Reputation: 925
I have a python application that's meant to be run on a raspberry pi. I've created a docker-compose file to set it up, and my entry point happens to be a shell script that checks various things on the host such as:
The problem is, if I enable SPI, the raspberry pi needs to reboot to set it up (not quite sure why), but when my shell script reaches the sudo reboot command from within the docker container, I get the following error:
Failed to connect to bus: No such file or directory
Failed to talk to init daemon.
I understand that it's probably trying to find dbus and the init daemon within the docker container but they don't exist. How do I give my container access to these resources? Do I need to mount another volume? This is my docker-compose.yml file:
version: "3"
services:
mongoDB:
restart: unless-stopped
volumes:
- "/data/db:/data/db"
ports:
- "27017:27017"
- "28017:28017"
image: "andresvidal/rpi3-mongodb3:latest"
mosquitto:
restart: unless-stopped
ports:
- "1883:1883"
image: "mjenz/rpi-mosquitto"
FG:
privileged: true
network_mode: "host"
depends_on:
- "mosquitto"
- "mongoDB"
volumes:
- "/home/pi:/home/pi"
- "/boot:/boot"
#image: "arkfreestyle/fg:v1.8"
image: "test:latest"
entrypoint: /app/docker-entrypoint.sh
restart: unless-stopped
FG is my python application with the entry point docker-entrypoint.sh which looks like:
#!/bin/sh
if [ ! -f /home/pi/.initialized ]; then
echo "Initializing..."
# Turn spi on
if grep -Fxq "dtparam=spi=on
dtparam=watchdog=on" /boot/config.txt
then
echo "\nSPI is already enabled"
echo "Creating .initialized"
# Create .initialized hidden file
touch /home/pi/.initialized
echo "Starting application..."
sudo python3 __main__.py -debug
else
### Enable SPI ###
fi
fi
### Create .initialized file ###
echo "Rebooting in ten seconds..."
sleep 10
sudo reboot # This line results in the error
else
echo "Initialized already!"
sudo python3 __main__.py -debug
fi
The privileged option already gives my container access to the GPIO, I imagined it would give me access to reboot as well, however it seems that is not the case. Please let me know what I need to do to be able to reboot.
Upvotes: 4
Views: 4897
Reputation: 311526
My first guess is that you simply need to expose /run/dbus
and /run/systemd
to your container, as in:
docker run -v /run/dbus:/run/dbus -v /run/systemd:/run/systemd ...
But while that is necessary, it isn't sufficient; with just those two bind mounts, attempting to interact with the host systemd from inside the container results in:
[root@631fff40f09c /]# reboot
Failed to connect to bus: No data available
Failed to talk to init daemon.
It turns out that the in order for this to work, the container must be running in the host's global PID namespace, which means we need:
docker run -v /run/dbus:/run/dbus -v /run/systemd:/run/systemd --pid=host ...
With this in place, running reboot
inside the container successfully reboots the host.
In a docker-compose.yml
, that would look something like:
FG:
privileged: true
network_mode: "host"
pid: "host"
depends_on:
- "mosquitto"
- "mongoDB"
volumes:
- "/home/pi:/home/pi"
- "/boot:/boot"
- "/run/dbus:/run/dbus"
- "/run/systemd:/run/systemd"
image: "test:latest"
entrypoint: /app/docker-entrypoint.sh
restart: unless-stopped
Upvotes: 6