私は、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
!