看到这个标题“2026.1.28 docker安装”,我第一反应是你在服务器或者自己的开发机上又踩了环境的坑。Docker这个东西,装起来一条命令的事,但真正把它装“好”,让后面跑容器、拉镜像、配网络都顺手,还真不是照着官方文档复制粘贴就能搞定的。我见过太多人装了三天Docker,最后卡在权限、内核、包源、磁盘这几个看似不起眼的地方,折腾到怀疑人生。
这篇文章不打算把Docker的完整入门从头讲一遍,而是围绕“安装”这件事,把我在实际环境中反复验证过的思路、步骤、取舍和排错经验整理出来。无论你是刚接触容器的新手,还是已经用了一段时间但没自己完整装过一次环境的老手,都可以照着下面的路径走一遍。为什么“怎么装”比“装什么”更重要,我会在第一章先讲清楚。后面会具体到不同系统的安装步骤、装完之后的必做配置、启动失败的排查思路,以及我踩过的几个典型坑。尽量少说空话,多点实操。
1. 安装前的三个决策:环境、版本和运行模式
1.1 先分清系统,再决定安装方式
很多人一搜“docker安装”就随便找个教程开始执行,但不同系统之间的差别非常大。如果你在Windows上安装了Docker Desktop,又跑到Linux服务器上用同一套思路去搞,十有八九会撞墙。
从我的经验看,安装之前先回答三个问题:
- 你的系统是什么?Windows、macOS、还是Linux?如果是Linux,是哪个发行版?
- 这台机器是个人开发机,还是生产环境的服务器?后者对系统稳定性、内核版本要求更高。
- 你只是临时跑几个容器,还是打算长期用它做服务编排?这决定你是否需要先配置好镜像加速、日志清理、存储位置。
不要跳过这几个问题直接装。原因很简单:Docker的安装方式和内核息息相关,特别是Linux环境下,存储驱动、网络模式、防火墙规则都依赖于具体内核版本。先花两分钟确认环境,比装完再排查半天要省事得多。
1.2 官方版、发行版自带版、脚本版,选哪个
装Docker最常见的三种途径:
- 官方仓库安装(通过系统包管理器安装官方维护的docker-ce包)
- 发行版自带的docker包(比如系统软件源里直接提供的docker.io)
- 官方安装脚本(一条curl命令跑完)
我个人的建议是优先使用官方仓库安装。发行版自带的docker.io版本往往比较旧,尤其在某些长期维护的系统上,版本滞后可能让你用不上新特性,也会导致和某些容器镜像的兼容性问题。官方安装脚本虽然方便,但缺少手动设置的过程,出问题了不好理解根源。官方仓库的方式最稳妥,配置一次之后可以持续获得更新。
当然也要说实话:在某些离线环境、内网环境里,官方仓库可能访问不了,这时候用离线安装包反而更可行。我个人在实际的内网部署环境里就遇到过这种问题,官方仓库完全不可达,最后是先把安装包下载到一台机器上,再拷贝到目标服务器。这种情况我会在第三章详细说。
1.3 Docker Engine和Docker Desktop的区别
如果你是Linux用户,装的是Docker Engine,也就是纯粹的容器运行时和管理命令行工具。而Windows和macOS上更常见的是Docker Desktop,它自带一个虚拟机层,因为容器本身依赖Linux内核特性,在Windows和macOS上跑Docker,本质上是先启动了一个轻量级Linux虚拟机,再把容器跑在虚拟机里。
这个区别决定了排错的思路。在Linux上启动docker服务失败,要查的是systemd日志和系统内核配置;在Windows或macOS上启动失败,多半要先看虚拟化是否在BIOS里开启、虚拟机服务是否被占用。
如果你只是在个人电脑上学习容器,Docker Desktop没问题,方便省事。如果你是部署到服务器上,那没得说,必须用Docker Engine。我见过很多人在服务器上装了Docker Desktop,资源占用巨大不说,还因为虚拟机层乱七八糟的问题导致容器网络不通,最后全部重装。生产环境装Docker Engine,不要装Desktop。
2. Linux服务器上的Docker安装全流程
2.1 Debian系系统的官方仓库安装步骤
先从我踩过最多的Debian系说起,包括Ubuntu、Debian本身,以及它们的衍生系统。这类系统用apt管理包,安装流程基本一致。
第一步,更新索引并安装前置依赖:
sudo apt update sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release这些包的作用分别是:apt-transport-https让apt支持通过HTTPS访问软件源;ca-certificates提供CA证书;curl用来下载公钥;gnupg用于验证签名;lsb-release用于识别系统版本。如果嫌麻烦,少装一两个其实也能跑,但完整的依赖能避免后续奇奇怪怪的问题,我测试过多次,老老实实装全最稳。
第二步,添加Docker官方GPG密钥:
curl -fsSL https://mirrors.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg注意这一步的输出路径,后面添加软件源时要用到。我在某台机器上遇到过一个情况:某位同学把密钥写到了根目录,软件源配置里指向的路径找不到密钥文件,导致每次apt update都报KEYEXPIRED或者NO_PUBKEY。这看起来是小问题,但排查起来很费时间。
第三步,写入软件源配置:
echo \ "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.docker.com/linux/debian \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null如果你的机器不是amd64架构,需要把arch改成对应的架构名,比如arm64。这一点很容易被忽略,又很容易导致安装失败。
第四步,安装Docker引擎:
sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugindocker-ce是Docker引擎本体,docker-ce-cli是命令行工具,containerd.io是容器运行时组件,docker-compose-plugin是插件版Compose,能用一条命令替代以前单独安装docker-compose的步骤。
装完之后第一时间启动并验证:
sudo systemctl enable --now docker sudo docker run hello-world如果看到“Hello from Docker!”的提示,说明安装成功。没有看到也不要慌,后面第四章专门讲排查。
2.2 RHEL系系统的安装步骤
CentOS、Rocky Linux、Alpine Linux,这类的系统用的是yum或者dnf。CentOS 7和8的包管理方式差异比较大,CentOS 8之后用dnf,但命令基本上兼容yum。
还是先装依赖:
sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://mirrors.docker.com/linux/centos/docker-ce.repo然后安装:
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin启动:
sudo systemctl start docker sudo systemctl enable docker这里我要特别提醒一个老系统上的常见问题:内核版本太老。Docker新版对内核有最低版本要求,尤其是当你想用较新的网络功能或存储驱动时。我遇到过在老旧内核上装好Docker之后,容器能创建,但一启动就报“operation not permitted”或者莫名其妙被kill。用uname -r看一下内核版本,太老的话先考虑升级内核,不要硬着头皮用老内核扛。
2.3 离线安装方案:内网环境怎么处理
生产环境经常有机器不连通外网,这种场景下,我前面说的官方仓库方式就失效了。离线安装我试过几种思路,最稳妥的是在另一台同架构、同系统版本的机器上下载好安装包,做成离线包,拷贝过去安装。
具体操作就是:在能联网的机器上,先用apt或者yum把RPM/DEB包下载到本地,注意要下载全部依赖,而不只是主包。例如在Debian系上可以用apt download命令挨个下载依赖,或者在联网机器上用apt-get install --download-only配合apt-rdepends列出依赖列表。
然后打包拷到内网机器上,用dpkg -i *.deb或者rpm -Uvh *.rpm安装。还有一个更省事的方法:如果可以用tar包,直接从Docker官方下载静态二进制压缩包,解压后把docker、docker-containerd、docker-run等二进制文件拷到系统PATH目录下,然后配置systemd服务。
静态二进制方式我实测非常稳,尤其适合那种“我不能装任何包管理器的东西”的严格环境。缺点是升级麻烦,每次都得手动替换二进制,服务重启。但内网环境本来版本更新频率就低,这个缺点基本可以接受。
2.4 装完别急:先解决几个基础配置
安装脚本跑完不代表环境就是可用的。我每次装完Docker,都会按顺序做四件事:
把当前用户加入docker组,避免每条命令都要sudo:
sudo usermod -aG docker $USER然后重新登录或者执行newgrp docker,否则不生效。
设置Docker守护进程使用国内或内网可用的镜像源,或者按照实际网络情况配置代理。这个在局域网里尤其重要,能极大提高拉镜像速度。
修改docker数据存储目录。默认在/var/lib/docker,如果你的根分区空间小,而其他磁盘空间大,那就提前改掉,不要等磁盘满了再迁移,那时候麻烦很多。改方法是编辑/etc/docker/daemon.json,加上"data-root": "/path/to/docker"。
配置日志清理策略。容器日志默认无限增长,我亲眼见过一个什么日志都没配的容器,跑了一个月把磁盘撑爆。建议在daemon.json里追加:
{ "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" } }这能让单个容器日志上限约150MB,这是经验值,够大多数场景用了。
记得改完daemon.json之后重启docker:
sudo systemctl restart docker3. Windows和macOS安装Docker Desktop的要点
3.1 Windows上容易踩的前置条件
Windows上有两条路:一条是装WSL2后跑Docker Desktop,另一条是直接用Hyper-V虚拟机方式。现在主流是前者,因为WSL2启动快、资源占用低,和Docker Desktop的结合也更顺畅。
安装Docker Desktop之前,请先确认三件事:
- Windows 10/11必须开启WSL2功能,老版本Windows要用WSL1,兼容性差很多
- BIOS设置里虚拟化技术必须开启,CPU虚拟化没打开的话,无论哪个方式都会报错
- 如果系统里之前装过旧版Docker Toolbox,务必先卸载干净,否则两个版本会争着使用镜像和端口映射
很多人在Windows上遇到“Docker Desktop failed to start”的弹窗,九成跟这三个前置条件有关。特别是公司发的电脑,BIOS密码锁住了虚拟化选项,那就真没办法了,只能用远程开发服务器或者转用纯命令行方式。
装完之后,Docker Desktop默认用得还挺顺,但要注意它会自动配置hosts映射和DNS解析,偶尔会把本地的某些端口占用冲突显示出来。如果遇到“port is already allocated”的报错,先看看是不是Docker Desktop常驻占用了端口,再检查自己的项目里有没有同端口号的服务。
3.2 macOS上的安装细节
macOS上装Docker Desktop就简单很多了,下载dmg、拖拽安装、启动。要注意的是Intel芯片和Apple Silicon芯片的版本选择的差异。如果你用M系列芯片,Docker Desktop会优先运行ARM64架构容器,很多老镜像没做ARM64适配,运行时会出现无声失败或者进程启动异常。解决办法是开启Docker Desktop的实验性模拟支持,或者用--platform linux/amd64参数强制跑amd64镜像。
还有一点:macOS上Docker Desktop的内存限制默认是2GB,如果你的机器内存足够大,建议把这个值调高。比如你要跑一套包含多个微服务的编排环境,2GB远远不够,拉起来的容器开始会被OOM杀掉。我一般设置为机器内存的一半,运行起来顺畅得多。
3.3 Docker Desktop的替代思路
如果你不想用Docker Desktop,或者公司不允许安装,还有别的路子。比如在Windows上直接用WSL2里的Linux发行版,在Linux环境里装Docker Engine,然后从Windows侧通过WSL2的IP访问容器服务。这样也算一个比较轻量、不那么依赖GUI的方案。
macOS上也有类似思路,用虚拟机软件跑一个Linux虚拟机,然后在虚拟机里装Docker Engine,再在宿主机上配置转发。优点是不受Docker Desktop的许可限制,缺点是网络配置繁琐,每次开机手要动一下。这个方案我在某个客户那边因为许可证问题被逼试过一次,最终还是成功了,唯一麻烦的是每次Mount代码目录要重新配置。
4. 装完启动不了?实战排错方法
4.1 systemd启动失败怎么查
Linux上最常见的场景:你执行了systemctl start docker,结果状态是failed。这时候第一步别急着重装,先看日志:
sudo journalctl -u docker --no-pager -n 50日志里面线索很多。我整理一个速查表,方便对照排查:
| 报错关键词 | 大概率原因 | 处理思路 |
|---|---|---|
| failed to start daemon | 配置文件daemon.json有语法错误 | 用docker daemon --validate --config-file检查配置 |
| Error starting daemon: error initializing graphdriver | 存储驱动和内核不匹配导致 | 检查内核模块overlay是否加载 |
| iptables failed: No such file or directory | iptables未安装或版本过旧 | 安装iptables,或切换firewalld离场 |
| cgroup mountpoint not found | 老内核cgroup v1/v2切换问题 | 引导参数加systemd.unified_cgroup_hierarchy |
| failed to load listeners: listen tcp 0.0.0.0:2375 | 端口被占用或权限不足 | 检查端口占用,或修改监听地址 |
其中graphdriver的问题我遇到过好多次。新装的系统默认用overlay2驱动,但有些老内核没加载overlay模块,就会报这个错。先执行modprobe overlay,如果提示找不到模块,基本判断内核太老或者内核模块没装,这时候要么换内核,要么在daemon.json里换存储驱动为vfs。vfs性能很差,但至少能跑起来应急。
4.2 拉取镜像失败的网络排查
如果是网络问题导致拉取镜像失败,报错往往是“Get https://registry-1.docker.io/v2/: net/http: TLS handshake timeout”。这个报错几乎每个人都会遇到。解决办法按优先级来:
- 在daemon.json里配置可用的镜像加速器,尤其是在内网或者网络有公网流量限制的机器上,这是最有效的。
- 配置代理,适用于公司在有代理网关的环境下。
- 使用公司内部的私有镜像仓库,先docker pull本地仓库里的镜像,再打tag,避免走公网。
我实测下来,前两种方式基本能覆盖大多数拉取失败场景。配置完镜像加速之后,记得重启Docker并验证一下:
sudo systemctl restart docker docker info看Registry Mirrors那一栏到底有没有生效。我就见过有人改完daemon.json不重启,然后反复问我“为什么拉镜像还是失败”。改配置文件必须重启,别在这上面浪费时间。
4.3 Docker权限经常遇到那些事儿
刚装好Docker,执行docker ps报错“permission denied while trying to connect to the Docker daemon socket”。原因很简单,当前用户不在docker组里。前面已经提到用usermod -aG docker $USER解决,但还有一个易忽略的点:改完组之后,必须重新登录一次或者退出当前终端再开一个新的,不然当前会话的组信息还是旧的。
如果你用sudo执行docker命令,也能正常跑,但每次都加sudo非常影响效率,还容易在生产环境的自动化脚本里埋雷。脚本里如果忘了加sudo,同一个命令在有些机器上能跑,有些机器上就报权限错误。把这些权限问题统一处理干净,后面会少很多麻烦。
4.4 常见问题速查表
我再补一个好用的汇总表格,按问题场景整理:
| 现象 | 问题定位思路 |
|---|---|
| docker version能显示,但docker ps报连不上daemon | 服务没启动或启动失败 |
| docker pull一直超时 | 先看能否访问外部源,判断是DNS解析还是TLS问题 |
| 容器起来了,但网络不通 | 检查iptables规则和docker0网桥是否存在 |
| 容器删不掉,报device or resource busy | 有进程还挂在容器上,重启docker服务再删 |
| 镜像占满磁盘 | 用docker image prune和docker system prune清理临时数据 |
5. 我踩过的坑:几个背景与真实教训
5.1 乱改存储路径导致数据丢失
有一次我在一台测试机上觉得磁盘空间吃紧,想着把docker的data-root改到一块新挂载的大盘上。我在daemon.json里写了新路径,但没注意那里已经有一份部分目录结构,容器启动之后数据错乱,好几个服务的持久化数据都找不到了。教训就是:改data-root之前,确认新路径是空目录或者全新的,并且先把旧数据用docker save导出备份,改完后再迁移。尽量别直接改路径,一定要先tar备份卷。
5.2 用脚本安装省事,但升级时自己坑了自己
我还试过用官方脚本安装,确实快、省心。但后来要升级版本,发现脚本安装把docker和containerd的版本写死在特定路径,和包管理器安装的版本冲突,最终不得不用脚本自带的卸载功能全部清掉,再换仓库安装。从那以后,非必要不推荐脚本安装。除非这台机器是一次性测试机,随便搞搞无所谓。
5.3 忘记配置日志策略的代价
有一段时间,我在一台机器上跑了个日志量很大的服务,没有做任何日志轮转配置。结果一天下来,/var/lib/docker/containers下的json文件把磁盘填满到98%。系统进程开始报“No space left on device”,连sshd登录都受影响,最后只能手动清日志。你如果使用生产服务器,建议第一时间就把日志轮转配置好,别等到出事了再想起来。
5.4 新旧版本共存导致的神秘异常
有一台机器的环境有点特殊,系统自己装了旧版docker.io,我又用官方仓库装了docker-ce。结果系统里有多个版本的容器运行时,混用之后导致网络配置和镜像存储目录互不相同。表象是有些容器能看到,有些看不到,有些服务能访问,有些不行。排查了整整一个下午,最后才发现是两套环境并存。所以前面强调的那句话再来一次:装之前先检查系统里是否已经有docker相关包,有的话先卸载干净。
6. 后续扩展:从装好到用起来的几个建议
6.1 用Compose管理整套环境
装完Docker之后,可能眼前的直接需求是跑几个单个容器。但只要服务数量达到三个以上,命令行直接管理就显得很吃力。我建议下一步就开始用Compose。安装完成后自带的docker compose插件其实已经可以用了,不需要单独安装。用compose.yaml把多个容器的配置写在一个文件里,版本化、可复制,比记忆一大串docker run命令靠谱。
6.2 配置守护进程的远程访问
如果你有开发机和服务器的分离场景,可以给Docker守护进程配置远程访问。这里我提醒一句,不要直接把2375端口暴露到公网,不带TLS是很大的安全问题。我见过某团队直接把2375暴露出来,导致服务器被拿去挖矿的新闻。正确做法是配置好TLS证书,或者用SSH转发方式访问。能不开远程就尽量不开,默认的本地Unix socket最稳妥。
6.3 用官方文档和本地帮助补全知识
我最后再说一个经验,网上很多教程转载、拼凑,版本越旧越害人。Docker本身自带的文档和命令行帮助已经写得比较清楚了,真遇到问题,先跑一遍docker --help,再看docker run --help,效率往往比满网搜索高。如果版本没太落后,官方文档描述的逻辑是可循的,也能避免读到自己环境完全不匹配的老教程。
安装Docker这件事,确实不算难,但如果把安装过程中涉及的每一个决定理解透,会避免日后许多维护和排错的痛苦。希望你装完之后,不是只得到一个能跑helloworld的玩具,而是一套真正能扛住实际业务的容器环境。我自己在多次安装实践中对这一点感触尤其深——耐心一点,把环境理顺,后面使用的时候就会觉得很顺,少加很多班。