☰
Docker安装全面指南:环境决策、踩坑排错与生产实践
2026/10/13 7:24:55 网站建设 项目流程

看到这个标题“2026.1.28 docker安装”,我第一反应是你在服务器或者自己的开发机上又踩了环境的坑。Docker这个东西,装起来一条命令的事,但真正把它装“好”,让后面跑容器、拉镜像、配网络都顺手,还真不是照着官方文档复制粘贴就能搞定的。我见过太多人装了三天Docker,最后卡在权限、内核、包源、磁盘这几个看似不起眼的地方,折腾到怀疑人生。

这篇文章不打算把Docker的完整入门从头讲一遍,而是围绕“安装”这件事,把我在实际环境中反复验证过的思路、步骤、取舍和排错经验整理出来。无论你是刚接触容器的新手,还是已经用了一段时间但没自己完整装过一次环境的老手,都可以照着下面的路径走一遍。为什么“怎么装”比“装什么”更重要,我会在第一章先讲清楚。后面会具体到不同系统的安装步骤、装完之后的必做配置、启动失败的排查思路,以及我踩过的几个典型坑。尽量少说空话,多点实操。

1. 安装前的三个决策:环境、版本和运行模式

1.1 先分清系统,再决定安装方式

很多人一搜“docker安装”就随便找个教程开始执行,但不同系统之间的差别非常大。如果你在Windows上安装了Docker Desktop,又跑到Linux服务器上用同一套思路去搞,十有八九会撞墙。

从我的经验看,安装之前先回答三个问题:

  1. 你的系统是什么?Windows、macOS、还是Linux?如果是Linux,是哪个发行版?
  2. 这台机器是个人开发机,还是生产环境的服务器?后者对系统稳定性、内核版本要求更高。
  3. 你只是临时跑几个容器,还是打算长期用它做服务编排?这决定你是否需要先配置好镜像加速、日志清理、存储位置。

不要跳过这几个问题直接装。原因很简单: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-plugin

docker-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,都会按顺序做四件事:

  1. 把当前用户加入docker组,避免每条命令都要sudo:

    sudo usermod -aG docker $USER

    然后重新登录或者执行newgrp docker,否则不生效。

  2. 设置Docker守护进程使用国内或内网可用的镜像源,或者按照实际网络情况配置代理。这个在局域网里尤其重要,能极大提高拉镜像速度。

  3. 修改docker数据存储目录。默认在/var/lib/docker,如果你的根分区空间小,而其他磁盘空间大,那就提前改掉,不要等磁盘满了再迁移,那时候麻烦很多。改方法是编辑/etc/docker/daemon.json,加上"data-root": "/path/to/docker"。

  4. 配置日志清理策略。容器日志默认无限增长,我亲眼见过一个什么日志都没配的容器,跑了一个月把磁盘撑爆。建议在daemon.json里追加:

    { "log-driver": "json-file", "log-opts": { "max-size": "50m", "max-file": "3" } }

    这能让单个容器日志上限约150MB,这是经验值,够大多数场景用了。

记得改完daemon.json之后重启docker:

sudo systemctl restart docker

3. 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 directoryiptables未安装或版本过旧安装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”。这个报错几乎每个人都会遇到。解决办法按优先级来:

  1. 在daemon.json里配置可用的镜像加速器,尤其是在内网或者网络有公网流量限制的机器上,这是最有效的。
  2. 配置代理,适用于公司在有代理网关的环境下。
  3. 使用公司内部的私有镜像仓库,先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的玩具,而是一套真正能扛住实际业务的容器环境。我自己在多次安装实践中对这一点感触尤其深——耐心一点,把环境理顺,后面使用的时候就会觉得很顺,少加很多班。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询