我正在创建两个应用程序,主应用程序和从应用程序,它们通过 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");
主应用程序现在可以向从应用程序发送消息。不过,我还没有尝试从从站向主站发送消息。
答案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
有效!