1. 项目概述:为什么在 Ubuntu 22.04 上装 Docker 不是“点几下就完事”的事

Docker、ubuntu22、docker-ce——这三个词凑在一起,表面看就是一条标准的 Linux 环境部署流水线,但实际踩进去才发现,它根本不是教科书里“更新源→安装包→启动服务”三步走的童话。我去年在三台不同配置的 Ubuntu 22.04 服务器上重装 Docker,一次成功的是那台刚重装系统的干净虚拟机;另两台——一台跑着 Nginx 和 NetBox 的生产边缘节点,另一台装过 Kylin 10 兼容层又切回原生 Ubuntu 的开发机——全卡在 dockerd 启动失败或 docker-compose up unable to get image 'mysql:8.0.34' 这类看似网络问题、实则根子在底层依赖错位的坑里。这不是 Docker 本身的问题,而是 Ubuntu 22.04 这个发行版在内核、cgroup v2、systemd、containerd.io 版本演进节奏上的“错峰上线”带来的真实摩擦。

很多人搜“ubuntu22 安装 docker”,真正想解决的从来不是“怎么装”,而是“装完之后 docker ps 能看到容器、docker-compose up -d 能拉镜像、容器里 nginx 能响应请求、MySQL 能连上”。这背后牵扯到五个不可绕过的硬性条件:内核必须启用 CONFIG_CGROUPS=y CONFIG_NAMESPACES=y (Ubuntu 22.04 默认满足,但某些定制内核或 Kylin 10 兼容层会阉割); containerd.io 必须与 docker-ce 主版本严格对齐(比如 docker-ce 24.0.7 只认 containerd.io 1.6.31,混用 1.7.x 就会静默崩溃);APT 源必须指向官方或可信镜像站(国内用户若直接用默认 archive.ubuntu.com ,常因 DNS 劫持导致 apt update 卡在 Reading package lists... ); /etc/docker/daemon.json 若存在,哪怕只有一行空格,也可能让 dockerd 拒绝启动;最后, docker-compose 已于 2023 年底正式脱离 Python 生态,v2.20+ 是纯 Go 编译的二进制,和旧版 docker-compose (Python 实现)完全不兼容——你 apt install docker-compose 装出来的,极大概率是已废弃的 v1.x,而 docker-compose up 报错 command not found version mismatch ,根源就在这里。

所以这篇内容不是“Docker 安装教程”,而是“Ubuntu 22.04 上 Docker 生产级可用环境的构建手记”。它覆盖从卸载残留、验证内核、选择源、校验签名、安装顺序、配置调优、到 compose 替代方案的全链路。你会看到为什么 curl -fsSL https://get.docker.com | sh 在 Ubuntu 22.04 上可能比手动安装更危险;为什么 apt install docker.io 是最省事却最不推荐的方案;以及当 docker-compose up unable to get image 时,90% 的情况根本不用查代理或镜像仓库,只需执行一条 sudo systemctl status containerd 就能定位到 containerd 进程是否真的在跑。它面向的是已经能 ssh ubuntu@server 、会 vim /etc/apt/sources.list 、知道 journalctl -u docker 查日志的中级 Linux 使用者,目标很明确:装完就能用,且后续三个月不因 Docker 自身问题重启服务器。

2. 核心细节解析与实操要点:Ubuntu 22.04 的 Docker 安装不是“一键式”,而是“五步校验式”

在 Ubuntu 22.04 上安装 Docker,核心矛盾在于“官方文档的通用性”和“Ubuntu 22.04 发行版特性的冲突”。官方 Docker 文档(https://docs.docker.com/engine/install/ubuntu/)写得非常严谨,但它默认你操作的是一个全新、未修改、未安装过任何容器相关组件的系统。而现实中的 Ubuntu 22.04,可能是从 20.04 升级而来,可能预装了 docker.io (社区维护版),可能被 ubuntu-desktop 带来的 snap 版 Docker Desktop 干扰,甚至可能因为之前尝试安装 Kylin 10 兼容层而残留了 libseccomp2 的降级包。因此,真正的安装流程必须前置五步强制校验,缺一不可。

2.1 第一步:彻底清理历史残留,比安装更重要

很多 dockerd 启动失败、 docker version Cannot connect to the Docker daemon 的问题,根源都在 /var/lib/docker/ 目录或 /etc/docker/ 下的残余配置。但直接 rm -rf /var/lib/docker 是灾难性的——它会删除所有你辛苦构建的镜像、运行中的容器数据卷。正确做法是分层清理:

首先,停止所有 Docker 相关服务:

sudo systemctl stop docker docker.socket containerd
sudo systemctl disable docker docker.socket containerd

其次,卸载所有已知的 Docker 包,包括 docker.io (Ubuntu 官方仓库提供的轻量版)、 docker-ce (Docker Inc. 官方版)、 docker-ce-cli (命令行工具)、 containerd.io (容器运行时):

sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker.io
sudo apt-get autoremove -y --purge

提示: apt-get purge 会同时删除配置文件,这是关键。如果只用 apt-get remove /etc/docker/daemon.json 这类配置文件会保留,成为后续启动失败的隐形炸弹。

然后,手动清理残留目录和二进制:

sudo rm -rf /var/lib/docker /var/lib/containerd /var/run/docker.sock /etc/docker
# 清理可能存在的 snap 安装(Ubuntu Desktop 用户尤其注意)
sudo snap remove docker 2>/dev/null || true

最后,验证清理是否干净:

dpkg -l | grep -i docker  # 应该无输出
ls -la /usr/bin/docker*  # 应该只显示 /usr/bin/docker(来自 docker-ce-cli)或无输出

这一步耗时约 2 分钟,但它能避免你后面花 2 小时排查一个本可避免的权限或配置冲突问题。我见过太多人跳过此步,结果 docker info 显示 WARNING: No swap limit support ,以为是内核问题,其实是 /var/lib/docker 下旧版 overlay2 驱动残留导致的元数据损坏。

2.2 第二步:内核与系统准备,Ubuntu 22.04 的 cgroup v2 是把双刃剑

Ubuntu 22.04 默认使用 cgroup v2,这是 Linux 内核 5.8+ 引入的统一控制组接口,相比 cgroup v1 更简洁、更安全。Docker 20.10+ 完全支持 cgroup v2,但有一个致命前提: containerd.io 必须是 1.4.0+ 版本,且 dockerd 启动参数不能显式禁用它。问题在于,某些老旧的 containerd.io 包(如 Ubuntu 22.04 仓库里的 containerd.io=1.5.9-1 )在 cgroup v2 环境下会因 runc 版本不匹配而静默退出。

验证你的系统是否真正启用了 cgroup v2:

# 查看当前挂载点
mount | grep cgroup
# 正常输出应包含:cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
# 如果看到大量 cgroup on /sys/fs/cgroup/xxx type cgroup (rw,nosuid,nodev,noexec,relatime,xxx),说明是 cgroup v1 模式

# 查看内核启动参数(关键!)
cat /proc/cmdline | grep cgroup
# 正常应为:... systemd.unified_cgroup_hierarchy=1 ...
# 如果出现 cgroup_no_v1=all 或 cgroup_enable=memory,则说明被强制降级到 v1,需修改 GRUB

如果你的系统是 cgroup v1 模式(常见于从 20.04 升级上来的系统),有两种选择:一是升级内核到 5.15+ 并启用 systemd.unified_cgroup_hierarchy=1 (推荐,长期稳定);二是临时切换到 cgroup v2,只需编辑 /etc/default/grub

sudo nano /etc/default/grub
# 修改这一行:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash systemd.unified_cgroup_hierarchy=1"
sudo update-grub && sudo reboot

注意:不要盲目添加 cgroup_enable=memory 。Ubuntu 22.04 的 systemd 249+ 已默认启用 memory controller,强行添加反而可能导致 systemd 启动失败。真正的检查点是 systemd.unified_cgroup_hierarchy=1 是否生效。

2.3 第三步:APT 源选择与密钥管理,国内用户绕不开的“镜像站陷阱”

Ubuntu 22.04 的默认 APT 源 archive.ubuntu.com 对国内用户并不友好,DNS 解析慢、连接超时是常态。但直接替换为 mirrors.aliyun.com mirrors.tuna.tsinghua.edu.cn 也有风险:这些镜像站同步官方源有延迟(通常 1-2 小时),而 Docker 官方包的发布是原子性的—— docker-ce docker-ce-cli containerd.io 必须版本严格匹配。如果镜像站只同步了 docker-ce=24.0.7 ,但 containerd.io 还停留在 1.6.28 ,你 apt install docker-ce 就会因依赖不满足而失败。

我的实测方案是“混合源”:基础系统包走国内镜像,Docker 官方包走 Docker 自己的 APT 仓库。这样既保证速度,又确保版本一致性。

首先,备份并替换系统源(以清华源为例):

sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo apt update

然后,添加 Docker 官方 GPG 密钥和仓库(这是最易出错的一步,必须严格按顺序):

# 下载并安装 Docker 的官方 GPG 密钥(注意:必须用 curl -fsSL,wget 可能因证书问题失败)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 添加 stable 仓库(注意:[arch=amd64] 是必须的,否则 arm64 机器会报错)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

关键原理: /usr/share/keyrings/ 是 systemd 220+ 引入的标准化密钥存储路径,比旧版 /etc/apt/trusted.gpg.d/ 更安全。 signed-by= 参数指定了该仓库的密钥位置, apt 会严格校验每个包的签名。如果跳过 gpg --dearmor 步骤,直接 apt-key add ,在 Ubuntu 22.04 上会收到 WARNING: apt-key is deprecated ,且未来版本将完全失效。

验证仓库是否添加成功:

apt-cache policy docker-ce
# 输出中应看到:500 https://download.docker.com/linux/ubuntu jammy/stable amd64 Packages
# 且 Candidate 版本是你想要的(如 24.0.7~ubuntu.22.04.1)

2.4 第四步:安装顺序与版本锁定,containerd.io 是 Docker 的“心脏”

Docker 的架构是分层的: dockerd (守护进程)负责 API 和编排; containerd (运行时)负责镜像拉取、容器生命周期管理; runc (运行时)负责真正创建和运行容器进程。其中 containerd.io 是承上启下的核心,它的稳定性直接决定整个 Docker 是否可用。

官方文档建议 apt install docker-ce docker-ce-cli containerd.io 一行安装,但在 Ubuntu 22.04 上,我强烈建议分步、显式指定版本安装,理由有三:第一, apt install 默认会安装 docker-ce 的最新版,但 containerd.io 可能因依赖关系被降级;第二, docker-ce-cli docker-ce 的版本号虽一致,但它们的 .deb 包是独立构建的,必须确保 apt 选中的是同一发布周期的包;第三, containerd.io 的版本号(如 1.6.31-1 )和 docker-ce (如 24.0.7-1 )没有数学关系,只能查官方发布页确认。

我的实操步骤(以 2023 年 10 月发布的 24.0.7 为例):

# 更新索引
sudo apt update

# 查看可用版本(关键!)
apt list -a docker-ce docker-ce-cli containerd.io

# 输出类似:
# docker-ce/jammy 5:24.0.7-1~ubuntu.22.04.1 amd64
# docker-ce-cli/jammy 5:24.0.7-1~ubuntu.22.04.1 amd64
# containerd.io/jammy 1.6.31-1 amd64

# 严格按此版本号安装(注意:containerd.io 的版本号是 1.6.31-1,不是 1.6.31)
sudo apt install -y docker-ce=5:24.0.7-1~ubuntu.22.04.1 docker-ce-cli=5:24.0.7-1~ubuntu.22.04.1 containerd.io=1.6.31-1

# 安装后立即验证 containerd 是否正常
sudo systemctl start containerd
sudo systemctl status containerd  # 必须显示 active (running)

实操心得:如果 systemctl status containerd 显示 failed ,90% 的原因是 containerd.io 版本与 docker-ce 不匹配。此时不要 apt install --reinstall ,而是先 sudo journalctl -u containerd -n 50 查看错误日志,通常会看到 failed to load plugin io.containerd.runtime.v1.linux runc: symbol lookup error ,这直接指向 runc 二进制版本不兼容。解决方案是下载对应版本的 runc 二进制(https://github.com/opencontainers/runc/releases), sudo cp runc /usr/sbin/runc 替换。

2.5 第五步:docker-compose 的“去 Python 化”,v2.20+ 是唯一正解

这是 Ubuntu 22.04 用户最容易栽跟头的地方。搜索“docker-compose 下载”、“docker-compose 安装”,大量教程还在教你 pip install docker-compose ,这在 2023 年已是技术债。Docker Inc. 已于 2023 年 7 月宣布 docker-compose (Python 版)进入 EOL(End of Life),所有新功能、安全补丁只提供给 docker compose (Go 版,即 docker-compose-plugin )。

docker-compose (Python)和 docker compose (Go)的区别,远不止名字多一个空格:

  • 启动方式 :前者是独立命令 docker-compose up ;后者是 docker 的子命令 docker compose up
  • 依赖 :前者需要 Python 3.6+ 和一堆 pip 包;后者是单个静态二进制,无外部依赖
  • 性能 :后者启动速度快 3-5 倍,内存占用低 60%
  • 兼容性 :后者完全兼容 docker-compose.yml 语法,但 env_file profiles 等高级特性支持更完善

在 Ubuntu 22.04 上,正确安装 docker compose 插件的方法只有一种:

# 确保 docker-ce-cli 已安装(前面已做)
# 下载最新 release(以 v2.23.0 为例,需替换为实际最新版)
DOCKER_COMPOSE_VERSION=v2.23.0
curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /tmp/docker-compose
sudo mv /tmp/docker-compose /usr/libexec/docker/cli-plugins/docker-compose
sudo chmod +x /usr/libexec/docker/cli-plugins/docker-compose

# 验证
docker compose version  # 输出应为 Docker Compose version v2.23.0

注意:插件路径必须是 /usr/libexec/docker/cli-plugins/ ,这是 docker CLI 的硬编码插件目录。放在 /usr/local/bin/ docker compose 会找不到。另外, docker-compose (Python)和 docker compose (Go)可以共存,但 which docker-compose 会优先返回 /usr/bin/docker-compose (Python 版),所以建议卸载 Python 版: pip uninstall docker-compose

3. 实操过程与核心环节实现:从零开始构建一个“开箱即用”的 Ubuntu 22.04 Docker 环境

现在,我们把前两节的所有校验、清理、安装逻辑,整合成一份可直接复制粘贴、逐行执行的完整脚本。这不是一个“理想化”的流程,而是我在三台不同场景的 Ubuntu 22.04 机器上反复验证、调整后的“最小可行路径”。它包含了所有关键检查点、错误处理和 fallback 方案,确保即使某一步失败,你也能立刻知道原因并手动修复。

3.1 完整自动化安装脚本(含错误捕获与诊断)

请将以下内容保存为 install-docker-ubuntu22.sh ,然后 chmod +x install-docker-ubuntu22.sh && sudo ./install-docker-ubuntu22.sh 执行:

#!/bin/bash
set -e  # 任何命令失败即退出

echo "=== 步骤 1:验证系统信息 ==="
if ! command -v lsb_release &> /dev/null; then
    echo "错误:lsb_release 未安装,请先运行 'sudo apt update && sudo apt install -y lsb-release'"
    exit 1
fi
UBUNTU_VERSION=$(lsb_release -rs)
if [[ "$UBUNTU_VERSION" != "22.04" ]]; then
    echo "警告:检测到 Ubuntu $UBUNTU_VERSION,本脚本专为 22.04 设计,继续执行需自行承担风险"
    read -p "是否继续?(y/N): " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        exit 1
    fi
fi

echo "=== 步骤 2:彻底清理历史 Docker ==="
sudo systemctl stop docker docker.socket containerd 2>/dev/null || true
sudo systemctl disable docker docker.socket containerd 2>/dev/null || true
sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker.io 2>/dev/null || true
sudo apt-get autoremove -y --purge 2>/dev/null || true
sudo rm -rf /var/lib/docker /var/lib/containerd /var/run/docker.sock /etc/docker 2>/dev/null || true
sudo snap remove docker 2>/dev/null || true

echo "=== 步骤 3:配置国内 APT 源(清华) ==="
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list
sudo apt update

echo "=== 步骤 4:添加 Docker 官方 APT 仓库 ==="
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

echo "=== 步骤 5:安装指定版本的 Docker 组件 ==="
# 获取最新稳定版(动态查询,避免硬编码)
DOCKER_CE_VERSION=$(apt list -a docker-ce 2>/dev/null | grep -E '^[^[:space:]]' | head -1 | awk '{print $2}' | cut -d'-' -f1)
if [[ -z "$DOCKER_CE_VERSION" ]]; then
    echo "错误:无法从 APT 获取 docker-ce 版本,请检查网络和仓库配置"
    exit 1
fi
echo "检测到 docker-ce 最新版本: $DOCKER_CE_VERSION"

# 安装 docker-ce, docker-ce-cli, containerd.io(严格匹配)
sudo apt install -y "docker-ce=$DOCKER_CE_VERSION-*" "docker-ce-cli=$DOCKER_CE_VERSION-*" containerd.io

echo "=== 步骤 6:启动并验证 containerd ==="
sudo systemctl start containerd
if ! sudo systemctl is-active --quiet containerd; then
    echo "错误:containerd 启动失败!请运行 'sudo journalctl -u containerd -n 50' 查看日志"
    exit 1
fi

echo "=== 步骤 7:启动 Docker 服务 ==="
sudo systemctl start docker
if ! sudo systemctl is-active --quiet docker; then
    echo "错误:docker 服务启动失败!请运行 'sudo journalctl -u docker -n 50' 查看日志"
    exit 1
fi

echo "=== 步骤 8:安装 docker compose 插件(Go 版) ==="
# 获取最新 docker compose 版本(GitHub API)
LATEST_COMPOSE=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [[ -z "$LATEST_COMPOSE" ]]; then
    LATEST_COMPOSE="v2.23.0"  # fallback
fi
echo "安装 docker compose 插件: $LATEST_COMPOSE"
curl -L "https://github.com/docker/compose/releases/download/$LATEST_COMPOSE/docker-compose-$(uname -s)-$(uname -m)" -o /tmp/docker-compose
sudo mkdir -p /usr/libexec/docker/cli-plugins
sudo mv /tmp/docker-compose /usr/libexec/docker/cli-plugins/docker-compose
sudo chmod +x /usr/libexec/docker/cli-plugins/docker-compose

echo "=== 步骤 9:添加当前用户到 docker 组(免 sudo) ==="
sudo usermod -aG docker $USER
echo "注意:请注销并重新登录,或运行 'newgrp docker' 使组生效"

echo "=== 步骤 10:最终验证 ==="
echo "1. 检查 Docker 版本:"
docker --version
echo "2. 检查 Docker Compose 版本:"
docker compose version
echo "3. 运行 Hello World 测试:"
docker run --rm hello-world 2>/dev/null | grep "Hello from Docker!"
if [[ $? -eq 0 ]]; then
    echo "✅ 安装成功!Docker 环境已就绪。"
else
    echo "❌ Hello World 测试失败,请检查网络和镜像仓库配置。"
fi

这个脚本的核心价值在于它的“防御性编程”:

  • set -e 确保任何一步失败立即终止,避免错误累积;
  • 每个 sudo systemctl is-active --quiet 都是关键健康检查点,失败即给出明确的 journalctl 排查指令;
  • docker run --rm hello-world 是终极验证,它不仅测试 dockerd 是否运行,还测试了 containerd 的镜像拉取、 runc 的容器创建、以及网络是否通畅;
  • 所有 curl 命令都加了 -s (静默)和 -L (跟随重定向),避免因 GitHub API 限流或 CDN 重定向导致失败。

3.2 配置调优:让 Docker 在 Ubuntu 22.04 上真正“生产就绪”

装完只是起点,要让它稳定、高效、安全地运行,必须进行几项关键配置。这些配置不是“锦上添花”,而是解决 Ubuntu 22.04 特有痛点的刚需。

3.2.1 配置镜像加速器(解决 unable to get image 的首要方案)

国内用户 docker pull 卡住、 docker-compose up unable to get image 'mysql:8.0.34' ,90% 的原因不是网络问题,而是默认的 docker.io 镜像仓库(即 registry-1.docker.io )在国内访问极不稳定。解决方案是配置国内镜像加速器,如阿里云、腾讯云、中科大等。

创建 /etc/docker/daemon.json (注意:文件必须存在,且 JSON 格式严格):

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://<your-aliyun-mirror-id>.mirror.aliyuncs.com",
    "https://mirror.ccs.tencentyun.com",
    "https://docker.mirrors.ustc.edu.cn"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF

如何获取你的阿里云镜像加速器地址?登录 https://cr.console.aliyun.com → “镜像工具” → “镜像加速器”,复制那个 https://xxxx.mirror.aliyuncs.com 地址。不要用公共地址,否则会被限速。

配置后,必须重启 dockerd

sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证是否生效
sudo docker info | grep "Registry Mirrors" -A 3
3.2.2 启用 cgroup v2 的 memory controller(解决 WARNING: No swap limit support

Ubuntu 22.04 默认启用 cgroup v2,但 memory controller 可能被禁用,导致 docker stats 无法显示内存使用, docker run -m 512m 无效。检查:

cat /proc/cgroups | grep memory
# 正常应显示:memory  11  1  1 (第三个字段为 1 表示启用)

如果第三列为 0,需启用:

# 编辑 GRUB 配置
echo 'GRUB_CMDLINE_LINUX_DEFAULT="quiet splash systemd.unified_cgroup_hierarchy=1 cgroup_enable=memory swapaccount=1"' | sudo tee -a /etc/default/grub
sudo update-grub && sudo reboot
3.2.3 配置 rootless Docker(可选,提升安全性)

对于非生产环境或个人开发, rootless 模式能极大提升安全性——Docker 守护进程不再以 root 身份运行,容器也无法获得宿主机 root 权限。Ubuntu 22.04 原生支持:

# 安装 rootless 工具
sudo apt install -y uidmap

# 初始化 rootless daemon
dockerd-rootless-setuptool.sh install

# 启动
systemctl --user start docker

# 设置开机自启(需登录用户)
systemctl --user enable docker

注意:rootless 模式下, docker 命令需通过 systemctl --user 启动,且 docker.sock 位于 $XDG_RUNTIME_DIR/docker.sock ,普通 sudo docker 无法连接。它适合开发,但不适合需要 --privileged 或访问 /dev 设备的场景(如宇树 G1 机器人放音频,就需要 --device /dev/snd ,rootless 不支持)。

3.3 实战案例:用 docker-compose 部署一个可访问的 Nginx + MySQL 环境

安装完成,我们来做一个真实场景的验证:部署一个 ubuntu22 安装nginx ubuntu22 安装hermes (Hermes 是一个轻量级 API 网关,常用于微服务)的组合。这能覆盖网络、存储、环境变量、健康检查等核心概念。

创建 docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:1.25-alpine
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./html:/usr/share/nginx/html:ro
    depends_on:
      - php
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

  php:
    image: php:8.2-apache
    volumes:
      - ./php-app:/var/www/html:ro
    environment:
      - TZ=Asia/Shanghai

  mysql:
    image: mysql:8.0.34
    command: --default-authentication-plugin=mysql_native_password
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: myapp
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppass
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "--password=rootpass"]
      interval: 30s
      timeout: 10s
      retries: 5

volumes:
  mysql-data:

创建 nginx.conf (精简版):

events {
    worker_connections 1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://php:80;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

启动:

docker compose up -d
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f nginx
# 访问 http://localhost:8080,应看到 PHP 的 phpinfo 页面

这个案例的价值在于它复现了热搜词 ubuntu22 安装nginx ubuntu22 安装hermes docker-compose up 报错unable to get image 'mysql:8.0.34' 的完整上下文。如果 mysql:8.0.34 拉取失败,第一步不是怀疑网络,而是 docker compose config 检查 YAML 语法, docker info | grep "Registry Mirrors" 检查镜像加速器, sudo systemctl status containerd 检查运行时——这才是 Ubuntu 22.04 上 Docker 故障排查的正确顺序。

4. 常见问题与排查技巧实录:那些让你抓狂的 Ubuntu 22.04 Docker 错误,其实都有固定解法

在 Ubuntu 22.04 上玩 Docker,有些错误就像幽灵一样反复出现。它们往往有固定的模式、固定的日志线索、和固定的三行命令就能解决。我把过去一年在论坛、工单、内部 Slack 里高频遇到的 12 个典型问题,整理成一张“症状-日志-根因-解法”的速查表。这不是理论推导,而是从生产环境血泪中捞出来的经验。

4.1 Ubuntu 22.04 Docker 常见问题速查表

问题现象 关键日志线索( journalctl -u docker -n 50 根本原因 三行解决命令
docker: command not found 无(命令不存在) docker-ce-cli 未安装,或 PATH 未包含 /usr/bin sudo apt install -y docker-ce-cli
echo $PATH | grep /usr/bin
hash -r
Cannot connect to the Docker daemon Failed to connect to bus: No such file or directory docker 命令试图连接 systemd 用户 session,但未启用 --user sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
dockerd 启动失败,无日志 systemctl status docker 显示 activating (start) 然后超时 containerd 未启动,或 runc 版本不匹配 sudo systemctl start containerd
sudo journalctl -u containerd -n 50
sudo apt install -y runc
docker ps 返回空,但 docker info 正常 docker info Containers: 为 0, Images: 为 0 dockerd 启动了,但 /var/lib/docker 目录为空或权限错误 sudo ls -la /var/lib/docker
sudo chown -R root:root /var/lib/docker
sudo systemctl restart docker
docker-compose up command not found bash: docker-compose: command not found 安装的是 Go 版 docker compose ,但你敲的是 docker-compose (带横杠) `

更多推荐