ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Ubuntu安装Docker Engine与Compose v2全流程详解

2026/9/15 10:26:19 拓冰建站 浏览量
Ubuntu安装Docker Engine与Compose v2全流程详解 先说一个我自己的真实经历。第一次在 Ubuntu 上装 Docker图省事照着一篇老博客敲了apt install docker.io然后docker --version结果装下来是一个几年前的旧版本Compose 还得单独用 pip 装装完又跟系统 Python 环境打架折腾到半夜才跑通第一个容器。后来换了官方 apt 仓库的方式把 Docker Engine 和 Compose v2 一次性配好之后再也没出过版本层面的幺蛾子。这篇文章就把这一整套流程完整写出来每一步都解释为什么这么做不光是照着敲就能跑更重要的是让你知道跑通了之后遇到问题该怎么排查。适合第一次在 Ubuntu 上装 Docker 的新手也适合之前用杂七杂八方式装过、想彻底理一遍的老手。1. 安装前先想清楚Docker Engine 和 Docker Desktop 到底选哪个1.1 两种方案的本质区别先说结论这篇文章主要讲 Docker Engine 的安装方式。但你搜ubuntu 安装 docker的时候结果里会混着大量 Docker Desktop 的内容这俩在 Ubuntu 上不是一回事选错了后面会绕很多弯。Docker Desktop 是面向开发者的图形化方案自带一个 Linux 虚拟机在 Windows/macOS 上在 Ubuntu 上虽然能原生跑但它默认也会起一个虚拟机后端资源占用高启动速度慢而且和 Linux 里直接跑 Engine 的方式有一些网络层面的差异。如果你是在一台服务器、虚拟机、云主机上装或者打算长期跑容器服务Docker Engine Compose 插件才是正路。两者的核心差异我列个表对比项Docker Engine本文方案Docker Desktop包名docker-ce / docker.iodocker-desktop后端直接使用宿主机内核依赖虚拟化自带独立虚拟机典型适用场景服务器部署、虚拟机、云主机本地开发、图形界面操作Compose 支持docker-compose-pluginv2 插件内置在 Desktop 中资源占用低高虚拟机占内存明显镜像加速配置手动改 daemon.jsonGUI 里可以设置1.2 你现在的使用场景适合哪个如果你是在 VMware、VirtualBox 里装的 Ubuntu或者用 WSL2 跑 Ubuntu又或者在云上开了台 Ubuntu 服务器我建议直接用 Engine。这条路不依赖图形界面SSH 进去也能操作跑通了这一套后续部署 MySQL、Redis、GitLab 什么的都顺理成章。如果你坚持要用 Docker Desktop也不是不行但要注意在 WSL2 环境下Desktop 和 Engine 如果同时存在命令行里docker指向谁取决于 PATH 顺序和 Docker Context 设置这个后面专门讲。反正从纯技术沉淀的角度先把 Engine 这条链路吃透不管去哪台 Linux 机器都能复制。1.3 本文环境说明下面所有步骤我在 Ubuntu 20.04 LTS 和 22.04 LTS 上都实测过24.04 的流程完全一致。不同版本之间主要是 APT 源里填的代号不一样focal、jammy、noble我会在对应位置特别标注。建议你安装之前先看一眼自己的系统版本lsb_release -a输出里的 Codename 记下来一会儿配置 APT 源会用到。2. 先清场卸载旧版本不要把两条命令装出来的假 Docker当成生产环境2.1 为什么不能直接 apt install docker.io很多教程图省事直接让你apt install docker.io。这个包来自 Ubuntu 官方源版本滞后非常严重。我用 22.04 的时候官方源的 docker.io 还停留在 20.10.x而 Docker 官方仓库里的 docker-ce 已经迭代到 24.x 了。容器生态迭代快Compose 文件格式、网络特性、安全补丁都在持续更新装一个落后两年的版本后面写 compose 文件时很多新字段不识别排查起来非常折磨。另一个问题是 docker.io 这个包默认不带 docker-compose-plugin你得额外想办法装 Compose。要么 pip 装 docker-compose会引入一堆 Python 依赖而且 v1 版本已经停止维护要么手动下载二进制又涉及到版本匹配和权限问题。官方仓库把 Docker Engine、CLI、Containerd、Buildx、Compose 插件一次性打包好版本统一依赖关系理顺这才是正规军打法。2.2 旧版本清理指南如果你之前通过各种方式装过 Docker不论 docker.io、docker-ce、还是测试版先统一清理掉避免残留的配置干扰。# 卸载各种可能存在的 docker 包 sudo apt-get remove docker docker-engine docker.io containerd runc # 如果你之前用 docker-ce 官方仓库装过包名是这些 sudo apt-get remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这个命令不会删除/var/lib/docker目录里面保存着已下载的镜像、容器、卷。如果你确定旧数据不要了可以顺手清掉sudo rm -rf /var/lib/docker不确定的话就先留着新版本装好后旧镜像还能继续用只是要注意新旧版本的数据目录结构可能存在不兼容建议迁移前先备份。2.3 安装前的系统检查清理完旧包之后确认系统自带的一些工具是否齐全。缺什么补什么sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release这几个包后面都用得上curl 用来下载密钥gnupg 用来处理 GPG 密钥ca-certificates 保证 HTTPS 证书校验正常。别看它们不起眼很多教程里跳过了这步结果后面添加 Docker 官方源时 curl 报证书错误或者 gpg 命令找不到又得回头补装。3. 官方 APT 仓库的完整安装流程每个步骤背后的原因都说清楚3.1 建立信任链添加 Docker 官方 GPG 密钥Ubuntu 的 APT 系统要求每个软件源都有一个对应的 GPG 密钥用来验证软件包的签名防止源被篡改后分发恶意软件。没做过这块的话可以把它理解成软件源每次发布软件包都会带一个数字签名系统用这把公钥去验签对得上才允许安装。# 创建密钥存放目录这个路径是 Docker 官方约定的 sudo install -m 0755 -d /etc/apt/keyrings # 下载 Docker 官方的 GPG 公钥 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.gpggpg --dearmor的作用是把从网络上下载的 ASC 格式密钥转换成二进制格式这样 APT 读取效率更高。权限设成ar是因为新版 APT 对密钥文件权限比较敏感之前有用户因为权限不对导致 apt update 时直接报Key is stored in legacy trusted.gpg keyring虽然能用但是日志刷屏完美主义建议一步到位。3.2 写入 APT 源并解释这行长命令在干嘛接下来要把 Docker 官方仓库写入 APT 源列表。这里有个关键点Docker 官方仓库是分 Ubuntu 版本的focal、jammy、noble所以要用命令动态拼接而不是写死一个版本号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/null拆开看这行命令arch$(dpkg --print-architecture)自动获取当前 CPU 架构x86 机器是 amd64ARM 机器是 arm64signed-by/etc/apt/keyrings/docker.gpg指定这个源使用我们刚下载的密钥验签$(lsb_release -cs)自动匹配 Ubuntu 代号20.04 是 focal22.04 是 jammystable指定的是 Docker 的稳定发布通道不建议手动写死版本代号因为换机器部署的时候容易忘了改用命令动态生成一劳永逸。执行完之后apt update一下让系统识别新仓库sudo apt-get update如果这一步报The repository ... does not have a Release file基本就是版本代号拼接错了检查一下lsb_release -cs输出的代号和仓库实际目录名是否一致。3.3 一次性装齐 Docker 全家桶现在可以装 Docker 了。我建议大家直接装下面这一整条命令不要只装 docker-cesudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这几个包分别负责什么值得花 30 秒搞清楚docker-ceDocker 引擎本体负责管理容器生命周期docker-ce-clidocker命令行工具装完才有docker ps、docker images这些命令containerd.io容器运行时负责真正拉起容器进程现代 Docker 架构里引擎和运行时是分离的docker-buildx-plugin扩展了docker build命令支持多平台构建等高级功能docker-compose-plugin这就是 Compose v2 本体装完后可以通过docker compose命令使用有些教程只装前三个但实际使用中迟早会遇到docker compose或者docker buildx的需求与其后来补装不如一次到位。启动 Docker 服务并设置开机自启sudo systemctl enable docker.service sudo systemctl enable containerd.service sudo systemctl start dockerenable的作用是让 Docker 在系统启动时自动拉起服务器场景下几乎总是需要的。start是立即启动当前会话的服务。3.4 验证安装是否成功跑一个最简单的验证命令sudo docker version注意看两个信息Server 版本号是否和 Client 一致都是你刚装的版本以及docker-compose-plugin是否已经就位docker compose version如果能看到类似Docker Compose version v2.x.x的输出说明 Compose 插件已经装好了不需要再去单独处理。到这里 Docker 本体已经安装完成但还差一步——每次敲sudo docker真的很烦。4. 告别 sudo用户组配置与重新登录的细节4.1 你第一个会遇到的不爽装完 Docker 后大多数普通用户执行docker ps会碰到这样一条错误docker: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock原因很简单Docker 守护进程通过/var/run/docker.sock这个 Unix Socket 接收命令而这个 Socket 的所有者是root:docker权限为srw-rw----普通用户不在 docker 组里自然没有访问权限。4.2 把当前用户加入 docker 组解决方案也简单把需要用 docker 的用户加入 docker 组sudo usermod -aG docker $USER-aG两个参数缺一不可-a是 append追加到附加组列表-G指定组名。少写-a的话会把用户从其他附加组里踢出去运气不好可能直接失去 sudo 权限这个坑我身边真有人踩过。4.3 组变更生效的两种方式修改组信息之后不会立即生效因为用户会话在登录时就已经确定了所属组列表。有两条路方式一退出当前登录会话重新登录。如果是 SSH 连接直接退出重连如果是桌面环境注销再登录。方式二不想重新登录的话用newgrp命令临时切换组身份newgrp docker然后验证docker ps如果能看到空的容器列表而不是 permission denied说明组权限生效了。注意newgrp只是对当前终端会话有效新开终端还是得重新执行或者在每个新终端里重新登录用户。4.4 docker 组权限的风险提示这里必须多说一句把用户加入 docker 组等于给了这个用户 root 级别的权限。原因在于docker 组用户可以通过挂载宿主目录的方式进入宿主文件系统。比如docker run -it -v /:/host ubuntu bash这条命令直接以 root 身份进到了宿主机的根目录。所以 docker 组只能加给完全信任的用户不要把所有人的账号都塞进去。如果你管理的是一台多人共用的服务器更安全的方式是保留 sudo 权限每次用sudo docker操作或者给特定用户配置 sudo 规则只允许执行 docker 命令。5. Docker Compose v2插件式安装的好处与离线安装方案5.1 为什么推荐直接使用 docker compose 而不是 docker-compose历史上 Docker Compose 是一个独立的 Python 工具命令是docker-compose需要单独安装。2022 年 Docker 发布 Compose v2 之后官方把 Compose 以插件形式集成到 Docker CLI 中命令变成了docker compose注意中间没有横杠。v2 和 v1 的区别不仅体现在命令名上v2 是 Go 语言重写启动多容器项目时速度明显更快Compose 的配置文件名从docker-compose.yml扩展到compose.yaml、compose.ymlv1 已经停止维护新版本 Docker 环境基本都不再兼容通过 apt 安装docker-compose-plugin的方式Compose 会和 Docker CLI 保持同步更新不需要人工维护版本。这也是我前面强调要装这个插件包的原因。5.2 离线安装 docker-compose 的思路有些内网环境不能直接访问 Docker 官方源需要在有网的机器上下载好 deb 包再带进去。方法是换一台同架构、同 Ubuntu 版本的机器# 在有网的机器上只下不装 sudo apt-get install -y --download-only docker-compose-plugin containerd.io docker-ce docker-ce-cli docker-buildx-plugin这条命令会把所有 deb 包下载到/var/cache/apt/archives/目录。把它们拷到内网机器上执行sudo dpkg -i /var/cache/apt/archives/*.deb如果出现依赖缺失还需要先手动安装依赖包。所以离线安装时建议把整个/var/cache/apt/archives目录都带过去而不是只拷 compose 那一个包。5.3 验证 Compose 的完整链路用一个小项目验证一下 compose 是否能正常工作。创建一个测试目录写一个最简单的 compose 文件mkdir -p ~/compose-test cd ~/compose-test cat compose.yaml EOF services: hello: image: alpine:latest command: echo hello compose EOF然后运行docker compose up正常情况下会输出一条hello compose并退出。如果这里报compose is not a docker command说明 compose 插件没装上回去重新执行 3.3 节里带docker-compose-plugin的安装命令。6. 镜像拉不动大概率是没配镜像加速器6.1 docker pull 卡住或超时的根源Docker 默认从 Docker Hub 拉取镜像而 Docker Hub 在国内的访问稳定性大家心里有数。如果你执行docker pull hello-world时输出一直停在Waiting或者报dial tcp: lookup registry-1.docker.io: no such host不是你命令敲错了是网络链路的问题。有一种思路是配置 HTTP 代理但很多内网环境根本没有可用代理更常见的做法是配置 Docker 镜像加速器。国内各大云厂商以及部分高校都提供了 Docker Hub 的镜像站点我们在 daemon 配置文件里把镜像源指向这些站点Docker 拉镜像时会优先从加速站点获取。6.2 daemon.json 配置实操Docker 引擎的配置文件路径是/etc/docker/daemon.json默认不存在需要手动创建sudo mkdir -p /etc/docker sudo vim /etc/docker/daemon.json写入如下内容镜像源以你实际可用的为准{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com ] }保存后重启 Docker 让配置生效sudo systemctl daemon-reload sudo systemctl restart docker验证配置是否生效docker info在输出的Registry Mirrors一段应该能看到你刚才填的地址。没有输出就说明配置文件格式有误或者路径不对优先检查 JSON 格式。提示很多教程会直接给一个固定的公网加速地址但这类地址经常变动而且部分地址只对特定网络环境可用。最稳妥的方式是在你自己的云服务商控制台里申请专属加速地址或者选择网络环境下当前可用的公共镜像源。配置好加速器之后再执行docker pull hello-world正常情况几秒钟就能拉完。6.3 验证安装的完整链路docker run hello-world如果输出中包含Hello from Docker!这一段说明从拉镜像到运行容器的整条链路都是通的。这一步才是真正的安装完成标志前面所有配置最终都是为了这一下。把docker run hello-world这条命令拆开看它实际上做了三件事检查本地有没有 hello-world 镜像、没有就自动 pull、pull 成功后启动容器并执行容器内的默认命令。所以这一步通过意味着 daemon 运行正常、镜像拉取链路通畅、容器生命周期管理正常。7. 高频故障排查我在安装和日常使用中踩过的坑7.1 报错Cannot connect to the Docker daemondocker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?先确认 Docker 服务状态sudo systemctl status docker如果状态是 inactive 或 failed查看日志sudo journalctl -u docker.service --no-pager | tail -n 50常见原因有两个。一是系统里已经有旧版 Docker 的数据目录新版引擎启动时解析旧配置报错处理方式是备份并清空/var/lib/docker后重启服务。二是和网络管理工具冲突在部分云主机上Docker 默认创建的docker0网桥会跟云平台的网络策略冲突需要在 daemon.json 里调整iptables相关参数。7.2 报错permission denied 或 Is your docker daemon running如果docker ps报 permission denied说明用户不在 docker 组参考第 4 章内容。如果确认已经加入 docker 组且重新登录过再用docker info看 daemon 是否正常两者问题不同处理方向也不同。7.3 报错docker compose 命令不存在docker compose报错compose is not a docker command但docker --version正常。说明 compose 插件没装上执行sudo apt-get install -y docker-compose-plugin这个问题在只装docker-ce的教程里非常常见也是我为什么一直强调要装全家桶包。7.4 WSL2 环境中的 Docker 指向混乱如果你在 Windows 上装了 Docker Desktop同时又在 WSL2 的 Ubuntu 里装了 Docker Engine命令行里执行docker时可能指向任意一个。用docker context ls查看当前上下文用docker context use default切回本机 Engine或者用docker context use desktop-linux切到 Desktop。7.5 故障排查汇总表现象可能原因排查命令解决方案docker ps 权限不足用户不在 docker 组groups $USERsudo usermod -aG docker $USER并重新登录Cannot connect to daemondocker 服务未启动systemctl status dockersudo systemctl start dockerdocker compose 不可用compose 插件未安装docker compose versionsudo apt-get install -y docker-compose-plugindocker pull 超时镜像加速器未配置docker info查看 Registry Mirrors配置 daemon.json 后重启 dockerapt update 报密钥错误GPG 密钥权限不对查看ls -l /etc/apt/keyrings/docker.gpgsudo chmod ar /etc/apt/keyrings/docker.gpgWSL2 下 docker 指向混乱多个 docker 上下文并存docker context lsdocker context use default7.6 一条完整的装完验收命令序列最后分享一个装完机后我会立刻跑的完整验收流程10 秒钟就能确认所有组件是否就位docker --version docker compose version docker buildx version docker run --rm hello-world四行输出分别确认Docker CLI、Compose 插件、Buildx 插件、镜像拉取与容器运行。这一套走完你的 Ubuntu 上的 Docker 环境才算真正初始化完成可以开始装 MySQL、Redis、GitLab 这些实际服务了。我在多台 Ubuntu 服务器和本机虚拟机上重复过很多遍这套流程最大的感受是安装本身不难难的是理解每一步到底在解决什么问题。弄清 GPG 密钥、APT 源、用户组、daemon 配置这些底层逻辑后不管换成什么发行版、什么网络环境心里都会有底。如果你装的过程中碰到其他奇怪的问题优先按 7.5 的表对一遍系统日志大多数坑都能从日志里找到直接线索。