☰
Ubuntu 22.04 安装 Docker 完整指南:从源配置到故障排查
2026/10/19 14:41:45 网站建设 项目流程

1. 为什么要在 Ubuntu 22.04 上单独折腾 Docker 安装

如果你刚接触 Docker,可能第一反应是“apt install docker.io”一把梭。这个做法在 Ubuntu 22.04 上确实能装出能用的 Docker,但版本往往偏老,而且和官方源里的版本存在不少行为差异。我自己的经历是:某次用系统源装的 Docker,跑一个需要较新 containerd 特性的镜像时直接报错,排查半天才发现是版本太旧。从那以后我在 Ubuntu 上一律用官方 Docker 源安装,省心非常多。

这篇文章围绕 Ubuntu 22.04(代号 jammy)从零安装 Docker 的完整流程展开,覆盖软件源配置、GPG 密钥管理、核心组件安装、用户权限配置,以及最常见的几个安装报错和处理方法。适合两类人看:一类是刚接触 Linux 和 Docker 的新手,照着一步步操作就能把环境搭起来;另一类是在 Docker 安装上遇到过各种奇怪报错、想系统了解原因和解决思路的老手。

Ubuntu 22.04 是当前非常主流的 LTS 版本,docker-ce、docker-ce-cli、containerd.io 这几个核心包在官方源里都有对应构建。只要系统能正常访问外网,整个安装过程十分钟内就能完成。读完全文,你会对“为什么装 Docker 要这么几步”有清晰认识,而不是机械复制命令。

2. 安装前必须搞清楚的几个核心概念

2.1 Docker 不是“一个软件”,而是一套组件

很多人对 Docker 的理解停留在“装一个命令行工具”,其实它包含三个核心部分:Docker 客户端(docker 命令)、Docker 守护进程(dockerd)、容器运行时(containerd)。客户端负责接收你的指令,守护进程负责管理容器生命周期,containerd 则负责真正拉起和运行容器进程。三者的关系可以用一个类比来理解:客户端是前台接待,守护进程是调度中心,containerd 是一线执行人员。

Ubuntu 系统的 docker.io 包把这几个组件打包在一起,版本之间绑定较紧,升级不够灵活。官方 docker-ce 源的好处是三个组件独立发布,你可以单独升级 containerd 而不动 docker-ce,这对生产环境的灰度升级很有价值。所以在 Ubuntu 22.04 上,我更推荐通过官方源来安装。

2.2 为什么需要 config 配置文件

安装完成后,Docker 默认行为可以满足大部分场景,但有两个需求几乎所有人都会碰到:一是给 Docker 配置镜像加速,二是限制 Docker 日志大小避免磁盘被撑爆。这两个操作都要通过 /etc/docker/daemon.json 文件完成。虽然这一步看起来和“安装”关系不大,但如果你在安装完成后直接使用默认配置,后续大概率会因为镜像拉取慢或日志膨胀回来改配置,不如装完顺手就配好。

2.3 用户组与权限的关系

安装完成后执行 docker ps 如果提示 permission denied,是因为 Docker 守护进程默认以 root 权限运行,而当前用户不在 docker 用户组里。把用户加入 docker 组后,就相当于让系统认定该用户有权限访问 Docker 的套接字文件。这一步直接决定你是否需要每隔几条命令就敲一次 sudo。

3. 从零开始:Ubuntu 22.04 安装 Docker 全流程

3.1 清理旧版本残留

如果你之前用过系统源安装的 Docker,或者曾经手动装过老版本,先清理干净再装新版,避免二进制文件冲突和配置文件残留。

sudo apt remove docker docker-engine docker.io containerd runc

注意上面这条命令会保留 /var/lib/docker 目录下的镜像、容器、卷等数据。如果你确定旧数据不要了,可以一并删除目录。如果你不确定,可以先保留,新版 Docker 会尝试兼容旧数据目录。我在一次升级中遇到过数据目录权限不对导致 Docker 无法启动的情况,后面在错误处理部分会详细展开。

清理完成后执行一次 apt 更新,确保索引是最新状态。

sudo apt update

3.2 安装依赖工具包

Docker 官方仓库需要通过网络从 HTTPS 源下载密钥和软件包,所以要先装几个基础工具。

sudo apt install ca-certificates curl gnupg lsb-release

这几个包的角色分别是:ca-certificates 提供 HTTPS 证书信任链,curl 用来下载 Docker 的 GPG 密钥,gnupg 用来导入和管理密钥,lsb-release 用于识别当前系统版本代号。Ubuntu 22.04 的代号 jammy 就是通过 lsb_release -cs 命令获取的。

这一步偶尔会碰到 apt 源更新慢或者网络波动,多数情况下重试就能解决。如果反复失败,检查一下系统能否正常访问外网。

3.3 添加 Docker 官方 GPG 密钥

Docker 官方源通过 GPG 密钥对软件包签名,系统必须信任这个密钥才能正常安装。这一步最常见的坑是目录不存在,所以先创建目录再下载密钥。

sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc

解释一下这几个操作的意义。install -m 0755 -d 创建 /etc/apt/keyrings 目录并设置 0755 权限,所有用户可读可执行但只有 root 可写。curl 下载密钥时加了 -fsSL 参数,-f 表示遇到 HTTP 错误就失败退出,-sSL 表示静默模式跟随重定向。我见过有人漏掉 -S 参数,结果下载失败时没有任何错误信息,排查起来很麻烦。最后 chmod a+r 确保所有用户都能读取密钥文件,否则部分场景下 apt 会报权限错误。

3.4 写入官方软件源

创建源列表文件,把 Docker 官方 Ubuntu 源写入。这里用到了系统版本代号变量,Ubuntu 22.04 会解析为 jammy。

echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] 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 自动检测系统架构,在 22.04 上输出 amd64 或 arm64。signed-by 参数指定上一步下载的密钥文件路径。$(. /etc/os-release && echo "$VERSION_CODENAME") 会自动读取系统版本代号,如果你手动写死 jammy 也可以,但用变量能保证脚本在不同 Ubuntu 版本上通用。

写入后执行更新:

sudo apt update

如果这一步报错提示 GPG 错误,大概率是密钥路径写错或密钥文件权限不对,回到 3.3 节检查。

3.5 安装 Docker 核心组件

现在进入真正的安装环节。执行下面的命令安装最新版 Docker 引擎和相关组件。

sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

比老教程多了 docker-buildx-plugin 和 docker-compose-plugin,前者是 Docker 的 BuildKit 构建插件,后者是 Docker Compose。以前 compose 需要单独装 docker-compose,现在官方直接把 compose v2 插件化,一条命令全搞定。

安装过程中如果提示有配置文件需要选择,通常会问你是否保留当前版本配置,直接选择保留即可。等待安装完成后,执行以下命令验证安装状态。

sudo docker --version

看到版本号输出,说明客户端安装成功。再执行 sudo systemctl status docker 查看守护进程状态,如果显示 active (running),说明服务已经启动。Ubuntu 22.04 上 Docker 安装包会自动完成 systemd 服务注册和开机自启配置,不需要手动设置。

3.6 验证容器运行

前面几步做完,Docker 已经能用了,但一定要跑一个实际容器确认整个链路通畅。最经典的验证方式是运行 hello-world 镜像。

sudo docker run hello-world

这一步会先从 Docker Hub 拉取 hello-world 镜像,然后启动容器输出一段说明文字。看到输出说明 Docker 的拉取、镜像管理、容器创建、容器执行整个链路都是通的。

如果这一步卡住不动,十有八九是网络问题。新版 Docker 默认从 Docker Hub 拉取镜像,国内网络环境下经常超时。解决办法是先配置镜像加速,然后重新执行。加速配置方法在下一节详细讲。

4. 安装后的核心配置:让 Docker 更好用

4.1 配置镜像加速

镜像加速不是 Docker 的强制配置,但没有它,在国内网络环境下拉取镜像经常失败或者慢到没法用。Docker 支持在 daemon.json 中配置多个镜像加速地址,拉取镜像时会按顺序尝试。

sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://docker.m.daocloud.io"] } EOF

修改配置文件后,重启 Docker 使配置生效。

sudo systemctl daemon-reload sudo systemctl restart docker

注意一个细节:daemon.json 必须是合法的 JSON 格式,配置写错了 Docker 守护进程可能启动失败。写完配置文件后可以用以下命令验证 JSON 格式是否正确。

cat /etc/docker/daemon.json | python3 -m json.tool

我自己就踩过这个坑,少写了一个逗号导致整个 Docker 服务起不来,系统日志里报了一大串 JSON 解析错误。格式化校验一下能省很多排查时间。

4.2 添加用户到 docker 组

每次敲 docker 命令都要加 sudo 很烦,把当前用户加入 docker 用户组之后,就不需要 sudo 了。

sudo usermod -aG docker $USER newgrp docker

第一条命令把当前用户追加到 docker 组。-aG 两个参数合在一起表示“追加到组”,如果漏了 -a,用户会被移出其他所有组,这是个需要特别注意的坑。newgrp docker 让当前终端会话立即切换用户组,不需要退出重新登录。

配置完成后执行 docker ps 验证,不报权限错误就说明成功了。注意 docker 用户组等同于 root 权限,任何加入该组的用户都能操控容器和宿主机文件系统。生产环境服务器上添加用户要严格控制,不要图方便把不相关的人加进去。

4.3 配置日志大小上限

Docker 默认对容器日志不设上限,一个日志量大的容器可以轻松把磁盘写满。这个问题的隐蔽性在于它不会立刻暴露,往往等磁盘爆了才发现是某个容器的日志文件占了几个 G。在 daemon.json 里加上 log 配置可以全局限制日志文件大小和数量。

sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://docker.m.daocloud.io"], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } } EOF

max-size 10m 表示单个日志文件最大 10MB,max-file 3 表示最多保留 3 个文件。超过限制后 Docker 会自动清理旧日志。重启 Docker 后配置生效。

有两个注意点。一是这个配置只对之后创建的容器生效,已经存在的容器要重建才会应用新日志策略。二是部分第三方应用会往容器内写大量日志,这个配置能防住磁盘被写满,但不能解决应用本身的日志刷屏问题,后者需要从应用层面处理。

4.4 设置 Docker 开机自启

Ubuntu 22.04 上 Docker 安装包默认设置了开机自启,但如果你在安装过程中手动改过服务状态,可能需要重新确认。

sudo systemctl enable docker.service sudo systemctl enable containerd.service

这两条命令确保 Docker 守护进程和 containerd 在系统重启后自动运行。服务器断电重启后不用手动敲 systemctl start docker,省掉很多麻烦。

5. 常见错误与故障排查实录

5.1 安装时报错:GPG error 或 NO_PUBKEY

这个错误在添加 Docker 源之后执行 apt update 时经常出现。报错信息通常包含 NO_PUBKEY 和一串十六进制密钥 ID,根本原因是 apt 找不到对应的 GPG 公钥。

我遇到的情况里,常见原因有三个。一是密钥下载失败或下载了空文件,curl 没加 -f 参数时服务器返回 404 也会保存一个 HTML 文件到本地,apt 读取时自然报错。二是密钥路径写错,比如把密钥放在 /etc/apt/keyrings 下,但源列表里的 signed-by 参数写成了别的位置。三是权限问题,普通用户无法读取密钥文件导致 apt 校验失败。

处理办法是删除旧的密钥和源列表配置,按照 3.3 和 3.4 节的步骤重新执行一遍,并确认密钥文件路径和源列表的 signed-by 参数完全一致。在 Ubuntu 22.04 上不建议再用 apt-key 命令,这个命令在新版 apt 中已经标记为 deprecated,后续版本会移除。

5.2 安装依赖时报错:无法满足依赖关系

安装 docker-ce 时可能提示依赖关系无法满足,通常涉及到 libc6 版本过低或者 containerd.io 冲突。Ubuntu 22.04 的基础依赖一般没问题,更多的情况是系统里已经存在旧版 containerd,比如通过其他途径安装过。

处理思路是先把旧版 containerd 删除,再执行安装。sudo apt remove containerd 然后 sudo apt install docker-ce docker-ce-cli containerd.io。如果系统提示某些包需要先升级 libc6,可以执行 sudo apt upgrade 把基础系统更新一遍再重试。在服务器上执行 apt upgrade 前要注意业务影响,如果这台服务器正跑着生产服务,最好在维护窗口操作。

5.3 docker ps 报错:permission denied

新装好的 Docker 执行 docker ps 报权限错误,这是新手最常遇到的情况。错误信息显示无法连接 /var/run/docker.sock,提示 permission denied。

原因很简单:当前用户不在 docker 用户组,没有权限访问 Docker 守护进程的 Unix 套接字。执行 4.2 节的两条命令即可解决。如果加了组还是不行,检查用户是否真的在 docker 组中:

groups $USER

输出列表里包含 docker 才说明组添加成功。如果不在,重新执行 usermod 命令,然后注销重新登录或者再执行一次 newgrp docker。

5.4 Docker 启动失败:daemon.json 配置错误

修改 /etc/docker/daemon.json 后重启 Docker,结果服务起不来,systemctl status 显示 failed。最常见的错误是 JSON 格式不合法,比如少逗号、多逗号、引号不匹配。

排查方法分两步。第一步看错误日志,sudo journalctl -u docker.service --no-pager | tail -50,日志里通常会直接提示 JSON 解析错误的具体位置。第二步校验 JSON 格式,用前面提到的 python3 -m json.tool 命令,快速定位语法问题。修好后重新 daemon-reload 和 restart。

另一种情况是配置了多个镜像加速地址,其中一个失效不影响 Docker 启动,但拉取镜像时会按顺序依次尝试,失败会浪费时间。建议只保留两三个稳定可用的镜像加速地址。

5.5 docker pull 超时或找不到镜像

镜像拉取超时基本是网络问题。除了配置镜像加速,还有几个可以尝试的思路。一是检查 DNS 配置,有时候系统 DNS 不稳定会导致域名解析超时,可以在 /etc/docker/daemon.json 中给 Docker 单独指定 DNS 服务器:

{ "dns": ["223.5.5.5", "8.8.8.8"] }

二是给 Docker 配置 HTTP 代理。如果所在网络环境需要通过代理访问外网,Docker 不会自动读取系统环境变量,需要在 /etc/systemd/system/docker.service.d/ 下创建配置文件写入代理信息。配置完同样需要 daemon-reload 和 restart。

5.6 存储驱动错误:overlay2 不支持

启动容器时报错提示 storage-driver 不兼容,多半是因为宿主机文件系统格式不支持 overlay2。overlay2 是 Docker 默认推荐使用的存储驱动,需要宿主机内核支持 OverlayFS。常见的不支持场景是根分区使用了不兼容的文件系统,或者内核版本太老。

Ubuntu 22.04 默认内核完全支持 overlay2,理论上不会遇到这个问题。如果你是在虚拟化环境或者容器内嵌套安装 Docker,可能出现 overlay2 不可用。最简单的绕行方案是切换存储驱动为 vfs,但这会显著降低性能,生产环境不建议使用。校验内核是否支持 overlay,可以执行 mount -t overlay overlay /tmp/test 临时测试,能挂载成功说明内核支持。如果是文件系统问题,考虑把 Docker 数据目录迁移到支持 overlay 的分区。

5.7 apt 锁等待超时

执行 apt install 时提示无法获取锁,说明系统里已有其他 apt 进程在运行。常见的场景是自动更新服务后台触发了 apt 升级,或者之前的 apt 进程异常退出没释放锁。

等一两分钟再试,或者检查是否有残留的 apt 进程:

ps aux | grep apt

确认没有在运行的 apt 进程后,可以删除锁文件。sudo rm /var/lib/dpkg/lock-frontend。删除锁文件是最后手段,如果有进程还在运行,强制删锁可能导致 dpkg 状态损坏,尽量先等或者终止冲突进程。

5.8 Docker 数据目录迁移

Docker 默认把镜像、容器数据放在 /var/lib/docker。如果系统盘空间不够,比如根分区只有 20G,而你需要拉的镜像动辄几个 G,很快就会撑满。这时候把 Docker 数据目录迁移到大容量磁盘是常用方案。

操作步骤是先把 Docker 服务停掉,移动数据目录到新位置,在 daemon.json 中指定>sudo systemctl stop docker sudo mv /var/lib/docker /data/docker

编辑 /etc/docker/daemon.json 添加>{ "data-root": "/data/docker" }

然后重启服务:

sudo systemctl daemon-reload sudo systemctl start docker

执行 docker images 确认之前的镜像还在,说明迁移成功。数据迁移过程中的风险点是新旧目录的权限不一致,如果容器报找不到目录或权限错误,检查新目录的属主和权限是否和原目录一致。

6. 安装完成后的功能验证与性能优化

6.1 用 nginx 容器做一次完整验证

hello-world 容器验证了基本链路,但如果你要确认端口映射、文件挂载这些功能是否正常,建议再跑一个 nginx 容器。

docker run -d --name test-nginx -p 8080:80 nginx:alpine

这条命令的含义是以后台模式启动一个名为 test-nginx 的容器,把宿主机的 8080 端口映射到容器内的 80 端口。等几秒钟让 nginx 完成启动,然后访问 http://localhost:8080,看到 nginx 欢迎页说明端口映射正常。验证完删除容器:

docker rm -f test-nginx

这一步能验证端口映射、镜像拉取、容器生命周期管理、服务网络连通性几个核心功能,比 hello-world 更有参考价值。

6.2 调整 Docker 资源占用

Docker 默认会占用系统资源用于日志处理和镜像管理。对于一些配置较低的 VPS 或开发机,可以做几项常规优化。

关闭不必要的 Docker 网络特性能降低部分资源占用。如果你只是本地开发使用,不需要跨主机容器通信,可以在 daemon.json 中加入 iptables 和 bridge 配置调整。但直接在 daemon.json 中关闭 iptables 容易出现容器网络异常,建议非必要不调整。

更常规的做法是限制容器系统资源,当运行容器时通过 --memory 和 --cpus 参数控制资源使用上限。这个方法适用于单容器场景。全局层面,可以通过 docker system prune 定期清理不用的镜像、容器、网络和构建缓存。定期清理是保持 Docker 环境健康最简单也最有效的手段。

docker system prune -a --volumes

注意这条命令会清除所有未使用的镜像和数据卷,执行前确认没有需要保留的容器数据。

6.3 升级 Docker 版本的实操方法

Docker 的版本升级其实和安装一样,更新软件源索引后直接 apt upgrade 就行。但生产环境中升级 Docker 要注意版本跨度,跨大版本升级前先查一下官方更新日志。

对于 Ubuntu 22.04 和 Docker 官方源,常规的升级路径是:

sudo apt update sudo apt upgrade docker-ce docker-ce-cli containerd.io

升级前先备份重要容器的数据卷,尤其是数据库容器的数据。升级过程中 Docker 服务会自动重启,所有运行中的容器会中断。如果你用的是 docker compose 管理服务,升级完执行 docker compose up -d 重新拉起即可。

我自己的实践是把 alpha 和 beta 版本的 docker-ce 包分开安装,避免 apt 把测试版当成 Stable 自动升级。在 /etc/apt/preferences.d/ 下创建 pin 配置可以锁定版本。如果你的环境以稳定性优先,这一步值得做。

7. 最后的几个实操建议

我在反复安装和排障中积累了几个值得分享的习惯。第一个习惯是安装前先把系统 apt 源换成国内镜像源,因为官方源在部分地区速度不稳定,影响的不只是 Docker 安装,还影响系统依赖包的安装速度。装上之后 Docker 镜像加速基本能覆盖大部分拉取需求。

第二个习惯是安装后马上验证 dockerd 的开机自启。有些人装完 Docker 把服务器重启一次,结果发现 Docker 没起来,还得手动启动。Ubuntu 22.04 上 Docker 服务默认自启,但如果你执行过 systemctl disable 把自启关了,重启后就会遇到这个问题。

第三个习惯是把常用的 Docker 配置命令写成一份初始化脚本,比如用户组添加、日志限制、数据目录迁移、镜像加速配置。这样新机器上几分钟就能完成标准环境搭建,不用重复踩坑。实际使用中这个脚本帮我节省了大量重复工作。

关于 Ubuntu 22.04 安装 Docker 的流程和问题排查就聊到这里。如果你在安装过程中遇到本文没覆盖到的错误,先看 journalctl -u docker.service 的日志,日志里的提示几乎总能告诉你问题出在哪一步。版本选择上,Ubuntu 22.04 本身很稳定,Docker 的长期支持版本配上 LTS 系统,可以保持相当长时间不用大动作升级。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询