Dockerコンテナ内のUbuntuのD-Bus

Dockerコンテナ内のUbuntuのD-Bus

私はD-Busを使用して互いに通信する複数のバックグラウンドプロセスを実行するDockerイメージを構築しています。私のイメージはUbuntu Bionicに基づいています。システムはすでにDebian 9でデフォルトで実行されています。

コンテナ内でD-Busを動作させるにはどうすればよいですか?インターネット検索でいくつかのアイデアを見つけましたが、インターネット上の質問のほとんどは、コンテナとホストシステム間でDバスを使用することです。一方、コンテナ内で実行されているプロセスだけをリンクするだけです。これまでの最も成功した試みは、X11関連のエントリが欠落しているというエラーメッセージで失敗しました。これは現在X11がまったくインストールされていないためです。

コンテナ内で実行して接続するD-Busサービスの例:

#!/usr/bin/env python

import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import sys

service_name = "com.testservice"
object_path = "/testservice"
interface_name = service_name

class SomeObject(dbus.service.Object):

    def __init__(self, bus, object_path):
        dbus.service.Object.__init__(self, bus, object_path)
    
    @dbus.service.method(service_name, in_signature='', out_signature='')
    def Exit(self):
        mainloop.quit()


if __name__ == '__main__':
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)

    session_bus = dbus.SessionBus()
    name = dbus.service.BusName(service_name, session_bus)
    object = SomeObject(session_bus, object_path)

    mainloop = gobject.MainLoop()
    mainloop.run()

現在のサービスを開始しようとすると、次の出力が提供されます。

Traceback (most recent call last):
  File "/hostwork/dbus-test.py", line 35, in <module>
    session_bus = dbus.SessionBus()
  File "/usr/lib/python2.7/dist-packages/dbus/_dbus.py", line 211, in __new__
    mainloop=mainloop)
  File "/usr/lib/python2.7/dist-packages/dbus/_dbus.py", line 100, in __new__
    bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
  File "/usr/lib/python2.7/dist-packages/dbus/bus.py", line 122, in __new__
    bus = cls._new_for_bus(address_or_type, mainloop=mainloop)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11

答え1

私は自分で解決策を見つけました。

私はDockerfileにdbusパッケージをインストールしましたが、X11には関係ありません。また、質問で共有したPythonスクリプトの依存関係を含む、私のソフトウェアのすべての依存関係をインストールしました。

私のDockerfileには次の行があります。

COPY start.sh /usr/local/bin
RUN chmod +x /usr/local/bin/start.sh
ENTRYPOINT ["/bin/bash", "/usr/local/bin/start.sh"]

start.shの内容は次のとおりです。

#!/usr/bin/env bash

export DBUS_SESSION_BUS_ADDRESS=`dbus-daemon --fork --config-file=/usr/share/dbus-1/session.conf --print-address`

exec bash

このようにコンテナを実行すると、DBUS_SESSION_BUS_ADDRESS が適切に設定されたシェルが提供されます。バックグラウンドでテストスクリプトを実行し、次のように話すことができます。

dbus-send --print-reply --session --dest=com.testservice /testservice com.testservice.Exit

殺す。

関連情報