1. 为什么在Ubuntu上安装Docker是个“技术活”?
如果你在Ubuntu上装过Docker,大概率遇到过这么几种情况:照着某篇教程一路回车,最后报个permission denied;或者用apt install docker.io装完,发现版本老得连docker compose命令都没有;又或者兴致勃勃地下载了Docker Desktop for Linux,结果启动时弹出一个“Virtualization support not detected”的窗口,直接给你整懵了。这感觉就像你想开车,结果发现车钥匙、方向盘和发动机分别在三家不同的店里,还互相不兼容。
我之所以想聊聊Ubuntu上安装Docker的“多种方式”,就是因为这背后远不止是几个命令的差异。它涉及到你对Ubuntu包管理生态的理解、对Docker官方分发策略的把握,以及对你自己系统环境(是桌面还是服务器?是物理机还是虚拟机?)的清晰认知。选错了安装路径,轻则后续升级麻烦,重则影响生产环境的稳定性和安全性。今天,我就以一个踩过几乎所有坑的过来人身份,帮你把这几种安装方式的来龙去脉、适用场景和隐藏的“坑”彻底捋清楚。无论你是刚接触Linux的新手,还是需要为团队制定标准化部署方案的老手,这篇文章都能让你在Ubuntu上玩转Docker时,心里更有底。
2. 安装前的“灵魂三问”:明确需求,避免白忙活
在动手敲下任何安装命令之前,花几分钟回答下面三个问题,能帮你省下后面几小时甚至几天的折腾时间。
2.1 你的Ubuntu是桌面版还是服务器版?
这是最根本的区分,直接决定了你能用哪些安装方式。
- Ubuntu Desktop(桌面版):带有图形界面(GNOME)。对于桌面用户,Docker官方提供了Docker Desktop这个一体化解决方案。它不仅仅包含Docker引擎(Docker Engine)和命令行工具(CLi),还打包了Docker Compose、一个可视化的管理界面、以及开箱即用的Kubernetes单机环境。它的安装过程类似于在Windows或macOS上安装一个应用程序,通过图形界面或deb包安装器完成。但是,Docker Desktop对系统虚拟化支持有硬性要求,这也是很多人在桌面版上安装失败的主要原因。
- Ubuntu Server(服务器版):没有图形界面,纯命令行操作。这是生产环境中最常见的形态。在这里,我们通常只安装Docker Engine(社区版或企业版)这个核心引擎,以及配套的CLI工具。安装方式主要通过APT仓库、离线deb包或者自动化脚本(如
get-docker.sh)来完成。服务器环境追求的是稳定、可控和资源高效,因此Docker Desktop并不适用。
2.2 你需要的是最新特性还是长期稳定?
Docker的版本迭代很快,新功能、性能改进和安全补丁会不断推出。但同时,生产环境又忌讳频繁变更。
- 追求最新(Latest/Edge):如果你是开发者,想第一时间体验
docker buildx的最新功能、或者需要某个刚修复的Bug,那么你应该使用Docker官方的APT仓库,并配置安装docker-ce(社区版)的最新版本。这种方式能让你紧跟上游。 - 追求稳定(Stable):对于线上服务器,稳定压倒一切。Ubuntu自己的官方软件源(
universe仓库)里包含一个名为docker.io的包。这个包的版本通常比Docker官方仓库的版本落后好几个大版本,但好处是它经过了Ubuntu发行版的集成测试,与系统其他组件的兼容性理论上更好。如果你的应用没有必须使用新版本Docker的特性,docker.io是一个省心的选择。注意:这个包不包含docker-compose插件,需要单独安装。
2.3 你的系统环境支持硬件虚拟化吗?
这个问题主要针对想在Ubuntu Desktop上安装Docker Desktop的用户。Docker Desktop为了实现其强大的功能(如无缝的文件共享、网络和资源管理),在Linux上依赖一个轻量级的虚拟机(VM)来运行Docker守护进程。这就要求你的CPU必须支持硬件虚拟化(Intel VT-x / AMD-V),并且在BIOS/UEFI中已启用。
如何检查?打开终端,运行:
grep -E --color 'vmx|svm' /proc/cpuinfo如果有输出(vmx对应Intel,svm对应AMD),则说明支持且已启用。如果没输出,你需要重启进入BIOS/UEFI设置中开启虚拟化支持。在云服务器或某些虚拟机里,这个功能可能由宿主机控制,你无法开启,这也是导致“Virtualization support not detected”错误的常见原因。
回答完这三个问题,你对安装路径应该已经有了初步判断。接下来,我们深入每一种安装方式。
3. 方式一:使用Ubuntu官方仓库安装docker.io(最省心,但版本旧)
这是最“Ubuntu”的方式,适合刚入门、或者对Docker版本没有特殊要求的服务器环境。
核心原理:Ubuntu将某个特定版本的Docker Engine(注意,不是Docker Desktop)打包成一个名为docker.io的deb软件包,放在它自己的universe软件仓库中。你通过apt安装的,其实是Ubuntu维护的一个“快照”版本。
操作步骤:
- 更新软件包索引:这是任何
apt操作前的良好习惯。sudo apt update - 安装
docker.io:sudo apt install docker.io - 验证安装:安装完成后,Docker服务会自动启动。运行以下命令检查版本和状态。
你会看到类似sudo docker --version sudo systemctl status dockerDocker version 20.10.12, build 20.10.12-0ubuntu2~22.04.1的输出,版本号明确显示了这是Ubuntu打包的版本。
优点:
- 极其简单:一条命令搞定,无需添加第三方仓库。
- 系统集成好:作为Ubuntu官方仓库的一部分,它会随系统安全更新一起获得补丁,管理统一。
- 稳定性高:版本经过Ubuntu团队测试,与当前系统版本兼容性好。
缺点与注意事项:
- 版本陈旧:这是最大的问题。在Ubuntu 22.04 LTS上,它可能还停留在Docker 20.10.x,而官方早已发布24.x甚至更高版本。你会错过很多新功能和重要安全更新。
- 不包含现代Docker Compose:安装的
docker-compose是Python写的旧版V1,而非现在主流的、功能更强的Docker Compose Plugin(V2)。你需要额外处理。 - 后续升级滞后:你只能等待Ubuntu仓库更新,无法主动升级到新版本。
实操心得:我早期在内部测试服务器上大量使用这种方式,图的就是省事。但有一次因为一个容器网络的新特性(如
ipvlan)只在较新版本的Docker中稳定支持,我们不得不全部重装为官方仓库版本。所以,如果你的项目周期长,且未来可能用到新特性,慎用此法。
4. 方式二:使用Docker官方APT仓库安装(推荐用于服务器)
这是Docker官方推荐的、用于Linux发行版的安装方式,能让你始终安装最新的稳定版或测试版Docker Engine。
核心原理:Docker维护了自己的APT软件源(download.docker.com)。我们将这个源添加到Ubuntu的源列表(/etc/apt/sources.list.d/)中,之后就可以用apt来安装和更新Docker官方发布的docker-ce(社区版)包。
详细步骤与原理拆解:
4.1 清理旧版本(非必需,但建议)
如果你之前通过其他方式安装过Docker,最好先清理干净,避免冲突。
sudo apt remove docker docker-engine docker.io containerd runc注意,apt remove不会删除镜像、容器、卷等数据,它们通常存放在/var/lib/docker/。
4.2 安装依赖工具
我们需要apt能通过HTTPS使用仓库,以及一些证书处理的工具。
sudo apt update sudo apt install ca-certificates curl gnupgca-certificates:确保系统能验证HTTPS证书。curl:用于下载密钥。gnupg:用于管理GPG密钥,验证软件包签名。
4.3 添加Docker的官方GPG密钥
GPG密钥用于验证从Docker仓库下载的软件包是否被篡改。这是安全安装的关键一步。
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 a+r /etc/apt/keyrings/docker.gpginstall -m 0755 -d ...:以安全的方式创建目录。curl -fsSL:-f静默失败,-s静默模式,-S显示错误,-L跟随重定向。组合使用是下载脚本或密钥的稳妥做法。gpg --dearmor:将ASCII格式的GPG密钥转换为二进制格式,供apt使用。
4.4 设置稳定版仓库
接下来,告诉apt去哪里找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这条命令需要仔细理解:
arch=$(dpkg --print-architecture):自动获取当前系统的架构(如amd64, arm64),确保下载正确的包。signed-by=/etc/apt/keyrings/docker.gpg:指定用于验证这个仓库的GPG密钥路径。$(. /etc/os-release && echo "$VERSION_CODENAME"):这是一个子shell命令,它会读取系统版本信息文件,并输出当前系统的代号(如Ubuntu 22.04是jammy)。这保证了无论你在哪个版本的Ubuntu上运行,命令都能自动适配正确的仓库路径。sudo tee ... > /dev/null:将生成的仓库配置行写入/etc/apt/sources.list.d/docker.list文件,tee命令同时兼顾了sudo提权和重定向。
4.5 安装Docker Engine
更新源并安装。
sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里安装了五个包:
docker-ce:Docker引擎本体。docker-ce-cli:命令行工具。containerd.io:容器运行时,Docker的底层依赖。docker-buildx-plugin:用于构建多平台镜像的强大工具。docker-compose-plugin:这是关键!它提供了docker compose命令(注意是空格,不是横线),即Compose V2。安装后,你可以直接使用docker compose up等命令。
4.6 验证与权限配置
安装后,服务会自动启动。验证:
sudo docker run hello-world这个命令会下载一个测试镜像并运行,如果看到欢迎信息,说明安装成功。
默认情况下,运行Docker命令需要sudo权限。为了方便,通常会将当前用户加入docker用户组:
sudo usermod -aG docker $USER执行此命令后,你必须完全退出当前终端会话(关闭所有窗口或断开SSH连接),然后重新登录,用户组变更才会生效。之后就可以不用sudo直接运行docker命令了。
优点:
- 版本最新:可以随时获取Docker官方的最新稳定版。
- 功能完整:一次性安装引擎、CLI、containerd、Buildx和Compose插件,生态完整。
- 升级方便:后续只需
sudo apt update && sudo apt upgrade即可升级Docker。
缺点与注意事项:
- 步骤稍多:需要添加仓库和密钥,对新手有一定门槛。
- 稳定性风险:最新的版本可能引入未知Bug,生产环境升级前需在测试环境充分验证。
踩坑实录:有一次在升级
docker-ce时,由于containerd的某个子版本不兼容,导致所有现有容器无法启动。教训是:在生产环境,不要盲目apt upgrade,最好先查看更新日志,或者使用apt-mark hold命令暂时锁定Docker相关包的版本。
5. 方式三:使用官方便捷脚本安装(快速体验,慎用于生产)
Docker提供了一个名为get-docker.sh的自动化安装脚本。
核心原理:这个脚本本质上是一个Bash程序,它自动检测你的系统,然后执行类似方式二的操作(添加仓库、安装包)。但它把所有的步骤封装在了一个命令里。
操作步骤:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh执行后,脚本会输出大量信息,显示它正在做什么,最后完成安装。
优点:
- 极其快速:对于纯净的系统,一条命令就能装好,非常适合快速搭建测试环境。
- 自动适配:脚本会自动检测发行版和版本,选择正确的安装方式。
缺点与重大注意事项:
- 不够透明:脚本在root权限下运行,它会做什么你无法完全掌控。虽然Docker官方脚本是可信的,但这违背了“知其然知其所以然”的安全原则。
- 无法定制:脚本通常安装最新的稳定版,你无法选择安装特定的版本。
- 不推荐用于生产:生产环境的安装需要可预测、可审计。使用脚本增加了不确定性,且难以集成到像Ansible、Puppet这样的配置管理工具流程中。
个人建议:这个脚本只适用于你个人的开发机或者一次性的临时环境。在任何严肃的服务器部署场景下,都应该使用方式二(APT仓库)或方式四(离线包),以确保安装过程清晰、可重复。
6. 方式四:手动下载deb包离线安装(最可控,适合无外网环境)
在内网服务器、安全要求极高的环境,或者需要严格指定某个次要版本时,离线安装是唯一选择。
核心原理:直接从Docker的发布仓库(download.docker.com)下载特定版本的docker-ce、docker-ce-cli、containerd.io等deb包,然后通过dpkg命令手动安装。
操作步骤:
6.1 确定系统架构和Ubuntu版本代号
dpkg --print-architecture # 输出如 amd64 lsb_release -cs # 输出如 jammy (Ubuntu 22.04)6.2 前往Docker发布仓库下载包
你可以在有网络的环境下,访问类似下面的URL模式来下载,或者直接浏览仓库目录:
https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/你需要下载以下包(以某个具体版本为例,请替换为所需版本):
containerd.io_<version>_<arch>.debdocker-ce_<version>_<arch>.debdocker-ce-cli_<version>_<arch>.debdocker-buildx-plugin_<version>_<arch>.debdocker-compose-plugin_<version>_<arch>.deb
你可以使用curl或wget下载,例如:
wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/containerd.io_1.6.28-1_amd64.deb wget https://download.docker.com/linux/ubuntu/dists/jammy/pool/stable/amd64/docker-ce_24.0.7-1~ubuntu.22.04~jammy_amd64.deb ... # 下载其他包6.3 传输并安装
将下载的deb包传输到目标服务器,然后按依赖顺序安装:
sudo dpkg -i ./containerd.io_*.deb sudo dpkg -i ./docker-ce-cli_*.deb sudo dpkg -i ./docker-ce_*.deb sudo dpkg -i ./docker-buildx-plugin_*.deb sudo dpkg -i ./docker-compose-plugin_*.deb如果安装过程中报告缺少依赖,可以运行sudo apt-get install -f来修复安装(此命令需要apt能访问配置好的软件源来获取依赖包,如果完全离线,则需提前下载所有依赖,比较复杂)。
优点:
- 完全离线:不依赖外部网络。
- 版本锁定:可以精确安装某个特定版本,非常适合CI/CD流水线或需要版本一致性的集群。
- 过程可控:每一步都清晰可见。
缺点:
- 繁琐:需要手动查找、下载和按顺序安装多个包。
- 依赖处理麻烦:在完全离线的环境中,处理复杂的依赖关系是一大挑战。
7. 方式五:在Ubuntu Desktop上安装Docker Desktop(图形化体验)
这是为桌面开发者准备的“全家桶”。它不仅仅是一个引擎,更是一个开发环境。
安装步骤:
- 下载deb包:访问Docker官网的 下载页面 ,选择Linux版,下载对应架构(Intel/AMD或Apple Silicon)的
.deb包。 - 安装:可以通过图形化的“软件安装”程序双击安装,也可以在终端里使用
apt安装本地deb文件:sudo apt install ./docker-desktop-<version>-<arch>.deb - 启动与配置:安装后,在应用程序菜单中找到Docker Desktop并启动。首次启动会进行初始化,可能会要求你输入密码以进行权限配置。
与Docker Engine的核心区别:
- 虚拟机层:Docker Desktop在Linux上通过一个轻量级的Linux虚拟机来运行Docker守护进程,这提供了更好的资源隔离和桌面集成(如文件拖拽)。
- 图形化管理界面:提供了容器、镜像、卷、网络的直观管理面板。
- 内置Kubernetes:可以一键启用单机版K8s集群,方便学习Kubernetes。
- 资源占用:相比纯命令行版的Docker Engine,Docker Desktop会占用更多的内存和CPU资源。
最常见的“坑”:Virtualization support not detected如果你在启动时遇到这个错误,请按以下步骤排查:
- 确认CPU支持:如前所述,运行
grep -E 'vmx|svm' /proc/cpuinfo。 - 检查是否启用:如果没输出,进入BIOS/UEFI启用虚拟化技术(通常叫Intel VT-x, AMD-V, SVM等)。
- 检查KVM模块:Docker Desktop依赖KVM。检查内核模块是否加载:
应该看到lsmod | grep kvmkvm_intel或kvm_amd。如果没有,尝试加载:sudo modprobe kvm sudo modprobe kvm_intel # 或 kvm_amd - 检查用户组:确保当前用户在
kvm用户组中。
如果没有,添加并重新登录:groups | grep kvmsudo usermod -aG kvm $USER - 虚拟机环境:如果你是在VMware、VirtualBox等虚拟机里安装Ubuntu Desktop,那么需要在虚拟机软件设置中,为这个虚拟机启用嵌套虚拟化(Nested Virtualization)。这是云服务器或公司虚拟桌面用户最常遇到的问题。
经验之谈:我个人在Linux笔记本上更倾向于使用方式二(APT安装Docker Engine)+ 命令行。Docker Desktop的图形界面对我吸引力不大,而其额外的资源消耗和潜在的虚拟化问题反而增加了复杂度。但对于从Windows/macOS过渡过来、或者非常依赖图形化工具查看容器日志和状态的开发者,Docker Desktop确实能提供更一致的跨平台体验。
8. 安装后的关键配置与优化
无论通过哪种方式安装成功,下面这几项配置都能极大提升你的使用体验和安全性。
8.1 配置镜像加速器(国内必备)
从Docker Hub拉取镜像速度可能很慢。我们需要配置国内镜像加速器。
编辑Docker守护进程配置文件(如果不存在则创建):
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ] } EOF这里添加了中国科技大学、网易和百度的镜像源。你可以选择一个或多个。配置完成后,重启Docker服务使配置生效:
sudo systemctl restart docker验证是否生效:
docker info | grep -A 10 "Registry Mirrors"8.2 调整Docker数据存储路径(避免根目录爆满)
默认情况下,Docker的镜像、容器、卷等数据都存放在/var/lib/docker,这通常在系统根分区。随着使用,很容易把根分区占满。
假设你想把数据迁移到空间更大的/data/docker目录:
- 停止Docker服务:
sudo systemctl stop docker - 复制原有数据(如果已有数据):
sudo rsync -avxP /var/lib/docker/ /data/docker/ - 修改Docker配置文件
/etc/docker/daemon.json,添加数据路径配置:{ "registry-mirrors": [...], "data-root": "/data/docker" } - 启动Docker服务:
sudo systemctl start docker - 验证新路径:
docker info | grep "Docker Root Dir" - 确认无误后,可以删除旧数据释放空间:
sudo rm -rf /var/lib/docker。
8.3 配置日志轮转(防止日志文件无限膨胀)
Docker容器默认的日志驱动(json-file)不会自动清理日志,长期运行可能产生巨大的日志文件。
修改Docker配置文件/etc/docker/daemon.json,为json-file日志驱动设置参数:
{ "registry-mirrors": [...], "data-root": "/data/docker", "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }这表示每个容器日志文件最大10MB,最多保留3个文件(即总共最多30MB日志)。超过后,旧文件会被自动删除。修改后同样需要重启Docker服务。
8.4 启用Docker Compose插件
如果你按照方式二或四安装了docker-compose-plugin,那么docker compose命令(V2)已经可用。它是一个Docker CLI插件,比旧的Python版V1更快、功能更全。你可以通过docker compose version来验证。
如果你之前习惯使用docker-compose(带横线)命令,可以创建一个软链接来保持习惯:
sudo ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose这样,docker-compose和docker compose就都可以用了。
9. 验证安装与故障排查指南
安装配置完成后,运行sudo docker run hello-world是最简单的验证。但如果失败,可以按以下链路排查:
问题:Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
排查1:服务状态
sudo systemctl status docker如果服务未运行,启动它:
sudo systemctl start docker。如果启动失败,查看详细日志:sudo journalctl -u docker.service --no-pager -n 50。排查2:用户组权限如果你已经将用户加入
docker组并重新登录,但仍然需要sudo,可能是当前会话的组信息未更新。尝试新开一个终端,或者执行newgrp docker命令。排查3:socket文件权限检查Docker socket文件的权限:
ls -l /var/run/docker.sock通常应该是
srw-rw---- 1 root docker。如果docker组没有读写权限,需要调整。
问题:拉取镜像速度极慢或超时
排查1:镜像加速器配置确认
/etc/docker/daemon.json配置正确且已重启服务。可以尝试ping一下你配置的镜像地址,看网络是否通畅。排查2:DNS解析Docker守护进程使用的DNS服务器可能有问题。可以在
daemon.json中指定DNS:{ "dns": ["8.8.8.8", "114.114.114.114"] }
问题:docker compose命令未找到
- 排查:确认是否安装了
docker-compose-plugin包。可以通过dpkg -l | grep docker-compose-plugin查看。如果已安装,其插件文件位于/usr/libexec/docker/cli-plugins/docker-compose,确保该路径在Docker CLI的插件搜索路径中。
安装Docker本身只是第一步,但它却是构建一切容器化应用的基石。选择哪种方式,没有绝对的对错,只有是否适合你当下的场景。对于个人学习,脚本安装或docker.io最快;对于开发机,官方仓库或Docker Desktop能获得更好体验;对于生产服务器,官方仓库和离线包则是可靠的选择。理解每种方式背后的原理,你就能在遇到问题时游刃有余。