d-busを介してホストと通信するようにDockerコンテナを設定します。

d-busを介してホストと通信するようにDockerコンテナを設定します。

私は、d-busを介して通信するマスターとスレーブラは、2つのアプリケーションを作成しています。私のアプリケーションが同じホスト上で実行されたときに期待どおりに動作します。
これで、スレーブアプリケーションをドッカーコンテナに移動したいのですが、ホストとコンテナ間でd-busセッションを共有するのに問題があります。これは私のDockerfileです。

i386/ubuntu:16.04から

ボリューム/実行/ユーザー/1000/
ENV DBUS_SESSION_BUS_ADDRESS=unix:パス=/run/user/1000/bus

apt-get アップデートの実行
apt-getアップグレード-yの実行
apt-get install -y dbusの実行

#RUN apt-get install -y libnotify-bin
#RUN apt-get install -y dbus-x11

adduser -u 1000 myuserの実行

#dbus.conf /etc/dbus-1/session.d/コピー

ユーザー 1000:1000
エントリポイント ["dbus-daemon", "--session", "--print-address"]

/run/user/1000/bus は私の DBUS_SESSION_BUS_ADDRESS 変数の値です。

コンテナを作る

docker create --mount type=bind,source=/run/user/1000/bus,target=/run/user/1000/bus mycontainer

/run/user/1000/bus はコンテナ内に表示されますが、コンテナが起動するとアドレスが印刷されます。

Unix:抽象=/tmp/dbus-iXrYzptYOX,guid=78a790f0f6a4387a39ac3d505da478a3
私のアプリケーションは通信できません。

コンテナの/etc/dbus-1/session.d/にdbus.confを追加して上書きする

 <listen>unix:path=/run/user/1000/bus</listen> 
「メッセージバスを開始できませんでした: '/run/user/1000/bus'ソケットをバインドできませんでした:アドレスはすでに使用中です。」というメッセージが表示されます。

docker内でdbus-daemonを起動する必要があるかどうかはわかりません。
どうすればいいですか?

答え1

解決策が見つかりました。これは私のDockerfileです。

i386/ubuntu:16.04から

apt-get アップデートの実行
apt-getアップグレード-yの実行
apt-get install -y dbusの実行

dbus.conf /etc/dbus-1/session.d/ コピー

ENTRYPOINT ["dbus-run-session", "slaveApp"]

そして私のdbus.conf:

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
    "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<busconfig>
    <listen>tcp:host=localhost,bind=*,port=6667,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    <auth>ANONYMOUS</auth>
    <allow_anonymous/>
</busconfig>

そして、ホストシステムでアドレス変数を設定します。

DBUS_SESSION_BUS_ADDRESS=tcp:host=${containerIp}, ポート=6667,family=ipv4 エクスポート

マイメインアプリケーションで接続を開始します(Qtを使用)。

QDBusConnection::connectToBus("tcp:host=${containerIp},port=6667", "qt_default_session_bus");

マスターアプリケーションはスレーブアプリケーションにメッセージを送信できるようになりました。しかし、まだスレーブからマスターにメッセージを送信しようとしたことはありません。

回答は次の記事からもたらされました。 https://stackoverflow.com/a/45487266/6509266

答え2

私は1つ得ることができますコンテナ化次のコマンドを使用してホストDBusを取得するには、Spotifyをインストールします(Ubuntuから)。

pkexec systemd-nspawn \
  --setenv=DISPLAY=unix$DISPLAY \
  --setenv=PULSE_SERVER=unix:/run/user/1000/pulse/native \
  --setenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
  --bind-ro /tmp/.X11-unix \
  --bind /run/user/1000 \
  --bind-ro /run/user/1000/bus \
  --bind /dev/snd \
  -u spotify \
  -M spotify \
  spotify

DBUS_SESSION_BUS_ADDRESSしたがって、ここで重要なのは、コンテナにホストバインディングがインストールされていることを確認し、同じ変数を同じ値にエクスポートすることです。コンテナにDBusもインストールしましたが、ブートイメージがなく、Spotifyだけを実行していることを考えると、そうする必要はありません。

答え3

私はアクセスしたいdocker-compose.ymlサービスに次のものを統合する必要がありました。

    environment:
      - DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
      - DISPLAY=:0

    security_opt:
      - apparmor:unconfined

    volumes:
      - /run/user/1000/bus:/run/user/1000/bus
      - /tmp/.X11-unix:/tmp/.X11-unix

(X11ビットが必要かどうかわかりません。dbusセッションバスアドレスとsecurity_optが重要なビットです。)

notify-send私はlibnotifyのためにこれをやっています。したがって、libnotify-binパッケージ(またはシステムにコマンドを提供するパッケージ)がインストールされていることを確認する必要があります。

次に、1つを作成して動作することをdocker-compose up確認してくださいnotify-send hello

関連情報