問題

私はラズベリーパイ上で実行されることを意図したPythonアプリケーションを持っています。私はそれを設定するためのdocker-composeファイルを作成しました。私のエントリポイントは、次のようなホスト上のさまざまなものをチェックするシェルスクリプトです。

  1. /boot/config.txtにアクセスして書き込むことで、SPIが有効になっていることを確認します。
  2. ワッチドッグ・サービスのインストールと有効にします。
  3. 再起動時にdockerコンテナを/etc/rc.localに書き込むことで自動的に実行します(これをrestart:alwaysまたはunless-stoppedフラグをdocker-composeファイルから置き換えることを検討しています)

問題は、SPIを有効にすると、ラズベリーパイが再起動してセットアップする必要があることです(理由はよくわかりません)が、シェルスクリプトがdockerコンテナ内からsudo rebootコマンドに達すると、次のエラーが表示されます。

  Failed to connect to bus: No such file or directory
 Failed to talk to init daemon.
 

dockerコンテナ内でdbusとinitデーモンを見つけようとしている可能性がありますが、存在しないことを理解しています。これらのリソースにコンテナアクセスを許可するにはどうすればよいですか?別のボリュームをマウントする必要がありますか?これは私のdocker-compose.ymlファイルです:

 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
 

ゲーリーは、次のようなエントリポイントdocker-entrypoint.shを持つ私のPythonアプリケーションです:

 #!/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 "
SPI 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       
 

特権オプションはすでにGPIOへのコンテナアクセスを提供していますが、再起動にもアクセスできると思いましたが、そうではないようです。再起動できるようにするために必要なことを教えてください。

  ベストアンサー

私の最初の推測は、次のように/run/dbus/run/systemdをコンテナに公開するだけです。

 docker run -v /run/dbus:/run/dbus -v /run/systemd:/run/systemd ...
 

しかし、それは必要ですが、十分ではありません。これらの2つのバインドマウントだけで、コンテナ内からホストsystemdと対話しようとすると、次のようになります。

 [[email protected] /]# reboot
Failed to connect to bus: No data available
Failed to talk to init daemon.
 

これが機能するためには、コンテナがホストのグローバルPID名前空間で実行されていなければならないことが判明しました。

 docker run -v /run/dbus:/run/dbus -v /run/systemd:/run/systemd --pid=host ...
 

これを実行すると、コンテナ内で reboot を実行すると、ホストが正常に再起動します。

docker-compose.ymlでは、次のようになります。

 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
 

  同じタグがついた質問を見る

linuxdockerraspberry-pidocker-compose