如何在Docker中运行QT GUI应用并显示到Ubuntu主机?
容器化Qt GUI应用并在Ubuntu主机显示的问题解决
问题背景
尝试将基于Qt的带窗口界面应用容器化,在Ubuntu主机显示,当前操作步骤如下:
Dockerfile内容
# syntax=docker/dockerfile:1 FROM ubuntu:xenial-20210804 WORKDIR /app COPY . . RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt update && apt install software-properties-common -y && \ apt-add-repository ppa:beineri/opt-qt591-xenial RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ --mount=type=cache,target=/var/lib/apt,sharing=locked \ apt update && \ apt-get install git cmake qtbase5-dev qtdeclarative5-dev qt59multimedia qt59quickcontrols \ qt59imageformats qt59quickcontrols2 qt59script libfftw3-dev libsamplerate0-dev \ libasound2-dev libmpv-dev libdrm-dev libgl1-mesa-dev portaudio19-dev autoconf libtool xvfb -y RUN mkdir build && cd build RUN git clone https://github.com/thestk/rtmidi # build & install RUN cd rtmidi && git checkout 88e53b9 && ./autogen.sh && make && make install SHELL ["/bin/bash", "-c"] RUN cd /app/build && cmake .. -DCMAKE_PREFIX_PATH=/opt/qt59/ && make -j8 # RUN rm /usr/lib/x86_64-linux-gnu/libGL.so && ldconfig # RUN Xvfb :2 -screen 0 1024x768x16 & ENTRYPOINT [ "/app/build/appname"] # This binary launches the app. # -- Below this line is things I've tried without success # ENV DISPLAY=:1 # RUN groupadd -g 1000 myuser # RUN useradd -d /home/myuser -s /bin/bash -m myuser -u 1000 -g 1000 # USER myuser # ENV HOME /home/myuser
构建与运行命令
构建镜像:
sudo docker build -t app_img .
第一次运行命令:
sudo docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" -e DISPLAY=$DISPLAY --net=host app_img
出现错误:
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root' libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast Could not initialize GLX
第二次尝试运行命令:
sudo docker run --volume="$HOME/.Xauthority:/root/.Xauthority:rw" --net=host rad_lib
出现错误:
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root' QXcbConnection: Could not connect to display
解决建议
1. 完善X11权限与环境变量配置
- 运行容器时,除挂载
.Xauthority和传递DISPLAY,需添加X11 socket挂载并设置XDG_RUNTIME_DIR:sudo docker run \ --volume="$HOME/.Xauthority:/root/.Xauthority:rw" \ --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ --volume="/run/user/$(id -u)/:/run/user/$(id -u)/:rw" \ -e DISPLAY=$DISPLAY \ -e XDG_RUNTIME_DIR=/run/user/$(id -u) \ --net=host \ app_img - 主机端临时开放本地X11访问权限:
xhost +local:(重启后失效,生产环境需严格控制)。
2. 修复容器内GL驱动冲突
- 在Dockerfile中补充安装GL依赖:
RUN apt-get install -y libgl1-mesa-glx libgl1-mesa-dri - 取消注释Dockerfile中
RUN rm /usr/lib/x86_64-linux-gnu/libGL.so && ldconfig行,解决libGL库版本冲突。
3. 用普通用户运行容器
- 取消Dockerfile中被注释的用户创建代码,确保UID/GID与主机一致:
RUN groupadd -g 1000 myuser RUN useradd -d /home/myuser -s /bin/bash -m myuser -u 1000 -g 1000 USER myuser ENV HOME /home/myuser - 对应调整运行命令的挂载路径:
sudo docker run \ --volume="$HOME/.Xauthority:/home/myuser/.Xauthority:rw" \ --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ --volume="/run/user/$(id -u)/:/run/user/1000/:rw" \ -e DISPLAY=$DISPLAY \ -e XDG_RUNTIME_DIR=/run/user/1000 \ --net=host \ app_img
4. 验证基础X11连接
- 在容器内运行
xeyes测试X11是否正常:sudo docker run --rm \ --volume="$HOME/.Xauthority:/root/.Xauthority:rw" \ --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ -e DISPLAY=$DISPLAY \ ubuntu:xenial-20210804 xeyes
若xeyes能显示,说明X11配置无问题,问题出在Qt应用的依赖或构建参数上。
5. 调整Qt构建参数
- 构建时添加xcb平台指定参数:
RUN cd /app/build && cmake .. -DCMAKE_PREFIX_PATH=/opt/qt59/ -DQT_QPA_PLATFORM=xcb && make -j8 - 确保容器内安装Qt xcb插件:
apt-get install -y qt59xcb-plugin。
内容的提问来源于stack exchange,提问作者LateBird
相关产品推荐
相关产品推荐

