Docker 容器内 Ubuntu 上的 D-Bus

Docker 容器内 Ubuntu 上的 D-Bus

我正在构建一个 Docker 映像,用于运行一堆使用 D-Bus 相互通信的后台进程。我的图像基于 Ubuntu Bionic。该系统已经可以在本机 Debian 9 上运行。

我需要做什么才能使 D-Bus 在容器内工作?我通过谷歌搜索找到了一些想法,但互联网上的大多数问题都是关于在容器和主机之间使用D-Bus,而我只需要连接容器内运行的进程。到目前为止,我最成功的尝试都失败了,错误消息表明缺少与 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 的 shell。我可以运行测试脚本后台并说

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

杀死它。

相关内容