Ubuntu安装Docker完整指南:从环境预检到排错实战

发布时间:2026/10/15 22:05:47

Ubuntu安装Docker完整指南:从环境预检到排错实战 从零开始Ubuntu 装机路上的一次 Docker 安装记录作为一个长期折腾 Linux 桌面和服务器的用户我几乎每次重装系统都要和 Docker 打交道。这篇文章是我前段时间在一台全新的 Ubuntu 设备上安装 Docker 的完整记录包含了每一步操作的背后逻辑、我踩过的坑以及最终稳定运行的配置方案。如果你正准备在 Ubuntu 上部署容器化应用或者只是想弄清楚 Docker 安装过程中那些“为什么必须这样做”的细节这篇内容应该能帮你省下不少排查时间。我默认你的系统是 Ubuntu 20.04 或 22.04 这类 LTS 版本因为生产环境和日常折腾我都更推荐 LTS毕竟安全更新周期长Docker 官方对 LTS 的支持也最稳定。文章里的命令我都实际跑过但每台机器的硬件、内核、网络环境不同你执行时如果遇到差异可以对照最后的排查章节逐项检查。1. 安装前的环境检查别急着敲命令很多人上来就是一条curl -sSL https://get.docker.com | sh图省事。我不反对这种官方脚本但如果你想知道系统里到底发生了什么或者你所在的环境网络受限脚本式安装会让人很被动。所以我的习惯是先花两分钟确认系统状态再手动按步骤装。1.1 为什么要先确认系统架构和内核Docker 的安装包依赖 CPU 架构最常见的是 amd64 和 arm64。树莓派这类 ARM 设备如果用了 x86 的源装出来的要么报错要么性能异常。确认架构就一条命令uname -m输出x86_64就是 amd64输出aarch64就是 arm64。后续添加 apt 源的时候Docker 官方会把架构信息写进源地址你手动操作时也要保证架构一致。另一个重要前提是内核版本。Docker 正常运行需要内核支持一些关键特性比如overlay网络模块和cgroups。Ubuntu 20.04 默认内核是 5.4 以上完全满足要求。但如果你用的是非常老的内核比如 3.x建议先升级系统再装 Docker否则运行容器时会出现奇怪的挂载错误。检查内核uname -r看到类似5.15.0-xxx-generic这样的版本就放心继续。1.2 我常用的几个预检命令除了架构和内核我还会顺手检查系统是否已经存在 Docker 痕迹。这一步很容易被跳过但如果你曾经用旧版本安装过残留的配置文件可能会干扰新版本。预检命令如下which docker dpkg -l | grep -i docker snap list | grep docker如果which docker有输出说明已经装过如果dpkg -l里有docker.io或docker-ce就需要先卸载。还有一点Ubuntu 自带的 snap 版本 Docker 有时会悄悄存在用snap list能看到。我自己就遇到过 snap 版 Docker 和 docker-ce 冲突导致 socket 文件被占用的情况所以预检这一步不可省。2. 卸载旧版本与配置官方软件源干净是成功的一半这一步看起来像是在做无用功但恰恰是很多安装失败的根源。Ubuntu 官方仓库里有一个名为docker.io的旧版本包它和 Docker 官方维护的docker-ce包在文件路径上高度重叠混装的话运行docker ps时经常报Cannot connect to the Docker daemon但实际上服务又没启动。2.1 清理历史残留的常见坑如果你像我一样曾经折腾过建议依次执行sudo apt remove docker docker-engine docker.io containerd runc注意这个命令只会卸载应用本体不会删掉/var/lib/docker里的数据。如果你只是想重装系统、所有容器数据都不要了那可以手动删除这个目录sudo rm -rf /var/lib/docker但这句话请务必谨慎删除之前想清楚里面有没有你需要的镜像和容器数据。我一般会先把/var/lib/docker压缩备份再执行清理这样就算后面遇到问题也有后悔药。如果用的是 snap 版卸载命令是sudo snap remove docker2.2 添加官方 Apt 源的完整流程为什么要用官方源而不是 Ubuntu 自带的源因为官方源里的docker-ce版本更新快能及时拿到安全补丁和新特性而自带源可能停留在很老的版本。添加方式比较固定sudo apt update sudo apt install ca-certificates curl gnupg 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这里有个关键细节Docker 官方文档要求把 gpg 密钥放到/etc/apt/keyrings目录并给ar权限这样 apt 才能正常读取。如果你以前是用apt-key add方式那种做法在新版 apt 里会弹出警告甚至直接拒绝使用。所以我建议直接按上面这版来干净又正规。接着是写入源列表。我用的是 Ubuntu 22.04对应编译代号 jammy。如果你用 20.04 就改成 focal。一条命令写入echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/nulllsb_release -cs会自动识别你的系统版本代号不用手写省事。执行完记得再跑一次sudo apt update如果源没问题更新列表里就会出现docker-ce相关的候选版本。提示如果你的网络访问download.docker.com很慢可以在源地址前加一个国内镜像前缀比如清华源或阿里云的 Docker 仓库地址。但要注意镜像站的 gpg 密钥路径不变只是把域名替换掉。3. 安装 Docker 引擎与命令行工具从依赖到 Hello-world源配置好之后安装本身反而简单。但我还是想拆开讲一下因为很多人只抄命令不明白为什么装这几个包。3.1 核心包之间的依赖关系需要安装的包有四个docker-ce、docker-ce-cli、containerd.io、docker-buildx-plugin以及docker-compose-plugin。其中docker-ce是 Docker 引擎本体负责管理容器生命周期docker-ce-cli是命令行工具你敲的docker pull、docker run都由它解释containerd.io是底层容器运行时引擎通过它真正创建和运行容器docker-buildx-plugin是构建镜像的扩展新版构建工具docker-compose-plugin是 Docker Compose v2 的官方插件如果你以后想用docker compose up一键启动多容器这个必须装。安装命令sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin如果系统里没有冲突包这一步会很快。装完不要急着测试先看一眼服务状态sudo systemctl status docker正常应该是active (running)。如果状态是dead多半是 swap 分区或 iptables 配置的问题后面排查章会说。3.2 安装完成后的第一件事运行测试容器我的习惯是跑一个最轻量的 hello-world 镜像验证整个链路是否通畅。命令很简单sudo docker run hello-world第一次运行会去拉取镜像。如果网络正常你会看到一段Hello from Docker!的提示同时容器会运行完自动退出。这一步能确认三件事引擎能启动、内核能创建容器、网络能拉取镜像。如果你看到 pull 超时或 connection refused那大概率是网络问题。常见的临时解决办法是先配置镜像加速再重新 pull。加速配置写在这个文件里sudo mkdir -p /etc/docker sudo nano /etc/docker/daemon.json填入{ registry-mirrors: [https://docker.mirrors.ustc.edu.cn] }保存后重启 Dockersudo systemctl restart docker之后再跑docker run hello-world拉取速度会明显改善。这里提醒一句加速器地址属于第三方如果你所在环境要求严格可以选官方源或自己搭建的私有仓库这个因人而异。4. 免 sudo 执行 docker 命令用户组配置的正确姿势安装完成后的第一件烦心事是每次敲docker都要带sudo容易忘而且会污染日志权限。解决方法是把当前用户加入docker组。4.1 为什么默认需要 sudoDocker 引擎其实监听在/var/run/docker.sock这个 socket 文件上而这个文件的属主是root:docker权限是srw-rw----。也就是说只有 root 和 docker 组成员才能读写。如果你当前用户不在 docker 组里操作系统就不允许你访问于是 CLI 会报权限不足。有人说这样设计不安全我同意。毕竟能访问 docker.sock 就等于能操作宿主机上的容器能力等同于 root。所以如果你在多人共享服务器上尽量让管理员而不是所有人加入 docker 组如果是个人开发机加入组确实能省很多事。4.2 配置当前用户加入 docker 组一条命令搞定sudo usermod -aG docker $USER执行完成后必须退出当前 shell 再重新登录或者干脆重启一次系统。因为用户组的新增权限只在新的登录会话中生效直接继续用旧 shell 还是会提示权限不足。我以前就吃过这个亏以为命令没生效折腾半天才发现没重新登录。验证是否生效docker ps正常情况下会列出一个空的容器列表不报任何错误。如果依然报permission denied可以再试一次newgrp docker命令这个命令会临时切换当前会话的主组也能让权限生效不过后续终端要重新开启才能永久保持。5. 实测中的常见问题与我的排错思路再顺手的安装流程在真实环境里也会遇到幺蛾子。这里把我在不同 Ubuntu 版本上安装 Docker 时遇到的三个典型问题整理出来每个都附上完整排查过程希望能帮你省掉瞎试的时间。5.1 网络超时与镜像加速的取舍现象执行sudo docker pull时一直卡在Waiting或直接Get https://registry-1.docker.io/v2/: net/http: request canceled。我当时的排查顺序是先ping google.com测网络通断再用curl -I https://download.docker.com测官方下载源最后发现是默认的 Docker Hub 拉取超时。解决方案是给 daemon 配置镜像加速也就是前面提过的daemon.json。但这里有个细节值得注意加速器只能加速镜像仓库的拉取不会加速你docker build时从 GitHub 下载源码的过程。如果 build 阶段超时那是网络问题和 Docker 无关得从代理或 DNS 角度解决。我在配置daemon.json时只填一个加速器避免多个源互相切换导致拉取缓存不一致。另外写完后一定要用这个命令验证 JSON 格式sudo docker info | grep -A2 Registry Mirrors看到你自己的加速器地址就说明配置生效了。格式错误的话Docker 会直接拒绝启动日志里会报Error parsing daemon.json。5.2 存储驱动与 overlay2 的注意事项现象容器运行时报error creating overlay mount ... /var/lib/docker/overlay2: invalid argument。这个问题一般出现在特定文件系统上。Docker 默认推荐的存储驱动是overlay2但前提是宿主机文件系统是 ext4 或 xfs且开启了 d_type 支持。如果你的系统盘或者数据盘是 btrfs、zfs 或网络文件系统NFSoverlay2 可能没法正常工作。我遇到过一次是在 NFS 挂载的目录上安装 Docker当时怎么跑都报错。排查完才发现/var/lib/docker默认位于根目录而根目录被挂载成 NFS。解决办法是把 Docker 的数据根目录改到本地磁盘在daemon.json里加一行{ data-root: /data/docker }之后sudo systemctl restart docker再用sudo docker info确认Docker Root Dir已经是新路径。这种方法对数据量大的场景也比较友好毕竟系统盘空间有限把容器数据放到独立数据盘确实更稳妥。还有一点是磁盘空间不足。Ubuntu 默认的/var/lib/docker分区如果只有 20G拉几个常用镜像就满了。建议安装前检查df -h如果空间紧张提前改>sudo systemctl enable docker sudo systemctl start docker另外我养成了一个习惯每半个月检查一次 Docker 和插件的更新。Ubuntu 的 apt 源里既然配了 Docker 官方源直接sudo apt upgrade就会把docker-ce和containerd.io一起更新。更新前先备份当前运行的容器列表用docker ps -a containers-backup.txt记录一下再执行升级。实测下来Docker 的升级通常不会中断正在运行的容器但保险起见重要服务我都会提前踢下线。以上就是我在 Ubuntu 上安装 Docker 的完整记录。从环境预检、源配置、核心组件安装到用户组调整和常见问题排查每一步都有对应的原因和验证方式。我在实际使用中的体会是与其追求一键脚本的快捷不如花十分钟理解安装过程中涉及的几个关键点这样遇到异常时才能真正对症下药而不是反复重装系统。希望这篇记录能帮你省掉一些弯路如果你在安装过程中碰到其他奇奇怪怪的问题欢迎带着报错信息来交流。
延伸阅读

更多相关文章

2026/10/15 22:05:47

Qt网络上传实战:QNetworkAccessManager与multipart文件上传全解析

写 Qt 网络上传这事儿其实有点意思。很多人刚开始用 Qt 做 HTTP 请求时,第一反应是去翻 QNetworkAccessManager 的文档,然后照着示例抄一段 post() 代码,结果发现要么服务端收不到参数,要么上传大文件时界面直接卡死。这篇文章就围…

2026/10/15 22:05:47

2核4G+10M带宽云服务器:选型、部署与运维全指南

先说结论:这套配置是被无数人验证过的甜点位,但它并不是万金油。买之前如果没搞清楚自己要跑什么,再便宜的机器也是浪费;反过来,只要负载画像匹配,2核4G10M带宽跑三四个轻量服务依然游刃有余。这篇文章就围…

2026/10/15 22:05:47

装配线平衡问题的遗传算法MATLAB实现与源码解析

简介:一份用于装配生产线任务平衡问题(ALB)的遗传算法MATLAB源代码,面向工业工程、机械制造与智能计算方向的科研人员及学生。算法在陈永卿等提出的混合遗传算法基础上改进,支持任务优先矩阵、任务时间与体积属性、时间…

2026/10/15 23:16:02

从“无标题”到高效命名:项目管理的必修课

“无标题”是每天都在屏幕上出现无数次的默认词。新建文档、新建文件夹、新建画布,系统都会塞给你这三个字。很多人对它们视而不见,直接敲一个回车就开始干活。但我在做了多年项目管理之后,越来越觉得“无标题”这个东西值得认真聊聊。它不是…

2026/10/15 23:16:02

C# WebApi实战:原生WebSocket构建即时聊天与连接管理

1. 从轮询到长连接:为什么WebApi项目最终都会走到WebSocket这一步做过WebApi的人大概都有过这样的经历:项目初期用HTTP轮询做消息通知,前端每隔几秒发一次请求问“有没有新消息”。用户量小的时候一切正常,等到同时在线人数上去之…

2026/10/15 23:16:02

Open3D点云处理实战:从入门到配准重建的完整指南

1. 点云处理的入门首选:为什么我押注Open3D搞三维视觉的,绕不开点云。不管是做自动驾驶的感知模块、工业质检的缺陷检测,还是建筑扫描的逆向建模,点云处理都是核心环节。但问题来了——点云这东西不像图像那么“规整”&#xff0c…

2026/10/15 23:16:02

HarmonyOS端侧相册自然语言搜图:双塔架构与增量索引实战

1. 项目缘起与整体设计思路相册搜图这件事,听起来像是“给照片打个标签,搜的时候匹配一下”这么简单,但真把它落到端侧、落到一个资源受限的手机系统上,坑远比想象中多。我这次做的项目,核心目标很明确:在 …

2026/10/15 23:16:02

重塑矩阵:一维存储与二维输出的工程实践指南

简介:这份PDF资料围绕LeetCode矩阵重塑类题目展开,面向正在刷题、准备算法面试或学习C与MATLAB矩阵操作的开发者。它聚焦一个核心问题:如何将二维矩阵按行遍历顺序重新填充为指定行列的新矩阵,并在元素总数不匹配时返回原矩阵。资…

2026/10/15 23:11:02

Elasticsearch在Ubuntu上的完整部署指南:从环境准备到安全配置

开头最近又帮朋友在一台 Ubuntu 服务器上装了一遍 Elasticsearch,整个过程踩了几个老坑,也顺手把配置方式重新理了一遍。Elasticsearch 这套东西,在 Linux 上装起来本身不算复杂,真正麻烦的是那些系统层面的参数调整和版本匹配问题…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/15 13:42:16

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/15 0:02:22

防关联浏览器哪个好?三款产品实测差异解析

新手做多店铺,最纠结的就是防关联浏览器选哪个。飞跨、网易、站斧这三款被问得最多,先给结论:要一体化省心、长期便宜,选站斧;要网易招牌和稳,选网易;预算紧做东南亚 Lazada,选飞跨。…

2026/10/15 0:02:22

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成 一、技术背景 大模型(LLM)在通用场景下表现强大,但当我们将 GPT-4 或 Qwen 直接用于生成影刀RPA操作指令和 XPath 定位时,准确率通常只有 40%-60%。原因…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑