ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ubuntu 安装 Docker 与 Docker Compose 完整指南:避坑与实践

Ubuntu 安装 Docker 与 Docker Compose 完整指南:避坑与实践 在 Ubuntu 上安装 Docker 和 Docker Compose 这件事我在自己服务器和客户现场前前后后折腾过几十次从最早跟着教程一步步敲命令到后来闭着眼都能把一套容器环境搭起来中间踩过的坑确实不少。这篇就按我实际的安装顺序来写把每一步为什么要这么做、有哪些容易翻车的地方都讲清楚。不管你是刚接触 Linux 的新手还是需要在生产环境快速部署的运维照着走一遍基本都能顺利跑起来。Docker 解决的是“环境一致性和交付”的问题Docker Compose 解决的是“多容器编排和启动顺序”的问题两个装好之后你在 Ubuntu 上部署 MySQL、Redis、Nginx、GitLab 这类常见服务就只是写一个 yaml 文件的事。下面我直接把完整流程拆开讲。1. 装之前先把这三件事搞清楚1.1 确认Ubuntu版本和内核是否满足Docker要求很多人上来就复制粘贴安装命令结果装到一半报错回头才发现系统版本太老或者内核太旧。Docker 对 Ubuntu 有明确的版本要求虽然说不强制最新版但旧版本确实会遇到各种兼容性问题。先跑一条命令确认系统版本lsb_release -a正常会看到类似Ubuntu 22.04.4 LTS或Ubuntu 24.04 LTS这样的输出。如果看到的是14.04、16.04这种已经停止维护的版本我建议你先升级系统再装 Docker否则后续装完也大概率跑不起来。接着确认内核版本uname -rDocker 官方要求内核版本不低于 3.10但那是很早以前的标准了。现在的 Docker Engine 在 5.x 内核上跑得最稳22.04 默认带的 5.15 内核完全没问题24.04 带的 6.8 内核更是没压力。再顺手检查一下系统架构uname -m绝大多数机器输出的是x86_64。如果你用的是树莓派或者 ARM 服务器输出会是aarch64后面下载 Docker Compose 二进制文件时一定要选对架构不然会报“Exec format error”。这一步看着不起眼但我在 ARM 设备上帮人排查过好几次基本都是架构选错导致的。1.2 选对安装源官方仓库和系统仓库的区别Ubuntu 的官方软件源里其实自带了一个叫docker.io的包用sudo apt install docker.io就能装上。但这个包有个问题它跟着 Ubuntu 的发布周期走版本更新非常滞后。比如 Ubuntu 22.04 的软件源里docker.io 可能还停在 Docker 20.10 或更早的版本。Docker 官方维护的docker-ceCommunity Edition仓库则完全不同它能第一时间拿到最新版本包括安全更新和 bug 修复。更重要的是Docker Compose v2 插件docker-compose-plugin只在 Docker 官方仓库里有Ubuntu 自己的源里根本没有。所以我的建议很明确直接添加 Docker 官方仓库从源头上避免版本老旧的问题。多花两分钟配一个官方源后面会省掉很多不必要的麻烦。1.3 评估网络环境提前准备好镜像加速器这是国内环境下安装 Docker 最核心的一步但经常被忽略。Docker 默认从 Docker Hub 拉取镜像而 Docker Hub 的服务器在国外直接拉取经常会出现超时、速度只有几 KB 的情况。解决办法是配置镜像加速器相当于给 Docker 加了一个“中间缓存层”。拉镜像的时候Docker 会从加速器那边下载而加速器服务器通常已经缓存了常用镜像速度能快几个数量级。截至我写这篇文章的时间公共镜像加速服务包括阿里云的容器镜像服务加速地址、腾讯云、中科大、DaoCloud 等其中阿里云需要登录控制台获取个人专属加速地址其他几家有公共地址。需要注意的是这些公共加速服务的可用性在不同地区、不同时段会有差异有的后来调整了服务策略甚至关闭了所以最稳妥的做法是去各服务商官网查目前最新的加速地址不要死记某个固定的域名。另外说一句如果你是在公司内网环境可能还有自建的 Harbor 或 Nexus 仓库那就直接把内网地址配置成加速地址就行原理是一样的。这个配置我放到后面 2.3 节详细说明。2. Docker引擎安装全流程2.1 添加Docker官方GPG密钥和软件仓库第一步先更新软件包索引同时安装几个基础工具sudo apt update sudo apt install -y ca-certificates curl gnupg这几个包的作用分别是ca-certificates让系统能验证 HTTPS 证书curl用来下载文件gnupg用来导入 Docker 官方的 GPG 签名密钥。接着创建一个目录存放 Docker 的 GPG 密钥sudo install -m 0755 -d /etc/apt/keyrings这里用install -m 0755 -d而不是直接mkdir是为了确保目录权限正确。0755 表示所有用户可读可执行只有 root 可写这个权限设置对后续 apt 验证密钥非常关键。然后下载 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.gpg--dearmor参数的作用是把下载的 ASCII 格式密钥转换成二进制格式。chmod ar让所有用户都有读取权限否则后面 apt update 检查签名时会报权限错误。最后把 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)会读取系统版本代号比如 22.04 对应jammy24.04 对应noble。这两个变量让仓库地址能自动适配不同版本换台机器也不会出错。添加完仓库后再跑一次sudo apt update让系统识别新的软件源。如果这个过程中没有任何报错说明官方仓库添加成功了。注意Ubuntu 24.04 之前的一些版本可能没有/etc/apt/keyrings目录所以前面那句话不是可选步骤。如果跳过tee命令会提示“No such file or directory”。2.2 安装docker-ce并验证基本运行仓库配好之后安装命令其实就一句话sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里的几个包各司其职docker-ceDocker 守护进程本体核心中的核心。docker-ce-cli命令行工具也就是平时敲的docker命令它和守护进程分离设计。containerd.io容器运行时Docker 底层靠它来真正创建和管理容器。docker-buildx-pluginBuildKit 构建插件用来高效构建镜像。docker-compose-pluginCompose v2 插件后面第 3 节再细说。这四个组件缺一不可。我见过有人为了省事只装docker-ce结果系统提示缺少依赖装不上最后还是得老老实实把其他几个一起装上。装完后先看版本docker --version sudo systemctl status docker如果输出Docker version 26.x.x或更高版本并且服务状态显示active (running)说明主程序已经跑起来了。接下来跑一个最经典的验证命令拉取 hello-world 镜像并运行sudo docker run hello-world这个命令会从 Docker Hub 拉取一个很小的测试镜像然后容器输出一段文字说明 Docker 工作正常。如果你之前没配过镜像加速器这一步可能会卡住没关系看完 2.3 节再回来验证。2.3 配置daemon.json让镜像拉取速度起来安装完成后的第一个必做优化就是配置镜像加速器。Docker 守护进程的配置文件在/etc/docker/daemon.json默认情况下这个文件不存在需要手动创建。用编辑器打开文件sudo vim /etc/docker/daemon.json填入以下内容以 DaoCloud 公共加速地址为例其他加速地址类似结构{ registry-mirrors: [ https://docker.m.daocloud.io ] }如果你用的是阿里云容器镜像服务登录阿里云控制台后在“容器镜像服务 ACR”页面找到“镜像加速器”每个账号会分配一个专属地址格式类似https://xxxx.mirror.aliyuncs.com填进去就行。保存退出后重新加载 Docker 配置并重启sudo systemctl daemon-reload sudo systemctl restart docker重启完可以用docker info检查加速器是否生效docker info | grep -A 1 Registry Mirrors如果能看到https://docker.m.daocloud.io之类的地址说明配置已经生效。这里要强调一个非常容易踩的坑daemon.json必须是严格的 JSON 格式。很多人手写配置时把注释写进去或者多了个逗号结果重启 Docker 直接失败日志报“unable to configure the Docker daemon with file /etc/docker/daemon.json”。我见过最离谱的情况是用户复制了带中文全角逗号的配置排查了很久才发现是符号问题。配置完成后再跑一次sudo docker run hello-world正常情况下几秒钟就能拉取完成并输出结果。3. Docker Compose安装先分清v1和v2再动手3.1 最省事的方案apt直接装docker-compose-plugin如果你对 Docker Compose 的概念还停留在docker-compose这个带横杠的命令上那说明你接触的是 Compose v1。v1 是一个独立的 Python 程序需要通过 pip 或单独下载二进制文件安装。但 Docker Compose v2 早就是官方主推的版本了它已经被重写成 Go 语言的插件直接集成到 Docker CLI 里。最大的变化是命令从docker-compose变成了docker compose中间是空格而且不需要额外安装单独的二进制文件。在 2.2 节安装 Docker 的时候我已经把docker-compose-plugin一并装上了。直接验证一下docker compose version输出类似Docker Compose version v2.27.0就说明一切正常。这种方式安装的 Compose版本是跟着 Docker 仓库走的以后apt update apt upgrade时会自动升级不需要手动管理。需要注意一点在部分较早的 Ubuntu 版本中这个插件的包名可能是docker-compose-v2如果提示找不到包就换这个名字试试。另外apt 装的 Compose 插件默认路径在/usr/libexec/docker/cli-plugins/如果发现命令找不到检查一下这个目录是否存在以及 Docker CLI 是否能识别到插件。3.2 官方推荐方案从GitHub Releases下载二进制如果你需要安装特定版本的 Docker Compose比如某个项目明确要求必须用 2.23 版本这时 apt 方式就不够灵活了需要手动从 GitHub Releases 下载二进制文件。先到 Docker Compose 的官方 GitHub 仓库找到对应版本的下载链接。以 2.23.0 为例sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose下载完成后给执行权限sudo chmod x /usr/local/bin/docker-compose注意这个方式安装的二进制文件默认叫docker-compose也就是说你仍然可以用 v1 时代的旧命令。建议加一个软链接让两种情况都覆盖到sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose然后在用户目录下创建插件目录把二进制文件复制成插件形式这样docker compose新命令也能用mkdir -p ~/.docker/cli-plugins/ sudo ln -s /usr/local/bin/docker-compose ~/.docker/cli-plugins/docker-compose国内网络环境下直接从 GitHub 下载有时候会比较慢或者超时。一个比较实用的办法是使用 GitHub 的加速镜像服务比如在下载链接前拼一个ghproxy类的代理前缀或者从一些国内开源镜像站下载。这些加速服务的域名和可用性会经常变动建议自行搜索当前可用的方案。验证安装是否成功docker-compose version docker compose version两条命令都输出版本号才算完整。3.3 两种方案怎么选一张表看懂对比维度apt安装docker-compose-plugin手动下载二进制安装难度极低跟随Docker一起装好中等需要手动下载和配置版本控制跟随仓库可能不是最新版可精确指定任何版本更新方式apt自动升级需要手动替换二进制文件命令形式docker compose新docker-compose旧和docker compose都支持适用场景绝大多数常规项目有版本强需求、离线安装、生产环境固定版本国内下载效率高走apt源较低需借助加速服务我的个人建议是日常使用直接用 apt 方案简单省心如果公司内部有统一的版本规范或者需要离线安装包再用手动二进制方案。两种方式并不冲突手动装的时候注意别把 apt 装的插件覆盖掉就行。4. 装完别急着用这几件事先做掉4.1 把当前用户加进docker组彻底告别sudo装完 Docker 后你会发现不带sudo直接运行docker ps会报这个错Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock原因很简单Docker 守护进程的 socket 文件默认属于root用户和docker组普通用户没有访问权限。解决方法是把当前用户加入docker组sudo usermod -aG docker $USER执行完后必须重新登录或者执行以下命令让用户组生效newgrp docker也可以干脆退出 SSH 重新连接这样最彻底。这里我说一点安全上的题外话加入docker组的用户相当于拥有和 root 同等的权限因为 Docker 可以挂载宿主机任意目录到容器里一旦容器被攻破宿主机的数据可能就是裸奔的。所以在生产环境中不要把所有人都加进 docker 组尽量只给真正需要管理容器的人授权。4.2 用hello-world和compose demo做完整验证能跑hello-world只能说明 Docker 基本算通了。为了验证 Compose 真的可用我建议写一个最小的 demo 项目试试。创建一个测试目录mkdir ~/compose-test cd ~/compose-test创建一个docker-compose.yml文件services: nginx: image: nginx:alpine ports: - 8080:80 restart: unless-stopped然后启动docker compose up -d等待拉取完成后浏览器访问http://localhost:8080能看到 Nginx 的默认欢迎页就说明 Compose 完全正常。最后清理掉测试环境docker compose down这一步走完你手里就是一套随时可以投入使用的 Docker Compose 环境。后面接 MySQL、Redis、GitLab 的时候都是同样的套路写好 compose 文件up -d完事。4.3 设置开机自启避免重启后容器全丢如果你希望服务器重启后 Docker 服务自动启动执行sudo systemctl enable docker.service sudo systemctl enable containerd.service这两条命令会创建系统启动时的软链接。如果你已经在 compose 文件里写了restart: unless-stopped那么 Docker 自启后它还会自动把之前所有标记为自动重启的容器一起拉起这个设计非常实用。我遇到过一些人跳过了这一步结果服务器断电重启后 Docker 是装了但所有容器状态全是 exited还得一个个手动启动。省这一步一分钟后面恢复服务要花半小时一点都不划算。5. 新手最容易踩的坑常见问题与排查记录5.1 镜像拉取永远超时加速器到底怎么填表现执行docker pull mysql:8.0卡在下载界面几分钟不动然后报EOF或net/http: request canceled之类的错。这个问题的根源大概率是没配加速器或者加速器地址没生效。排查步骤如下先看当前加速器配置docker info --format {{.RegistryMirrors}}如果输出是[]或nil说明加速器没有被识别。检查/etc/docker/daemon.json是不是 JSON 格式有误有没有多余的逗号、括号。确认无误后sudo systemctl restart docker再执行docker run --rm hello-world如果还是慢换一个加速地址。可以多写几个备选地址Docker 会自动选择可用的{ registry-mirrors: [ https://docker.m.daocloud.io, https://docker.1panel.live ] }另外注意有些加速器只支持 Docker Hub拉取quay.io、ghcr.io这些第三方仓库的镜像时加速器是不生效的。这种情况需要给镜像打 tag 切换到加速器地址比较麻烦我通常建议直接找代理中转或者换源。5.2 权限报错socket其实是没加组表现Got permission denied while trying to connect to the Docker daemon socket很多人误以为这是 Docker 没启动来来回回重启了好几次都没用。其实就一条命令解决sudo usermod -aG docker $USER newgrp docker如果你的用户已经加过组了还是报错检查一下是不是当前这个 SSH 会话太老没读到最新的用户组信息退出重连基本都能解决。5.3 命令找不到或版本对不上compose安装形态惹的祸表现输入docker-compose --version提示command not found但docker compose version却是好的。或者反过来。原因在于 v1 和 v2 的安装形态不同。v1 的独立二进制装在/usr/local/bin/docker-composev2 的插件装在 Docker 插件目录里。两种方式互不干扰但不会自动互相生成。解决方案就是我在 3.2 节里写的手动下载二进制后做一个软链接到插件目录或者反过来apt 装了插件的想用旧命令就再加一个软链接把插件复制到/usr/local/bin/docker-compose。这样两条命令都能用不折腾。如果docker compose version提示 command not found先看看 Docker 版本docker --versionDocker 20.10 以上的版本才支持 Compose v2 插件如果 Docker 版本太旧优先把 Docker 升级到最新版。5.4 改完daemon.json后Docker起不来九成是JSON问题表现执行sudo systemctl restart docker后服务起不来systemctl status docker显示红色 fail。排查方法sudo dockerd --validate或者直接看日志sudo journalctl -u docker --no-pager | tail -50日志里如果有unable to configure the Docker daemon with file /etc/docker/daemon.json那可以百分之百确定是 JSON 格式问题。常见的坑包括中文全角冒号、逗号结尾多余的逗号字符串没加双引号JSON 不支持单引号自己不小心写了注释改好 JSON 后最好先用 Python 验证一下格式python3 -m json.tool /etc/docker/daemon.json没有报错再重启 Docker。这个习惯养成了能帮你避开很多低级但致命的配置错误。5.5 特殊网络环境下的补充说明如果你在公司内网或者受限网络环境下可能还会遇到另一个问题Docker 能启动但所有外网镜像都拉不下来而且加速器也不管用。这时候要检查一下是不是需要走 HTTP 代理。Docker 守护进程的代理配置在/etc/systemd/system/docker.service.d/http-proxy.conf配置格式是这样的[Service] EnvironmentHTTP_PROXYhttp://proxy.example.com:8080 EnvironmentHTTPS_PROXYhttp://proxy.example.com:8080 EnvironmentNO_PROXYlocalhost,127.0.0.1改完后需要执行sudo systemctl daemon-reload sudo systemctl restart docker这种场景我也遇到过几次尤其是部署在隔离区的服务器。具体代理地址和端口需要你自己根据网络环境填我这里就不展开讲了。说实话在 Ubuntu 上装 Docker 和 Docker Compose 这件事做熟了整个过程不会超过十分钟但新手阶段踩坑基本都集中在几个固定位置源没配好、加速器没生效、Compose 的 v1/v2 混淆、JSON 格式错误。这套流程我在 22.04 和 24.04 上都完整跑过稳定性没有问题。你装的时候如果遇到我上面没提到的报错多看一眼journalctl -u docker的日志大多数问题都会在里面露出马脚。
返回列表