之前的项目环境是一台刚刚装完 Ubuntu 24.04 并配置好硬件驱动的主机接下来要在这套系统上部署 Docker。遇到过不少同学在驱动装完之后直接跑安装命令结果 Docker 起不来、容器无法联网、或者设备权限不对。这篇文章把我在 Ubuntu 24.04 上从零安装 Docker 的完整过程整理出来包括驱动环境下的特殊配置、镜像加速、容器访问 GPU 和 USB 串口设备的方法以及高频报错的排查思路希望对大家有所帮助。1. 为什么安装完驱动之后还要单独配置 Docker1.1 驱动与 Docker 的关系很多场景下驱动安装本身和 Docker 并不是同一个层面的东西。驱动负责让操作系统识别和管理硬件设备比如显卡驱动、USB 转串口驱动、网络驱动等而 Docker 是一个容器运行时它运行在操作系统之上通过 Linux 内核特性实现进程隔离。默认情况下Docker 容器是看不到宿主机硬件设备的。即使宿主机已经正确安装了驱动容器内部也不会自动获得访问 GPU、串口、USB 设备的能力。这也是为什么“驱动装好了”和“Docker 里能用这个设备”是两件必须分开处理的事。以我当前这台 Ubuntu 24.04 主机为例系统里已经安装好了平台相关的硬件驱动重启后lsusb、lspci都能正确识别设备。但如果直接docker run一个需要访问这些设备的镜像大概率会遇到“设备找不到”或“权限不足”的报错。1.2 什么时候需要特别关注驱动与 Docker 的配合根据实际经验以下几类场景最容易踩坑场景典型设备Docker 中的表现GPU 加速NVIDIA 显卡、加速卡容器内nvidia-smi找不到设备USB 转串口CP2102、CH340、FT232 等容器内无法打开/dev/ttyUSB0视觉相机USB 相机、工业相机容器内无法访问/dev/video0嵌入式调试J-Link、ST-Link需要把 USB 设备透传给容器传感器/执行器舵机控制板、电机驱动板需要通过串口或 USB 与宿主机通信因此在安装完驱动的 Ubuntu 24.04 上安装 Docker 只是第一步后续还需要根据业务需要把对应的设备映射进容器。1.3 本文能帮你解决什么这篇文章会覆盖以下内容在 Ubuntu 24.04 上安装 Docker 官方版本。配置国内镜像加速解决拉取镜像慢的问题。安装 Docker Compose 插件。将宿主机用户加入 docker 用户组避免频繁使用 sudo。配置 Docker 访问 NVIDIA GPU。把 USB 串口设备、USB 相机设备映射到容器内部。汇总常见报错的排查思路。2. 环境准备与版本说明2.1 系统环境本文演示环境如下项目内容操作系统Ubuntu 24.04 LTS内核版本6.8.x以实际安装为准硬件平台170hx 平台已安装对应驱动安装方式Docker 官方 apt 仓库用户权限需要 root 权限或 sudo 权限Ubuntu 24.04 是 2024 年发布的 LTS 版本官方支持周期较长默认内核较新对 overlay2 存储驱动和 iptables 的支持都比较完善。相比旧版本 Ubuntu安装 Docker 的步骤更简单兼容性问题更少。需要特别说明的是如果你的系统是刚从旧版本升级上来的或者使用的是精简版内核可能会出现内核模块缺失的情况。遇到这类问题先不要急于安装 Docker可以先检查内核版本和必要模块。2.2 检查系统基础状态在开始安装之前建议先确认系统处于可用状态。特别是“安装驱动之后”的场景驱动安装过程可能会修改内核模块、grub 配置或网络设置先检查一下可以减少后续问题。# 查看系统版本 lsb_release -a # 查看内核版本 uname -r # 查看当前用户是否有 sudo 权限 sudo whoami # 查看系统资源占用 free -h df -h如果命令可以正常返回信息说明系统基础状态良好。2.3 确认没有旧版本 Docker如果是从旧环境迁移过来的机器可能已经安装过 Docker。建议先确认系统里是否残留旧版本 Docker避免冲突。# 检查是否已经安装过 docker which docker # 检查 docker 服务状态 systemctl status docker如果提示找不到 docker 命令说明系统里没有安装过如果有输出则需要先卸载旧版本再安装。3. Docker 安装方式对比3.1 四种常见安装方式在 Ubuntu 24.04 上安装 Docker主要有以下几种方式安装方式优点缺点适用场景apt 官方仓库安装版本明确、升级方便、可复现步骤略多生产环境推荐官方安装脚本一条命令完成无法很好定制、需要执行远程脚本快速试验Docker Desktop带图形界面、自带 Docker Compose需要额外组件、不适合服务器桌面开发二进制包手动安装完全可控维护成本高特殊情况对于 Ubuntu 24.04 服务器或开发机我更推荐使用 apt 官方仓库的方式。原因很简单可复现、可升级、出了问题可以明确知道自己的软件源和版本来源。3.2 为什么不在 Ubuntu 自带源里直接安装Ubuntu 软件源里确实自带docker.io包但版本通常较旧。例如 Ubuntu 24.04 自带源中的 docker.io 版本可能落后官方仓库版本较多。新版 Docker 在性能、安全性和新特性上都有改进尤其是 containerd、BuildKit 等组件的更新直接影响容器构建和运行体验。因此建议使用 Docker 官方 apt 仓库获取最新稳定版本。4. Ubuntu 24.04 安装 Docker 完整实操4.1 更新软件源并安装依赖先执行系统更新然后安装 Docker 官方仓库所需的依赖包。sudo apt update sudo apt install -y ca-certificates curl gnupg这里安装的三个包的作用分别是ca-certificates提供 CA 证书apt 在添加 HTTPS 源时需要校验证书。curl下载 Docker 官方 GPG 密钥时使用。gnupg用于导入和管理 GPG 公钥。4.2 添加 Docker 官方 GPG 密钥sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg这段命令做的事情创建目录/etc/apt/keyrings用于存放 Docker 的 GPG 密钥。从 Docker 官方地址下载 GPG 公钥并转换为二进制格式。赋予读取权限确保 apt 能够正常读取。install -m 0755 -d的意思是创建目录并设置权限-m 0755表示目录权限为所有者可读写执行其他用户可读执行。4.3 添加 Docker apt 仓库接下来把 Docker 官方仓库写入系统的软件源列表。echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null这段命令稍微复杂拆开解释一下$(dpkg --print-architecture)自动获取当前系统架构一般是amd64或arm64。$(. /etc/os-release echo $VERSION_CODENAME)自动获取 Ubuntu 版本代号Ubuntu 24.04 对应的代号是 noble。tee把组合好的内容写入/etc/apt/sources.list.d/docker.list。写完后可以用下面的命令确认仓库内容cat /etc/apt/sources.list.d/docker.list输出类似deb [archamd64 signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable4.4 安装 Docker 引擎更新软件源索引然后安装 Docker 相关组件。sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里安装的包说明包名作用docker-ceDocker 社区版引擎docker-ce-cliDocker 命令行工具containerd.io容器运行时docker-buildx-plugin构建插件支持多平台构建docker-compose-pluginDocker Compose v2 插件安装完成后会自动启动 Docker 服务。可以查看服务状态确认。sudo systemctl status docker如果服务正常会显示active (running)的状态信息。4.5 验证 Docker 安装使用 hello-world 镜像验证 Docker 是否正常。sudo docker run hello-world如果看到类似下面的输出说明 Docker 已经可以正常运行容器Hello from Docker! This message shows that your installation appears to be working correctly.如果拉取镜像时卡住或超时先不要着急可能是网络原因这篇文章后面会给出国内镜像加速配置方案。4.6 设置 Docker 开机自启动安装 Docker 后服务默认可能没有设置为开机自启。建议手动设置一下。sudo systemctl enable docker sudo systemctl start dockerenable是设置开机自启start是立即启动服务。重启系统后 Docker 也会自动运行。5. 配置当前用户免 sudo 使用 Docker5.1 为什么需要配置用户组默认情况下执行 Docker 命令需要 root 权限。每次都在命令前加sudo比较麻烦而且在脚本中混用 sudo 也可能带来权限问题。Docker 的守护进程使用 Unix socket 与客户端通信默认 socket 文件属于root用户和docker用户组。把当前用户加入docker用户组后就不需要每次使用 sudo 了。5.2 添加用户到 docker 组sudo usermod -aG docker $USER这条命令把当前用户添加到 docker 组。-aG表示追加到附加组列表$USER是当前登录用户名。执行完命令后需要重新登录或重启系统才能生效。不重启的话可以用下面的命令刷新组成员关系newgrp docker或者直接注销重新登录。5.3 验证免 sudo 执行重新登录后执行docker ps如果正常显示容器列表哪怕是空列表而不是报权限错误说明配置成功。这里需要提醒一下加入 docker 用户组相当于授予了等同于 root 的部分权限因为 docker 组用户可以操作宿主机上的资源。在生产环境的多用户服务器上要谨慎决定哪些用户能加入 docker 组。6. 配置国内镜像加速6.1 镜像拉取慢的原因Docker Hub 是 Docker 默认的镜像仓库由于网络原因国内服务器直接拉取 Docker Hub 镜像时经常会出现超时、速度慢、断流等问题。配置国内镜像加速器是解决这个问题最直接的方法。镜像加速器的原理是在 Docker 配置中指定一个更快的镜像仓库地址Docker 拉取镜像时会优先从加速地址获取。6.2 修改 Docker 守护进程配置编辑或创建/etc/docker/daemon.json文件。sudo mkdir -p /etc/docker sudo nano /etc/docker/daemon.json写入以下内容{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com, https://docker.nju.edu.cn ] }需要说明的是镜像加速器地址在不同地区和网络环境下可用性差异很大如果某个地址失效可以更换其他可用地址。建议根据自己的实际测试结果选择。保存文件后重启 Docker 服务sudo systemctl daemon-reload sudo systemctl restart docker6.3 验证镜像加速配置运行下面的命令查看配置是否生效docker info在输出中找到Registry Mirrors一栏如果能看到刚才填写的地址说明配置成功。Registry Mirrors: https://docker.m.daocloud.io/ https://dockerproxy.com/ https://docker.nju.edu.cn/之后重新拉取 hello-world 镜像测试docker pull hello-world正常情况下速度会有明显提升。6.4 镜像加速器的局限性需要注意镜像加速器只对 Docker Hub 公共镜像有效。如果拉取的是私有仓库镜像或某些特定镜像仍然需要配置对应的 registry 地址。此外不同加速器的镜像同步策略不同个别镜像可能不是最新版本生产环境建议验证后再使用。7. 驱动安装完成后的 Docker 专项配置这一节是本文的重点。既然标题是“170hx 平台安装驱动之后”那么驱动相关环境下的 Docker 配置就需要单独处理。以下分别从 GPU 和 USB 串口设备两个常见方向展开。7.1 NVIDIA GPU 驱动与 Docker 配置如果平台安装的是 NVIDIA 显卡驱动并在宿主机上已经能正常使用nvidia-smi命令那么 Docker 容器里默认是无法访问 GPU 的。需要额外安装 NVIDIA Container Toolkit。首先确认宿主机驱动正常nvidia-smi如果能看到类似下面的输出说明驱动安装成功--------------------------------------------------------------------------------------- | NVIDIA-SMI 550.54.15 Driver Version: 550.54.15 CUDA Version: 12.4 | ---------------------------------------------------------------------------------------接下来配置 Docker 支持 GPU。先安装 NVIDIA Container Toolkit 的 apt 仓库。curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed s#deb https://#deb [signed-by/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list然后安装 toolkitsudo apt update sudo apt install -y nvidia-container-toolkit安装完成后配置 Docker 使用 NVIDIA 容器运行时sudo nvidia-ctk runtime configure --runtimedocker sudo systemctl restart docker验证容器可以访问 GPUdocker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi如果容器内能正常输出nvidia-smi信息说明 GPU 已经在容器中可用。需要注意--gpus all参数要求 Docker 版本较新并且已经正确安装了 nvidia-container-toolkit。如果运行报错先检查 toolkit 是否安装成功、Docker 服务是否重启。7.2 USB 转串口设备映射到容器在嵌入式开发和机器人项目中经常需要使用 USB 转串口芯片比如 CP2102、CH340、FT232 等。这些芯片在 Ubuntu 下会生成/dev/ttyUSB0或/dev/ttyACM0设备节点。首先确认宿主机已经识别设备lsusb ls /dev/ttyUSB*如果看到/dev/ttyUSB0存在说明驱动已经生效。启动容器时用--device参数把宿主机设备映射进容器docker run -it --device/dev/ttyUSB0 ubuntu:22.04 bash进入容器后检查设备是否可见ls -l /dev/ttyUSB0如果能看到设备节点说明映射成功。需要注意的是容器内的用户可能没有权限访问/dev/ttyUSB0。这时可以在启动容器时通过--group-add参数把容器用户加入dialout组docker run -it --device/dev/ttyUSB0 --group-add dialout ubuntu:22.04 bash或者直接用--privileged参数但这种方式会赋予容器更多宿主机权限生产环境需要谨慎使用。7.3 USB 相机和视频设备映射类似地视觉相机等设备在 Ubuntu 下会生成/dev/video0设备节点。映射方式相同docker run -it --device/dev/video0 --group-add video ubuntu:22.04 bash如果同时需要 GPU 和摄像头可以组合参数docker run -it \ --gpus all \ --device/dev/video0 \ --device/dev/ttyUSB0 \ ubuntu:22.04 bash这样容器内就同时拥有 GPU 计算能力、摄像头访问能力和串口访问能力。7.4 使用 docker-compose 配置设备映射对于复杂的应用不建议在命令行里写一长串参数。使用 Docker Compose 可以把容器配置固化到 YAML 文件里方便维护和复现。以下是一个示例docker-compose.ymlversion: 3.8 services: app: image: ubuntu:22.04 container_name: my_app restart: unless-stopped devices: - /dev/ttyUSB0:/dev/ttyUSB0 - /dev/video0:/dev/video0 group_add: - dialout - video deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu] stdin_open: true tty: true启动服务docker compose up -d进入容器docker exec -it my_app bash这种写法的好处是设备映射关系一目了然换机器部署时只需要保持 YAML 文件一致即可。8. 常见问题与排查思路8.1 Docker 服务启动失败问题现象常见原因解决思路Cannot connect to the Docker daemonDocker 服务未启动sudo systemctl start docker服务启动后立即退出网络配置冲突查看日志journalctl -u docker -n 50内核模块缺失旧内核或精简内核modprobe overlay、modprobe br_netfilterIP 转发被关闭网络转发配置问题检查/proc/sys/net/ipv4/ip_forward8.2 拉取镜像超时或失败问题现象常见原因解决思路dial tcp: lookup ... no such hostDNS 解析失败检查宿主机 DNS 配置request canceled while waiting for connection无法连接 Docker Hub配置镜像加速器net/http: TLS handshake timeout网络问题重试或更换镜像加速地址镜像体积太大导致超时镜像本身较大使用docker pull分步拉取或找替代镜像配置镜像加速器后仍然失败时可以尝试直接拉取其它公开镜像源验证网络连通性docker pull alpine:latest如果 alpine 能拉取成功而某个大镜像失败大概率是镜像大小或特定源的问题。8.3 容器内访问串口设备权限不足问题现象常见原因解决思路permission denied: /dev/ttyUSB0容器内用户不在 dialout 组启动时添加--group-add dialout设备不存在宿主机驱动未加载或设备未插好先确认宿主机lsusb能看到设备每次重启设备号变化设备节点不稳定通过 udev 规则固定设备名8.4 Docker 命令需要 sudo 但不想每次输入问题现象常见原因解决思路permission denied while trying to connect to the Docker daemon socket用户不在 docker 组执行sudo usermod -aG docker $USER后重新登录8.5 容器内无法联网问题现象常见原因解决思路Network is unreachable容器网络模式问题检查宿主机能不能上网域名解析失败DNS 配置异常在daemon.json中配置 DNS 或用--dns 8.8.8.8防火墙拦截iptables 规则冲突检查防火墙状态sudo ufw status在 Ubuntu 24.04 上如果同时启用了 ufw 和 Docker默认的 iptables 规则可能会被 Docker 覆盖导致容器网络异常。处理方式通常是配置 Docker 的 iptables 选项或者调整 ufw 规则具体方案需要结合网络策略来定。8.6 安装 nvidia-container-toolkit 后 nvidia-smi 仍不可用问题现象常见原因解决思路容器内nvidia-smi命令不存在基础镜像没有 NVIDIA 驱动工具换用包含 CUDA 的镜像could not select device driver with capabilities: [[gpu]]nvidia 运行时未配置成功重新运行sudo nvidia-ctk runtime configure --runtimedocker提示版本不匹配驱动版本与容器镜像 CUDA 版本不匹配检查nvidia-smi输出确认支持的 CUDA 版本9. 最佳实践与工程建议9.1 不要把数据写在容器内部容器是易失的容器删除后内部文件也会消失。数据库、配置文件、日志等需要持久化的数据应该通过卷或绑定挂载的方式保存到宿主机。docker run -d \ --name mysql \ -v /opt/mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORDyour_password \ mysql:8.0这里把宿主机/opt/mysql/data挂载到容器内的/var/lib/mysql数据就不会因为容器重建而丢失。9.2 固定镜像版本而不是使用 latest在生产环境中不建议使用latest标签。镜像更新后可能会导致行为变化使用指定版本可以保证环境一致。# 不推荐 docker run mysql:latest # 推荐 docker run mysql:8.0.36在docker-compose.yml中也应该写明确的版本号。9.3 最小权限原则启动容器时尽量不要使用--privileged参数而是按需映射设备和组权限。对于仅需要 GPU 的容器使用--gpus参数对于需要串口的容器映射对应的设备节点并添加对应组权限。过多地使用特权模式会降低系统的安全性一旦容器被入侵攻击者就获得了接近宿主机的权限。9.4 日志清理要定期做容器日志默认会写到宿主机的/var/lib/docker/containers/id/目录下如果长时间不清理可能会占满磁盘。建议在daemon.json中配置日志轮转{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }这样单个日志文件达到 10MB 就会自动轮转最多保留 3 份避免日志无限增大。修改后需要重启 Docker 服务sudo systemctl daemon-reload sudo systemctl restart docker9.5 编写 Dockerfile 时把稳定的步骤放在前面Docker 构建镜像时会使用缓存如果某一步内容没有变化后续构建会直接使用缓存显著加快构建速度。因此应该把apt install这类比较少变化的操作放在 Dockerfile 前面把代码复制、编译这类经常变化的操作放在后面。FROM ubuntu:22.04 # 先安装系统依赖 RUN apt update apt install -y python3 python3-pip # 再复制项目代码 COPY . /app WORKDIR /app CMD [python3, main.py]9.6 使用 Docker Compose 管理多容器应用当一个项目涉及多个容器时例如 Web 服务配数据库再配 Redis手动管理容器会非常痛苦。使用 Docker Compose 可以把所有容器定义在一个文件里一条命令启动所有服务。# 查看所有服务状态 docker compose ps # 启动服务并后台运行 docker compose up -d # 查看日志 docker compose logs -f # 停止并删除容器 docker compose downCompose 文件本身就是一种文档记录了一个项目的完整依赖关系。10. 总结本文从 Ubuntu 24.04 安装 Docker 的完整流程讲起覆盖了 apt 官方仓库安装、免 sudo 配置、国内镜像加速、驱动安装完成后的 GPU 和 USB 设备映射配置以及常见问题的排查思路。如果你是在一台刚刚安装完驱动的主机上继续配置 Docker建议按照下面的顺序操作确认系统状态和内核版本。使用 apt 官方仓库安装 Docker Engine。配置国内镜像加速。把当前用户加入 docker 组。根据硬件需求配置 GPU 或 USB 设备映射。用一个小容器验证整个环境是否可用。这套流程不只是针对特定硬件平台对于大多数 Ubuntu 24.04 Docker 的场景都适用。配置过程中如果遇到报错先看服务日志再对照上文中的排查表格大部分问题都能找到方向。Docker 安装完成只是容器化实践的第一步接下来可以继续学习镜像构建、容器编排、数据卷管理、网络模式等进阶内容。在真实项目中建议先把镜像构建流程和持久化方案设计好再逐步引入 Compose 或更复杂的编排工具。如果本文对你有帮助可以收藏备用后面需要的时候直接拿出来对照操作。