如何在docker-compose.yml中让容器内OpenGL调用NVIDIA GPU
Docker Compose配置无法让ROS Noetic容器调用NVIDIA GPU的问题与解决
问题背景
使用Dockerfile和docker-compose构建ROS Noetic容器后,容器内OpenGL始终使用llvmpipe软件渲染,无法调用NVIDIA GPU;但直接通过docker run命令启动的容器可以正常调用GPU,需要修正docker-compose配置。
环境信息
文件夹结构
noetic ├── .devcontainer │ ├── devcontainer.json │ ├── docker-compose.yml │ ├── Dockerfile │ ├── .p10k.zsh │ ├── powerlevel10k │ ├── sources.list │ └── .zshrc ├── .dockerignore └── workspace
Dockerfile内容
# base image from noetic FROM osrf/ros:noetic-desktop-full RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak COPY .devcontainer/sources.list /etc/apt/ RUN apt update -yq && apt upgrade -yq && \ apt install -y curl sudo zsh zsh-autosuggestions zsh-syntax-highlighting RUN chsh -s /bin/zsh \ && echo "source /opt/ros/noetic/setup.bash" >> /root/.bashrc \ && echo "source /opt/ros/noetic/setup.zsh" >> /root/.zshrc \ && echo "export net.ipv4.ip_forward=1" >> /etc/sysctl.conf \ && /bin/bash -c "source /root/.bashrc" \ && /bin/zsh -c "source /root/.zshrc" \ && rm -rf /var/lib/apt/lists/* ARG user=noetic RUN useradd --create-home --no-log-init --shell /bin/zsh ${user} \ && adduser ${user} sudo \ && echo "${user}:1" | chpasswd \ && usermod -u 1000 ${user} && usermod -G 1000 ${user} \ && echo "%${user} ALL=(ALL:ALL) ALL" >> /etc/sudoers \ && echo "%${user} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \ && mkdir -p /home/${user}/software/powerlevel10k COPY .devcontainer/powerlevel10k /home/${user}/software/powerlevel10k COPY .devcontainer/.zshrc /home/${user} COPY .devcontainer/.p10k.zsh /home/${user} RUN echo "source /home/${user}/software/powerlevel10k/powerlevel10k.zsh-theme" >> /home/${user}/.zshrc \ && echo "source /home/${user}/.zshrc" >> /root/.zshrc ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 HEALTHCHECK --interval=600s --timeout=20s \ CMD curl -fs http://localhost/ || exit 1 USER ${user}
Docker Compose版本
docker-compose版本为1.28.0,build d02a7b1a
当前docker-compose.yml内容
version: '3.7' services: noetic: container_name: noetic build: context: ../ dockerfile: .devcontainer/Dockerfile # image: osrf/ros:noetic-desktop # hostname: noetic_host privileged: true network_mode: "host" command: /bin/bash volumes: - /dev:/dev # Add more volumes here if needed - ../workspace:/workspace - /tmp/.X11-unix:/tmp/.X11-unix environment: - NVIDIA_VISIBLE_DEVICES=all - TZ=Asia/Shanghai - xpack.monitoring.enabled=false - xpack.watcher.enabled=false - DISPLAY=$DISPLAY - GDK_SCALE - GDK_DPI_SCALE deploy: resources: limits: cpus: '0.70' memory: 8G reservations: devices: - driver: nvidia count: all capabilities: [gpu] healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 10m timeout: 20s retries: 3 logging: driver: "json-file" options: max-size: "50M" max-file: "10" tty: true
问题现象
- 本地主机
nvidia-smi输出:
+---------------------------------------------------------------------------------------+ | NVIDIA-SMI 535.161.07 Driver Version: 535.161.07 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 NVIDIA GeForce RTX 3050 ... Off | 00000000:01:00.0 On | N/A | | N/A 47C P5 5W / 60W | 509MiB / 4096MiB | 8% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | 0 N/A N/A 1623 G /usr/lib/xorg/Xorg 238MiB | | 0 N/A N/A 2917 G /usr/bin/gnome-shell 62MiB | | 0 N/A N/A 5596 G /usr/lib/firefox/firefox 136MiB | | 0 N/A N/A 111082 G ...sion,SpareRendererForSitePerProcess 63MiB | +---------------------------------------------------------------------------------------+
- 本地
glxinfo | grep -i opengl输出:
OpenGL vendor string: NVIDIA Corporation OpenGL renderer string: NVIDIA GeForce RTX 3050 Laptop GPU/PCIe/SSE2 OpenGL core profile version string: 4.6.0 NVIDIA 535.161.07 OpenGL core profile shading language version string: 4.60 NVIDIA OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: OpenGL version string: 4.6.0 NVIDIA 535.161.07 OpenGL shading language version string: 4.60 NVIDIA OpenGL context flags: (none) OpenGL profile mask: (none) OpenGL extensions: OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 535.161.07 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20 OpenGL ES profile extensions:
- 容器内
glxinfo | grep -i opengl输出:
OpenGL vendor string: Mesa/X.org OpenGL renderer string: llvmpipe (LLVM 12.0.0, 256 bits) OpenGL core profile version string: 4.5 (Core Profile) Mesa 21.2.6 OpenGL core profile shading language version string: 4.50 OpenGL core profile context flags: (none) OpenGL core profile profile mask: core profile OpenGL core profile extensions: OpenGL version string: 3.1 Mesa 21.2.6 OpenGL shading language version string: 1.40 OpenGL context flags: (none) OpenGL extensions: OpenGL ES profile version string: OpenGL ES 3.2 Mesa 21.2.6 OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20 OpenGL ES profile extensions:
- 可正常运行的
docker run命令:
sudo docker run -it --privileged --gpus all -e NVIDIA_DRIVER_CAPABILITIES=all -e "DISPLAY=$DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix -v /dev:/dev --name noetic_nvidia osrf/ros:noetic-desktop-full /bin/bash
解决方法
当前docker-compose配置存在两个问题:缺少NVIDIA_DRIVER_CAPABILITIES=all环境变量,且低版本docker-compose(1.28.0)对deploy.resources.reservations.devices的支持有限,需调整配置:
- 在
environment中添加NVIDIA_DRIVER_CAPABILITIES=all,启用所有NVIDIA驱动能力(包括OpenGL渲染) - 替换
deploy.resources部分,改用runtime: nvidia(对应docker run --gpus all参数,低版本docker-compose中更可靠)
修改后的docker-compose.yml:
version: '3.7' services: noetic: container_name: noetic build: context: ../ dockerfile: .devcontainer/Dockerfile privileged: true network_mode: "host" runtime: nvidia # 对应--gpus all参数 command: /bin/bash volumes: - /dev:/dev - ../workspace:/workspace - /tmp/.X11-unix:/tmp/.X11-unix environment: - NVIDIA_VISIBLE_DEVICES=all - NVIDIA_DRIVER_CAPABILITIES=all # 添加该环境变量 - TZ=Asia/Shanghai - xpack.monitoring.enabled=false - xpack.watcher.enabled=false - DISPLAY=$DISPLAY - GDK_SCALE - GDK_DPI_SCALE deploy: {} # 移除原GPU资源预留配置,如需CPU/内存限制可保留对应部分 healthcheck: test: ["CMD", "curl", "-f", "http://localhost"] interval: 10m timeout: 20s retries: 3 logging: driver: "json-file" options: max-size: "50M" max-file: "10" tty: true
修改后重新构建并启动容器:
docker-compose down docker-compose build docker-compose up -d
进入容器后再次执行glxinfo | grep -i opengl,即可看到NVIDIA GPU的渲染信息。
内容的提问来源于stack exchange,提问作者尹若尘
相关产品推荐
相关产品推荐

