设置 docker 容器通过 d-bus 与主机通信

设置 docker 容器通过 d-bus 与主机通信

我正在创建两个应用程序,主应用程序和从应用程序,它们通过 d-bus 进行通信。我的应用程序在同一主机上运行时按预期工作。
现在我想将从属应用程序移动到 docker 容器,但在主机和容器之间共享 d-bus 会话时遇到问题。这是我的 Dockerfile:

从 i386/ubuntu:16.04

音量/运行/用户/1000/
ENV DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus

运行 apt-get update
运行 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:abstract=/tmp/dbus-iXrYzptYOX,guid=78a790f0f6a4387a39ac3d505da478a3
我的应用程序无法通信。

如果我将 dbus.conf 添加到容器中的 /etc/dbus-1/session.d/ 并覆盖

 <listen>unix:path=/run/user/1000/bus</listen> 
我收到消息“无法启动消息总线:无法绑定套接字“/run/user/1000/bus”:地址已在使用中”

我不确定我是否应该在 docker 内启动 dbus-daemon。
我怎样才能做到这一点?

答案1

我找到了解决方案。这是我的 Dockerfile:

从 i386/ubuntu:16.04

运行 apt-get update
运行 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:主机=${containerIp},端口=6667,family=ipv4

在我的主应用程序中,我启动一个连接(我使用 Qt):

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

主应用程序现在可以向从应用程序发送消息。不过,我还没有尝试从从站向主站发送消息。

答案摘自这篇文章: https://stackoverflow.com/a/45487266/6509266

答案2

我能够得到一个集装箱化的安装 Spotify 以使用以下命令获取主机 DBus(在 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 是重要的位)

我是为 libnotify 这样做的 - 所以我需要确保安装了 libnotify-bin 软件包(或者任何notify-send在系统上为您提供命令的东西)

然后做一个docker-compose up并检查是否notify-send hello有效!

相关内容