You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:57:18