
装 Docker 这个事儿看着简单实际上一搜全是报错“Docker Desktop failed to start because virtualisation support wasnt detected”、“permission denied while trying to connect to the Docker API”、“镜像下载慢”、“容器启动了但连不上”。这些报错我基本都撞过一遍。这篇文章不打算只给你一段安装命令就完事而是把从 Windows 到 Linux从装好到跑起来再到常见故障处理整个链条完整讲一遍。如果你正准备装 Docker或者装了但启动不起来按这个顺序走一遍基本能省下好几个小时的排查时间。1. 装 Docker 之前先想清楚你要装的是引擎还是 Desktop1.1 引擎、客户端、守护进程的关系很多人第一次接触 Docker会误以为它就是一个像微信一样的安装包点安装、双击图标就完事。Docker 其实是一套客户端/服务端C/S架构真正干活的叫dockerd它是守护进程服务端负责管理镜像、容器、网络和存储而你敲的docker命令叫客户端Client它只是把命令翻译成 API 请求发给守护进程去执行。这两个东西经常装在一起但如果你的机器是纯服务器场景其实可以只装引擎不装桌面端。常见的组合是Windows / macOS 个人开发机装 Docker Desktop它把引擎、命令行工具、容器 UI 面板全打包了。Linux 服务器只装 Docker Engine命令行工具通过 systemd 管理服务没有图形界面。搞清楚这个区别后你再去搜索“docker 安装”就不会被一堆“Docker Desktop 和 Docker Engine 到底选哪个”的帖子绕晕了。1.2 Docker Desktop 的本质Docker Desktop 是一个带图形界面的桌面应用底层依赖虚拟化来创建 Linux 运行环境。在 Windows 上它默认使用 WSL2 后端而不是早期那种又笨又重的 Hyper-V 虚拟机方案。WSL2 的优势是启动快、内存占用低而且文件系统性能好很多。如果你用的是 Windows 10 家庭版也不用担心WSL2 在家庭版就能启用如果是旧版 Docker Toolbox 那套方案现在真的没必要再碰了性能差维护也早就不积极了。1.3 核对系统要求在开始安装之前先花两分钟核对自己的系统不然可能装到一半才发现硬件不支持平台最低要求WindowsWindows 10 64 位 22H2 及以上或 Windows 11BIOS 中开启 CPU 虚拟化4GB 以上内存macOS10.15 以上Intel 芯片或 Apple Silicon 芯片均可Linux64 位系统内核 3.10 以上推荐 4.0带iptables、cgroups支持在 Windows 上CPU 虚拟化这一步最容易被忽略。怎么检查打开任务管理器 → 性能 → CPU看右下角有没有“虚拟化已启用”。如果是“已禁用”就得先去 BIOS 把 Intel VT-x / AMD-V 打开不然后面 Docker Desktop 启动时会直接给你报 virtualisation support 的问题。2. Windows 平台怎么装Docker Desktop 的完整落地流程2.1 第一步下载和安装包Docker Desktop 推荐直接从官网下载保持渠道干净。安装的时候有几个选项需要注意“Use WSL 2 instead of Hyper-V”默认勾选即可除非你有特殊需求。“Add shortcut to desktop”看个人习惯。安装包下好后一路 Next 安装很快真正的坑是在首次启动之前WSL2 和虚拟机平台这两个 Windows 功能要先准备好。2.2 第二步把 Virtual Machine Platform 和 WSL2 开好这是 Windows 上启动 Docker Desktop 最常见的前置条件。很多人的报错“Docker Desktop failed to start because virtualisation support wasnt detected”其实分两种情况一种是 CPU 虚拟化没在 BIOS 打开另一种就是 WSL2 依赖的 Windows 功能没启用或没更新内核。用管理员身份打开 PowerShell依次执行下面两条命令dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart执行完重启系统然后再去安装 WSL2 的内核更新包。这个内核更新包是独立安装程序不装的话后续wsl --set-default-version 2会报错。装完执行wsl --status如果看到“默认版本2”恭喜前置准备已经到位。2.3 第三步启动并验证现在双击 Docker Desktop 图标。首次启动会有一个“Accept terms”之类的协议确认同意之后托盘图标会转圈等它变成稳定状态就行。在终端里跑docker version看输出内容。关键要看两个部分Client 的版本以及 Server 的版本。如果只显示 Client 信息Server 部分报“cannot connect to the Docker daemon”说明守护进程还没起来继续往下看第五节排查。如果一切正常再跑一个经典测试docker run hello-world能拉到镜像并打印出“Hello from Docker!”这段提示说明整个环境已经通了。3. Linux 服务器安装Ubuntu 和 CentOS 两套姿势3.1 Ubuntu 用官方仓库装服务器上装 Docker推荐用官方 apt 仓库而不是直接apt install docker.io前者是 Docker 官方维护的最新版后者是 Ubuntu 仓库里的老版本很多新功能没有。步骤很固定先装依赖sudo apt update sudo apt install -y ca-certificates curl gnupg 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然后添加仓库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最后执行安装sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这里我特意把docker-compose-plugin也加进来了因为新版 Docker 已经把 compose 集成成插件执行docker compose中间没有横杠就是用它。后面部署多容器项目非常刚需。装完启动服务sudo systemctl enable --now docker3.2 CentOS 7 的注意事项CentOS 7 虽然已经进入维护期但国内存量服务器还非常多。装 Docker 主流程不复杂sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y docker-ce docker-ce-cli containerd.io sudo systemctl start dockerCentOS 7 最容易踩的坑是内核版本和 iptables 的兼容问题。Docker 在新版本里默认的防火墙后端是nftablesCentOS 7 内核自带的是旧式 iptables两者不一致可能导致 Docker 启动成功但容器之间网络不通。遇到这种问题可以在/etc/docker/daemon.json里加一行{ iptables: false }但注意这个开关会关闭 Docker 的 iptables 管理端口映射也可能受影响。真要稳妥推荐把盒子里的系统升级到新的发行版然后使用iptables-nft很多网络问题能少大半。3.3 用 systemctl 管理 Docker 服务的正确方式Linux 上装了 Docker 之后服务管理核心就两个命令sudo systemctl start docker # 启动 sudo systemctl enable docker # 开机自启启动失败时别忙着卸载重装。先看状态和日志sudo systemctl status docker sudo journalctl -u docker.service -n 50日志会给出具体失败原因绝大多数问题在日志里都能找到线索。4. 装完之后第一次配置镜像加速、权限、自启动4.1 配置镜像加速daemon.json这是国内用户装完 Docker 后最需要做的一件事。不配置加速拉取官方镜像的速度会让你怀疑人生镜像下载慢的搜索量常年居高不下。在/etc/docker/daemon.json写入你的加速地址{ registry-mirrors: [https://你的加速地址.mirror.example.com] }这个加速地址不建议从网上随便找一个就用因为很容易失效。最稳的方法注册云厂商容器服务后在控制台的“镜像加速器”页面会给你分配专属地址。获取后填进daemon.json然后重启sudo systemctl restart docker docker info执行docker info在输出里找到Registry Mirrors一栏能看到你配置的地址就算生效了。在 Docker Desktop 里配置加速的方法更简单Settings → Docker Engine直接编辑 JSON 配置右下角 Apply Restart 即可。它和 Linux 的/etc/docker/daemon.json语法完全一样。4.2 把 docker 命令权限交给普通用户刚装完 Docker用普通用户执行docker ps会报permission denied while trying to connect to the docker daemon socket at unix:///var/run/docker.sock这不是 Docker 没装好而是因为默认情况下docker.sock只允许 root 用户访问。解决办法是创建docker用户组并把自己的账号加进去sudo groupadd docker sudo usermod -aG docker $USER执行完一定要重新登录终端或者注销再登录让用户组权限生效。如果你不想重新登录也可以临时用newgrp docker进入新组会话验证。这一步做完docker ps就不需要额外加sudo了。注意直接给 docker 组里的用户等价于给 root 权限所以只加到可信账号上不要乱加。4.3 让 Docker 开机自动启动容器部署好以后可能因为服务器重启容器全没了实际上容器并没有没只是 Docker 服务没起来导致容器没自动拉起。Linux 上执行sudo systemctl enable dockerWindows 上的 Docker Desktop 则在 Settings → General 里勾选“Start Docker Desktop when you sign in to your computer”。容器层面的自启动则需要在创建容器时加--restartalways参数或者用docker update --restartalways 容器名对已有容器补充设置。我第一次部署 MySQL 时就忘了加这个参数后来机房断电重启MySQL 没有跟着 Docker 起来排了半天才发现只是少了这个参数。5. 高频报错逐一拆启动失败、权限拒绝、下载慢5.1 Docker Desktop 报 virtualisation support wasnt detected这个问题在 Windows 上出现频率极高完整错误一般长这样Docker Desktop failed to start because virtualisation support wasnt detected. Please ensure that virtualisation is enabled in your BIOS.好多朋友第一反应是重装 Docker Desktop重装两遍还是同样的错。根因基本只有两个一是 BIOS 里没开 CPU 虚拟化。进 BIOS找到 Intel Virtualization Technology 或 SVM ModeAMD 平台把它设为 Enabled保存重启。判断是否生效就用前面说的任务管理器 → CPU → 虚拟化是否显示“已启用”。二是开了 BIOS 虚拟化但 Windows 的虚拟机平台功能没启用。执行 PowerShell 命令把两个功能开启后重启Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux -All Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -All然后重新启动 Docker Desktop。实践下来80% 的“virtualisation support was not detected”都是第二种情况因为现在的电脑默认都开了 VT-x反而是 Windows 功能层面没打开。5.2 服务启动失败 / Failed to start Docker Application Container EngineLinux 上执行sudo systemctl start docker报Job for docker.service failed或者Failed to start Docker Application Container Engine这是比较头疼的一种。处理思路不要反复 start而是直接看日志sudo journalctl -u docker.service --no-pager | tail -100我遇到过的情况主要有两类与 iptables / firewalld 冲突。日志里能看到类似iptables failed: iptables --wait -t nat -A DOCKER ...的报错。常见处理是清掉 Docker 自己创建的网络规则后重启 Docker或临时停掉 firewalld 验证。之前的异常退出导致/var/lib/docker里的锁文件或 overlay 层残留。日志会提示unable to configure the Docker daemon with network或error creating overlay mount。这种情况通常需要停掉 Docker 后检查挂载点必要时清理/var/lib/docker/containers下的残留状态但我不建议直接全删目录全删等于所有镜像和容器数据一起没了。日志里到底哪一行报错才是解决问题的关键比去网上搜“docker服务启动失败”挨个试巫术有效得多。5.3 permission denied while trying to connect to the Docker API有些报带着unix:///var/run/docker.sock有些则完全不一样。常见的两条permission denied while trying to connect to the docker daemon socket这是配置用户组就能解决的普通权限问题按 4.2 操作即可。cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?这是守护进程真的没起来检查服务状态。还有一种比较容易忽略的情况你把 Docker 装在了宿主机上然后在另一个容器里也想调用 Docker 命令。容器里的docker客户端会去连套接字可是容器内不一定存在/var/run/docker.sock。正确姿势是把宿主机的套接字挂载进容器并确保组 ID 一致docker run -v /var/run/docker.sock:/var/run/docker.sock ...这种方式有个形象的说法叫“Docker outside of Docker”很多 CI 工具就是这么干的。5.4 镜像下载慢和网络不通镜像下载慢解决方式有两条路第一配置镜像加速参考 4.1。配置完再试docker pull速度往往立竿见影。第二拉取时选好标签。不要一上来就docker pull mysql:latest这个 latest 会拉取对应版本的全部层体积很大。换成mysql:8.0.36之类的具体版本体积更小、行为更可控复现版本也更容易。网络不通是另一个高频问题。装了 Docker 后容器能起但从宿主机访问容器里的服务却连不上先按这个思路查docker ps # 确认容器在跑看端口映射 docker port 容器名 # 查看实际映射的端口 docker inspect 容器名 | grep IPAddress # 看容器内部 IP排查完如果发现容器内部进程正常但宿主机访问不了多半是端口映射没生效docker run -p 3306:3306 ...-p参数左边是宿主机端口右边是容器内端口。只写一个-p 3306也没有错它等价于-p 3306:3306但如果你把两个端口写反了外部就永远连不上。还有一类“网络不通”其实是防火墙拦截Linux 上检查firewalld或ufw是否有放行对应端口Windows 上检查防火墙是否拦截了 Docker 的网络端口。6. 装好后别急着关终端用三个实例跑一遍6.1 MySQL 8.0 部署并让外部客户端连上装 Docker 最常见的动机之一就是在本地快速起一个 MySQL省去自己安装配初始化的一堆麻烦。拉取启动命令docker run -d \ --name mysql8 \ -p 3306:3306 \ -v mysql-data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORDMyRootPassword123 \ mysql:8.0这里加了一个具名数据卷mysql-data相当于把数据目录挂在宿主机上。以后即使你把这个容器删了再用相同卷名启动新容器数据也能找回来。如果不挂数据卷容器一旦删除数据就彻底干净了。启动后如何让外部客户端连接“访问 docker 容器内的 MySQL”是这个项目下最常见的搜索词。要点就是端口映射宿主机上的 3306 已经转发到容器内的 3306所以直接在宿主机或局域网里用mysql -h 127.0.0.1 -P 3306 -uroot -p注意-h千万别写成localhost因为很多 MySQL 客户端碰到 localhost 会企图走 unix socket 而不是 TCP导致报错连接不上。MySQL 8.0 还有一个容易踩的坑早期客户端连不上报Authentication plugin caching_sha2_password cannot be loaded。原因是 MySQL 8.0 默认认证插件是caching_sha2_password旧的工具比如太老的 Navicat、一些老版本 JDBC 驱动不认。解决办法是登录容器后创建一个用旧式认证插件的账号CREATE USER app% IDENTIFIED WITH mysql_native_password BY AppPassword123; GRANT ALL PRIVILEGES ON *.* TO app%; FLUSH PRIVILEGES;这样兼容性会好很多。不过更推荐的长期做法还是升级客户端驱动一次性解决。6.2 Redis 主从部署Redis 用 Docker 起主从比在实体机里折腾多份配置要轻松。先建一个自定义网络让主从容器之间可以互相访问docker network create redis-net启动主节点docker run -d \ --name redis-master \ --network redis-net \ -p 6379:6379 \ redis:7再启动从节点docker run -d \ --name redis-slave \ --network redis-net \ -p 6380:6379 \ redis:7 \ redis-server --replicaof redis-master 6379关键配置就是--replicaof redis-master 6379。注意这里用的是容器名redis-master而不是 IP这正是自定义网络的作用Docker 内置 DNS 会直接把容器名字解析成对应 IP。如果不用自定义网络你就得先docker inspect拿到主节点 IP再把 IP 填进--replicaof一旦容器重建 IP 变了又得重新改非常麻烦。验证主从是否生效docker exec -it redis-master redis-cli info replication输出里connected_slaves:1或更多就说明从节点连上了。6.3 GitLab 社区版部署在本地或内网搭 GitLab很多人直接面向 Docker 找方案。不过 GitLab 是个重量级选手机器内存至少 4GB低于这个配置基本起不来。命令如下docker run -d \ --name gitlab \ --hostname gitlab.example.com \ -p 8929:80 \ -p 2222:22 \ -v gitlab-data:/etc/gitlab \ -v gitlab-logs:/var/log/gitlab \ -v gitlab-config:/var/opt/gitlab \ gitlab/gitlab-ce:latest这里我把 HTTP 端口映射成宿主机的 8929SSH 映射成 2222避免和本机已有服务冲突。启动过程比较漫长第一次拉镜像可能就要几分钟容器初始化 GitLab 内部服务可能要等上两三分钟。可以用docker logs -f gitlab跟踪启动状态看到gitlab Reconfigured!或类似字样再访问http://宿主机IP:8929。首次访问会让你重置 root 密码这个密码不设置好是没法往下用的。很多人卡在这一步以为是端口没映射好。我在实际部署中最大的体会是Docker 的绝大多数问题都不是难在某个命令不会写而是环境之间差异太大。同一个报错在 Windows 上可能是 WSL2 没开在 Linux 上可能是 iptables 冲突在 CentOS 上可能是内核太老。所以遇到问题不要急着搜“docker 安装失败”然后照着玄学改配置一步到位的方法永远是看日志、看状态、看实际报错——定位根因永远比瞎试有效。装 Docker 这件事真把这些细节理顺了后面不管是跑 MySQL、Redis 还是 GitLab都会顺很多。