# 使用 NVIDIA Container Toolkit 运行 Docker GPU 容器

> NVIDIA Container Toolkit 的 Docker GPU 指南：使用 --gpus 参数、选择设备、在 Compose 中预留 GPU、解决 PyTorch 共享内存不足问题，并运行 ROCm 容器。

来源：https://fullgpu.com/zh/docs/docker-containers  
更新日期：2026-10-22  
发布方：FullGPU (https://fullgpu.com/)

借助 NVIDIA Container Toolkit 运行 Docker GPU 工作负载只需一个参数，但实际部署还需要多做几步：为每个容器选择 GPU、在 Docker Compose 中预留 GPU、选择与驱动匹配的基础镜像，以及为 PyTorch 提供足够的共享内存。我们的 Ubuntu 镜像已预装 Docker 和该工具包。AMD 服务器则改用设备参数，文末附近会介绍。

## 检查 Docker 和 Container Toolkit

```
docker --version
nvidia-ctk --version
docker info | grep -i runtimes
docker run --rm --gpus all ubuntu nvidia-smi
```

最后一条命令应输出与主机上相同的 GPU 表格。Container Toolkit 会把主机的驱动挂载到容器中，因此镜像中从不包含驱动，只需包含应用程序所用的 CUDA 库。以非 root 用户身份操作时，请在 `docker` 前加上 `sudo`，或者加入 `docker` 组（该组的权限等同于 root）。

## 为容器分配全部或部分 GPU

```
# all GPUs
docker run --rm --gpus all ubuntu nvidia-smi -L
# GPUs 0 and 1 (the inner quotes are required because of the comma)
docker run --rm --gpus '"device=0,1"' ubuntu nvidia-smi -L
# one GPU by UUID, as printed by nvidia-smi -L on the host
docker run --rm --gpus device=GPU-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
  ubuntu nvidia-smi -L
```

在容器内，选中的 GPU 从 0 开始编号，因此主机上的 2 号和 3 号 GPU 会显示为 0 号和 1 号。要把某项服务固定到特定的 GPU 上，使用 UUID 最为稳妥。要在 8 卡服务器上运行 8 个相互独立的任务，请用 `--gpus device=N` 为每张 GPU 各启动一个容器。

对于使用 NVIDIA 运行时的容器，Container Toolkit 还会读取 `NVIDIA_VISIBLE_DEVICES` 变量：

```
docker run --rm --runtime=nvidia -e NVIDIA_VISIBLE_DEVICES=0,1 \
  ubuntu nvidia-smi -L
```

如果 `/etc/docker/daemon.json` 中的默认运行时是 `nvidia`，那么设置了该变量的镜像（NVIDIA 的 CUDA 镜像就是如此）即使不加 `--gpus` 也会获得所有 GPU；因此，需要限制 GPU 时，请显式设置该变量。`CUDA_VISIBLE_DEVICES` 则不同：它在容器内部，从已挂载的 GPU 中进行筛选。

## 在 Docker Compose 中预留 GPU

```
services:
  trainer:
    image: ubuntu:24.04
    command: nvidia-smi -L
    ipc: host
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ["0", "1"]
              capabilities: [gpu]
```

用 `docker compose up` 运行，输出中应列出两张 GPU。如果要按数量而不是按 ID 分配 GPU，请将 `device_ids` 替换为 `count: all` 或 `count: 2`；这两个键不能同时使用，并且必须设置 `capabilities: [gpu]`。如果 `docker compose version` 运行失败，请安装 Compose 插件：Docker 来自 Docker 官方软件源时安装 `docker-compose-plugin`，来自 Ubuntu 软件源时安装 `docker-compose-v2`。

> 即使 ufw 拒绝该端口，像 `-p 8000:8000` 这样发布的端口仍可从互联网访问，因为 Docker 会写入自己的防火墙规则。请以 `-p 127.0.0.1:8000:8000` 的形式发布服务（在 Compose 中写作 `"127.0.0.1:8000:8000"`），并在前面放置反向代理，具体做法见[防火墙指南](https://fullgpu.com/zh/docs/networking-firewall)。

## 选择 CUDA 或 NGC 基础镜像

- **nvidia/cuda** 镜像发布在 Docker Hub 上，分为三种类型：`base`（最精简的 CUDA 运行时）、`runtime`（增加 CUDA 库）和 `devel`（再增加编译器和头文件），部分镜像还包含 cuDNN。标签格式为 `VERSION-FLAVOR-OS`，例如 `12.8.1-runtime-ubuntu24.04`。
- **NGC 镜像**（例如 `nvcr.io/nvidia/pytorch`）集成了经过调优的框架栈，按月发布标签，格式为 `YY.MM-py3`。其发行说明列出了每个标签所需的驱动。

请选择 CUDA 版本不高于主机上 `nvidia-smi` 所显示“CUDA Version”的标签；对于 Blackwell GPU，还需选择 CUDA 12.8 或更高版本。如果镜像所需的驱动比主机上的更新，容器会拒绝启动，并报出 `unsatisfied condition: cuda>=` 错误。[驱动与 CUDA 版本](https://fullgpu.com/zh/docs/nvidia-drivers-cuda)一文解释了这条规则。

## 为 PyTorch 提供足够的共享内存

Docker 默认将 `/dev/shm` 限制为 64 MB。PyTorch DataLoader 的 worker 进程和 NCCL 都依赖共享内存，因此训练会失败，并报出“bus error”或“insufficient shared memory (shm)”消息。请共享主机的 IPC 命名空间，或者提高该限制（将 `YY.MM` 替换为当前的标签）：

```
# share the host IPC namespace, as NVIDIA recommends for its PyTorch images
docker run --rm -it --gpus all --ipc=host \
  --ulimit memlock=-1 --ulimit stack=67108864 \
  -v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3

# or keep IPC isolated with a larger /dev/shm
docker run --rm -it --gpus all --shm-size=16g \
  -v /data:/data nvcr.io/nvidia/pytorch:YY.MM-py3
```

在容器内，`df -h /dev/shm` 会显示可用空间。在 Compose 中，请使用 `ipc: host` 或 `shm_size: "16gb"`。vLLM 镜像也需要同样的处理，参见[用 vLLM 提供大语言模型（LLM）推理服务](https://fullgpu.com/zh/docs/pytorch-vllm)。

## AMD GPU：ROCm 中的对应做法

```
docker run --rm --device=/dev/kfd --device=/dev/dri \
  --group-add video --ipc=host \
  rocm/pytorch:latest \
  python3 -c "import torch; print(torch.cuda.device_count())"
```

在 MI355X 服务器上，这条命令会输出 `8`。运行 ROCm 容器的标准方式是传入设备文件，而不是使用 `--gpus`：`/dev/kfd` 是计算接口，`/dev/dri` 中则是 GPU 设备节点。要让容器只使用部分 GPU，请添加 `-e HIP_VISIBLE_DEVICES=0,1`。其余内容请参阅 [ROCm 配置](https://fullgpu.com/zh/docs/amd-rocm)。

## 故障排查

- **could not select device driver "" with capabilities: [[gpu]]** 或 **unknown or invalid runtime name: nvidia**。Docker 尚未配置 NVIDIA 运行时。请运行 `sudo nvidia-ctk runtime configure --runtime=docker`，然后运行 `sudo systemctl restart docker`。
- **unsatisfied condition: cuda>=X.Y.** 该镜像需要更新的驱动。请改用较旧的镜像标签，或在控制台提交工单咨询驱动问题。
- **连接 Docker 守护进程套接字时出现 permission denied。**请使用 `sudo`，或者将您的用户加入 `docker` 组，然后重新登录。

## 相关页面

- [使用 vLLM 部署 LLM 推理服务](https://fullgpu.com/zh/docs/pytorch-vllm): 在您的 GPU 服务器上用 vLLM 部署 LLM 推理服务：用 uv 配置 Python 环境，安装 PyTorch 和 vLLM，测试兼容 OpenAI 的 API，再将其作为系统服务长期运行。
- [在 Ubuntu 上查看 CUDA 版本和 NVIDIA 驱动](https://fullgpu.com/zh/docs/nvidia-drivers-cuda): 用 nvidia-smi 和 nvcc 查看 NVIDIA 驱动与 CUDA 版本，了解两者的版本必须如何对应，并在 Ubuntu 24.04 上加装一个 CUDA 工具包，而无需安装新的驱动。
- [GPU 服务器防火墙配置](https://fullgpu.com/zh/docs/networking-firewall): GPU 服务器防火墙配置指南：用 ufw 先放行 SSH 再启用防火墙，同时过滤 IPv6，避开 Docker 发布端口绕过 ufw 的陷阱，并用 TLS 和 API 密钥保护 vLLM 推理端点。
- [GPU 服务器操作系统镜像：预装 CUDA、ROCm 与 Docker](https://fullgpu.com/zh/products/os-images): GPU 服务器操作系统镜像：Ubuntu 22.04 与 24.04，预装 NVIDIA 驱动、CUDA、Docker 和 Container Toolkit；AMD 服务器另有 ROCm 镜像。了解镜像中预装了哪些软件。
