十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Windows 上虚拟机 + Docker 完整落地指南:从零搭建到避坑实战

Windows 上虚拟机 + Docker 完整落地指南:从零搭建到避坑实战 很多人学 Docker卡住的地方往往不是命令而是脑子里缺一张完整的地图。尤其当你打算走“虚拟机 Docker”这条路时Windows、Linux、容器三层关系叠在一起很容易绕晕。这篇文章我想把整条路梳理成一条线为什么在 Windows 上折腾 Docker 首选虚拟机方式、每一步在干什么、哪些坑我替你踩过了。适用对象是 Windows 为主力系统、又不想长期租云服务器也不想被 Docker Desktop 各种启动报错折磨的新手。我在本地环境里反复装过很多次这套组合踩过“虚拟化支持检测不到”“虚拟机没有网络适配器”“容器一删数据全没”这类问题。下面这些内容不涉及高深理论全部是可以直接落地的操作和思路你照着走一遍基本就能把这套组合跑通。1. 先定方向为什么我建议用“虚拟机 Docker”而不是 Docker Desktop先说结论在 Windows 上跑 Docker 容器本质上是在 Linux 内核上运行进程。Docker 依赖 Linux 内核里的 namespace、cgroups 等机制做隔离和资源限制Windows 自己不具备这套内核能力所以必须有一个 Linux 环境垫底。Windows 用户面前有两条主流路线方案底层实现适合场景Docker Desktop基于 WSL2 或 Hyper-V常规开发追求简单虚拟机 Linux Docker基于 VMware/VirtualBox 等完整虚拟化想学 Linux、需要和生产环境一致、不想被 Hyper-V 绑定Docker Desktop 的安装体验确实好但它的报错也出了名的多。最典型的就是你打开软件后看到一句Docker Desktop failed to start because virtualisation support wasnt detected这句话的直译是“检测不到虚拟化支持”实际原因大概有这么几类BIOS/UEFI 里没开启 Intel VT-x 或 AMD-VWindows 的“虚拟机监控程序平台”或 Hyper-V 功能没有启用电脑装了 VMwareVMware 和 Hyper-V 同时抢虚拟化资源导致 Docker Desktop 起不来老 CPU 本身不支持嵌套虚拟化我还遇到过另一种情况公司电脑有安全策略禁用 Hyper-V 和 WSL你根本没有权限去“启用或关闭 Windows 功能”。这种环境下Docker Desktop 基本就是废的但 VMware 是用户态软件不需要改系统组件绕开了限制。所以我的判断是如果你已经在用 VMware或者电脑配置一般、系统是 Windows 10/11 家庭版、想顺手把 Linux 命令也学了那“虚拟机 Linux Docker”这条路更适合你。它多了一层性能开销但换来的是干净、可控、和服务器完全一致的环境。容器的运行机制、端口映射、数据卷这些概念在虚拟机里理解起来反而更直观因为你一眼就能看到“容器在 Linux 内部”、“Linux 在虚拟机内部”这个物理边界。虚拟机方式还有一个杀手级优势快照。你在干净的 Linux 系统上打个快照后面 Docker 配置搞乱了、软件装坏了直接回滚到快照一分钟还原不用重装系统。2. 三层架构一次看清宿主机、虚拟机、容器的协作链路这一节是整个思路的核心我建议你花十分钟把这张图在脑子里刻下来。整个环境分三层宿主机你的 Windows 电脑负责提供 CPU、内存、磁盘这些硬件资源虚拟机VMware 里跑起来的 Linux 系统是一台完整的“假电脑”有自己的内核、文件系统、网络栈容器Docker 在 Linux 里创建的隔离进程共享 Linux 内核但有自己的文件系统、进程空间、网络空间用一个生活化的类比Windows 是小区虚拟机是一栋楼楼里每个房间是一个容器。房间容器住着不同的人应用大家共享整栋楼的供水供电Linux 内核但每个房间有自己的锁和门隔离机制。你在房间门口装了一个传菜口端口映射外面的人按门铃点菜菜就从传菜口递进去。Docker 为什么比传统虚拟机轻量关键就在“共享内核”这四个字上。传统虚拟机比如 VMware 里的 Linux需要模拟出一整套硬件然后再起一个完整的操作系统开机要一两分钟。而容器没有自己的内核Docker 引擎直接调用宿主 Linux 内核的能力启动一个容器通常只要几秒钟。下面重点说网络这条链路这是新手最容易懵的地方。我在 VMware 里创建的虚拟机通常用 NAT 模式上网。在这个模式下虚拟机和 Windows 处于一个私有网段Windows 能访问虚拟机虚拟机也能访问 Windows。假设虚拟机的 IP 是192.168.110.128你在虚拟机里跑了 Docker 容器容器内部启动了一个 Web 服务监听端口80。这时候你要访问它需要分两步先做端口映射比如-p 8080:80意思是将虚拟机的 8080 端口转发到容器的 80 端口然后在 Windows 浏览器里访问http://192.168.110.128:8080很多人的困惑是我明明在 Linux 上能访问localhost:80为什么 Windows 上访问不了因为你还没有明白端口映射这层关系。没有-p参数容器里的端口对外界是完全不可见的它只存在于容器的网络空间里。数据也是这样。容器可以随时被删除、重建如果数据存在容器内部一删就没了。所以我们在运行容器时用-v参数把 Linux 上某个目录挂载进容器数据写到宿主机这里是 Linux 虚拟机上容器销毁后数据还在。三层架构里数据最终落在 Linux 虚拟机的磁盘上而 Linux 虚拟机的磁盘又是一个文件存在于 Windows 上所以从某种意义上说数据是“穿透”了两层虚拟化落在最底下的物理磁盘里的。我用一张表总结三层各自的职责层级职责类比Windows 宿主机提供硬件资源给 VMware小区物业管理Linux 虚拟机提供 Linux 内核给 Docker整栋楼的基础设施Docker 容器运行具体应用进程楼里的房间理解这层关系后后面所有命令、报错、配置都有了解释模板容器内部是独立的容器之间是隔离的要访问就得开端口要持久化就得挂数据卷。3. 从 VMware 到 Linux环境准备里那些“当时没注意、后来全是坑”的选项环境准备阶段看起来简单其实细节很多我按顺序走一遍把容易踩的坑标出来。3.1 先确认 CPU 虚拟化已经开启不管你是 Intel 还是 AMD在装 VMware 之前先进 BIOS/UEFI 确认 CPU 虚拟化已经打开。Intel 平台找Intel VT-x或Virtualization Technology设为EnabledAMD 平台找SVM Mode设为Enabled判断是否已开启最简单的办法是打开 Windows 的任务管理器切到“性能”标签看“虚拟化”那一行是否显示“已启用”。这一步没做好的后果轻则 VMware 提示“无法运行虚拟机请确认 BIOS 中开启了虚拟化”重则安装 Linux 的过程中直接蓝屏。我在贴吧里看到很多人问“虚拟机安装Linux蓝屏”十有八九是这一步没搞定。3.2 VMware 版本与 Linux 发行版选择VMware Workstation 现在个人使用是免费的直接去官网下载最新版装 17 的 Pro 版本就行。安装过程一路下一步注意取消勾选“安装后自动检查更新”这一类选项能省不少心。Linux 发行版我推荐新手用 Ubuntu Server 的长期支持版本目前稳定可选 22.04 LTS 或 24.04 LTS。原因很简单社区资料最多Google 和各类论坛里搜任何报错几乎都能找到 Ubuntu 的答案。CentOS Stream 和 Rocky Linux 也完全能用但教程资料相对少一些如果遇到问题排查成本会高。在虚拟机设置里我建议给的配置是配置项推荐值说明CPU2 核以上少于 2 核Docker 构建镜像时很难受内存4 GB 起步建议 8 GB后面要跑 GitLab 这类吃内存的应用4 GB 是底线磁盘40 GB 以上动态分配镜像、容器日志、数据卷都会占用空间网络NAT 模式最简单不需要额外配置3.3 Linux 安装过程中的关键选择用 Ubuntu Server 的 ISO 启动后安装界面有几个地方要特别注意。第一是网络配置。安装程序的默认 DHCP 会给你一个动态 IP但 DHCP 分配的地址可能在重启后变化。后面你打包镜像、访问 Web 服务都要用 IP地址变了会很烦。建议在安装时选择手动配置静态 IP或者装完后用 netplan 改。第二是“SSH server”这个组件一定要勾选。装完后你用 Windows 上的 MobaXterm、Xshell 或者终端直接 SSH 连进虚拟机操作比在 VMware 窗口里敲命令舒服得多复制粘贴也方便。第三是安装过程中会问要不要装“Ubuntu Pro”插件、要不要加入环境统计之类的全部跳过即可。装完之后建议先把 SSH 服务启起来然后在外面的终端里连一下sudo apt update sudo apt install -y openssh-server sudo systemctl enable --now ssh如果你发现虚拟机没有网络或者 VMware 的 NAT 服务异常优先检查系统的两个服务VMware NAT Service和VMware DHCP Service。Windows 下按Win R输入services.msc找到这两个服务确认是“正在运行”如果不是右键启动。这也是“虚拟机没有网络适配器”这个问题最常见的解法。3.4 快照装机之后的第一件事系统装好、SSH 能连接、apt update 能跑通之后我建议你立刻做一件事关闭虚拟机然后在 VMware 里“拍摄快照”。快照相当于给整个虚拟机拍了一张照片之后无论你在系统里怎么折腾快照都能带你回到这个干净状态。我后面装 Docker、跑容器、改配置每次遇到不可逆的修改前都会先打个快照。这个习惯帮我省了无数次重装系统的时间。4. Docker 引擎安装与镜像加速跑通 docker run 之前的必修课Linux 系统就绪后下一步就是在里面装 Docker 引擎。4.1 安装方式选择Docker 官方提供了一个一键安装脚本但国内网络访问官方源经常很慢甚至直接超时。我建议用国内镜像源来装稳妥可靠。方法一使用阿里云镜像源安装。先装依赖sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release添加阿里云的 Docker 源curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) 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-compose-plugin方法二如果你相信自己网络够快也可以用官方脚本curl -fsSL https://get.docker.com | bash脚本会顺便把docker compose插件也装好省去手动安装的麻烦。但脚本在国内环境经常卡住如果你看到半天没反应果断 CtrlC换回镜像源方案。4.2 配置镜像加速器Docker 安装好后默认从 Docker Hub 拉取镜像国内访问速度堪忧。打开配置文件sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [https://docker.m.daocloud.io] } EOF镜像加速地址有很多免费的比如阿里云需要去控制台申请专属地址DaoCloud 这个公共地址实测可用性也不错。如果你有阿里云账号建议用阿里云的镜像加速器在容器镜像服务控制台就能看到专属地址。配置完后重启 Dockersudo systemctl daemon-reload sudo systemctl restart docker4.3 用户组配置与验证默认情况下执行 docker 命令需要 sudo非常别扭。把当前用户加入 docker 组重新登录后就能免 sudo 了sudo usermod -aG docker $USER然后重新登录或者直接newgrp docker让组立即生效。验证是否装好先看客户端和服务端状态docker version关键看Server段有没有正常显示版本号。如果只显示 Client 没有 Server大概率是服务没起来执行sudo systemctl enable --now docker然后再跑一个测试容器docker run hello-world能看到一段“Hello from Docker!”的说明文字就算正式跑通了。4.4 一个容易忽略的点dockerd 启动失败Docker 服务起不来最常见的原因是daemon.json里写入了非法的 JSON。比如镜像加速地址写错、端口号带引号、逗号放错位置。排查思路是看日志sudo journalctl -u docker --no-pager | tail -50如果日志指向daemon.json配置解析错误把文件改回来重启服务即可。这种错误很隐蔽因为docker version的 Client 部分照常显示你会有一种“Docker 装好了”的错觉直到运行容器才发现服务端根本没起来。5. 镜像、容器、数据卷、端口映射先在脑子里建好这份心智模型前面几节已经把环境和引擎都装好了但不少同学到这一步仍然觉得 Docker 很抽象。这一节我用最直白的方式把四个最核心的概念讲透。5.1 镜像和容器模板与实例的关系镜像Image是静态的、只读的模板容器Container是镜像运行起来后的实例。你可以把镜像理解成一个游戏光盘容器就是用这张光盘启动的游戏会话。同一个镜像可以启动多个容器互不干扰。但要注意容器是可变的你在容器里安装了软件、修改了文件这些改动只存在于这个容器里镜像本身不会被改变。如果用这个镜像再启动一个新容器新容器还是原来的初始状态。日常操作命令命令用途说明docker pull nginx:1.25拉取镜像nginx是镜像名1.25是标签版本docker images查看本地镜像列出镜像名、标签、大小docker run创建并启动容器最核心的命令带一堆参数docker ps查看运行中的容器加-a可以看到包括已停止的全部容器docker exec -it 容器名 bash进入容器内部容器名可以用容器 ID 前几位替代docker logs -f 容器名查看容器日志-f表示持续跟踪输出docker stop/start/restart停止/启动/重启容器不删除容器docker rm 容器名删除容器加-f强制删除运行中的docker rmi 镜像名删除镜像先删除依赖该镜像的容器一个完整的实战示例用 Nginx 跑一个网站docker run -d \ --name my-web \ -p 8080:80 \ -v /data/web:/usr/share/nginx/html \ nginx:1.25这个命令是接下来所有容器的样板拆开看每一步-d后台运行--name my-web给容器起个名字方便后续操作-p 8080:80端口映射Windows 访问虚拟机IP:8080时流量进入容器的 80 端口-v /data/web:/usr/share/nginx/html数据卷挂载Linux 的/data/web目录对应容器里的网站目录启动后你在 Linux 里往/data/web放一个index.htmlWindows 浏览器访问http://虚拟机IP:8080就能看到内容。这个例子同时涉及了端口映射和数据卷是理解 Docker 工作方式最好的入门案例。5.2 端口映射冒号两边的顺序不能反-p参数的格式是 宿主机端口:容器端口。前半部分是你在宿主机Linux虚拟机上要监听的端口后半部分是容器内服务实际监听的端口。比如 Nginx 容器内部默认监听 80 端口你希望外部通过 8080 访问所以写成-p 8080:80。如果你写成-p 80:8080意思就变成了访问虚拟机 80 端口转发到容器 8080Nginx 没在 8080 上监听结果当然是访问不了。我在排查问题的时候第一件事就是看docker ps的PORTS那一列。如果显示0.0.0.0:8080-80/tcp说明映射正确如果什么都没显示说明容器启动时没加-p参数。5.3 数据卷容器可以随便删数据不能丢容器的文件系统是临时的每次容器重建后里面所有改动都会消失。这是新手最常踩的坑跑了几天数据库某天手一抖把容器删了数据全没了。解决方法是把数据放到宿主机上。常见的两种挂载方式绑定挂载bind mount-v /data/mysql:/var/lib/mysql把宿主机物理目录挂进去最直观方便备份命名卷named volume-v mysql-data:/var/lib/mysql由 Docker 管理目录数据在/var/lib/docker/volumes/下我建议新手优先用绑定挂载因为你知道数据确切放在哪里备份、迁移都方便。数据卷还有一个好处容器升级版本时新容器直接复用旧数据卷相当于“无损升级”。比如 MySQL 从 8.0 升级到 8.1你只需要拉新镜像、用同一个数据卷启动新容器。5.4 容器网络容器之间怎么通信默认情况下每个容器有独立的 IP属于 Docker 的默认 bridge 网络。容器之间可以互相访问但地址是动态分配的不固定。更推荐的做法是创建一个自定义网络然后让容器通过容器名互相访问docker network create my-net docker run -d --name mysql8 --network my-net -e MYSQL_ROOT_PASSWORD123456 mysql:8.0 docker run -d --name adminer --network my-net -p 8080:8080 adminer在同一个自定义网络里mysql8这个容器名会解析成对应的 IP其他容器直接通过名字访问就可以了。这就避免了手动查 IP 的麻烦。6. 四个典型落地方案MySQL 8.0、Redis 主从、GitLab、青龙依赖管理概念讲完我来跑四个实际的方案。这几个案例是我自己装过很多遍的覆盖了数据库、缓存、协作平台、定时任务等常见需求照着做就能跑起来。6.1 MySQL 8.0数据库的持久化与远程访问MySQL 8.0 的启动命令docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD你的密码 \ -v /data/mysql:/var/lib/mysql \ -v /data/mysql-conf:/etc/mysql/conf.d \ --restartalways \ mysql:8.0几个参数分别解释MYSQL_ROOT_PASSWORD设置 root 密码。首次启动容器时读取之后修改不影响已有密码。/var/lib/mysql是 MySQL 存储数据的目录挂载出来防止容器删除丢数据。--restartalways机器重启后容器自动启动这个参数对长期运行的服务非常重要。MySQL 8.0 与旧版有一处明显差异默认的认证插件改成了caching_sha2_password。老版本的 Navicat、MySQL Workbench 连接时可能报“Authentication plugin caching_sha2_password cannot be loaded”解决办法是进入容器改认证方式docker exec -it mysql8 mysql -uroot -pALTER USER root% IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;还有一个高频问题容器里的 MySQL 默认 root 只允许 localhost 登录你在 Windows 上用客户端远程连接时会提示权限被拒绝。需要创建一个允许任意主机访问的用户CREATE USER app% IDENTIFIED BY 密码; GRANT ALL PRIVILEGES ON *.* TO app%; FLUSH PRIVILEGES;中文乱码的预防建议在挂在出来的conf.d目录里加一个配置文件utf8mb4.cnf[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci然后重启容器docker restart mysql8。6.2 Redis 主从最简洁的高可用方案Redis 主从可以直观地体现“一套镜像起多个容器”的思路。先创建一个自定义网络让主从节点可以互访docker network create redis-net启动主节点docker run -d \ --name redis-master \ --network redis-net \ -p 6379:6379 \ -v /data/redis-master:/data \ redis:7 redis-server --appendonly yesredis-server --appendonly yes是容器启动时要执行的命令参数开启 AOF 持久化数据默认写在容器的/data目录也就是我们挂载出来的/data/redis-master。启动从节点docker run -d \ --name redis-slave \ --network redis-net \ -p 6380:6379 \ -v /data/redis-slave:/data \ redis:7 redis-server --appendonly yes --replicaof redis-master 6379关键就俩单词--replicaof redis-master 6379让这个从节点复制redis-master这个主节点。因为两个容器在同一个自定义网络里直接用容器名就能找到对方。验证主从状态docker exec -it redis-slave redis-cli info replication重点看role:slave和master_link_status:up这两行。如果显示up说明主从已经通了。主从验证完顺手给它设个密码更稳妥--requirepass 你的密码加到主节点配置里从节点则要加--masterauth 主节点密码。6.3 GitLab内存大户和端口冲突GitLab 是我用 Docker 装过的应用里最重的一个它内置了 PostgreSQL、Redis、Nginx 等一堆组件单机内存建议至少 4 GB。如果你虚拟机只分了 2 GB启动会非常卡甚至直接启动失败。启动命令docker run -d \ --name gitlab \ -p 8443:443 \ -p 8081:80 \ -p 8022:22 \ -v /data/gitlab/etc:/etc/gitlab \ -v /data/gitlab/log:/var/log/gitlab \ -v /data/gitlab/data:/var/opt/gitlab \ --restartalways \ gitlab/gitlab-ce:latest这里特别注意端口映射的选择。GitLab 内部默认用 80 端口提供 Web 服务但很多环境里 80 被系统进程占用所以我把宿主机端口改成了 8081。启动后你在 Windows 浏览器里访问http://虚拟机IP:8081。GitLab 第一次启动很慢可能要等两三分钟才能打开页面这个阶段别急着下结论说它坏了可以用docker logs -f gitlab看启动进度。首次访问时root 用户的初始密码在容器里docker exec -it gitlab cat /etc/gitlab/initial_root_password这个密码文件只在第一次启动时生成一定要趁早保存。6.4 青龙面板一次“依赖管理”引发的隔离性教学青龙面板是一个定时任务管理平台轻量、界面友好很多人在虚拟机上装它就是想让定时脚本有个统一的运行环境。它的安装命令docker run -d \ --name qinglong \ -p 5700:5700 \ -v /data/ql/config:/ql/config \ -v /data/ql/log:/ql/log \ -v /data/ql/db:/ql/db \ -v /data/ql/scripts:/ql/scripts \ --restartalways \ whyour/qinglong:latest装完后访问http://虚拟机IP:5700就能看到登录页面。这里我想重点说“依赖管理”这个事因为它是我见过新手最容易卡住的地方。很多人把脚本放进青龙后执行时报错提示找不到模块比如Cannot find module axios或者python: command not found第一反应是去 Linux 宿主机上装依赖但装完发现还是没用。这个现象的背后正是 Docker 的隔离性在起作用。脚本是在容器内部运行的容器有自己的文件系统你看不到也访问不到宿主机上装的东西。所以在青龙后台正确做法是在“依赖管理”功能里添加需要安装的依赖或者在容器内部执行安装命令docker exec -it qinglong bash # 进入容器后根据运行语言执行 # 如果跑的是 Node.js 脚本 npm install axios -g # 如果跑的是 Python 脚本 pip3 install requests当你理解了“容器内部和宿主机是两套环境”这个原理这类问题就再也不会困扰你了。这也解释了为什么我们用-v把配置文件、脚本目录挂载出来因为容器随时会重建只有把数据放在宿主机上才能长久保存。7. 虚拟机方式最常见的坑与排查链路从报错到根因最后把我在虚拟机上跑 Docker 遇到的高频问题汇总一下每个问题都给一个完整的排查思路而不是只给一个答案。7.1 常见问题速查表现象可能原因排查方向Docker Desktop 报 virtualisation support wasnt detectedBIOS 未开启 VT-x/AMD-V、Hyper-V 未启用进 BIOS 开启虚拟化控制面板启用“虚拟机监控程序平台”VMware 虚拟机没有网络适配器VMware NAT/DHCP 服务停止services.msc 中找到 VMware NAT Service、VMnetDHCP 并启动虚拟机安装 Linux 蓝屏CPU 虚拟化未开启、VMware 版本过老BIOS 开启虚拟化更新 VMware 到 17 版本docker 命令提示权限不足用户不在 docker 组sudo usermod -aG docker $USER后重新登录容器能启动但网页打不开端口映射不正确、容器内服务监听地址不对docker ps看 PORTSdocker exec进容器确认服务监听 0.0.0.0MySQL 容器删了再启数据没了没挂载数据卷启动时加-v /data/mysql:/var/lib/mysql磁盘被占满容器日志、无用的镜像和构建缓存堆积docker system prune -a一键清理容器重启后自动启动不了没加--restartalways更新容器docker update --restartalways 容器名7.2 完整排查链路一Windows 访问不了虚拟机里的网页这是最高频的问题我给你走一遍我的排查顺序。第一步确认服务真的起了。在 Linux 虚拟机里执行curl http://localhost:容器端口如果 curl 能拿到 HTML 响应说明容器和 Docker 都没问题问题出在链路的下游。如果 curl 失败先看docker ps确认容器在运行再看docker logs 容器名找应用报错。第二步确认端口映射正确。docker ps | grep 容器名看 PORTS 列是不是0.0.0.0:8080-80/tcp这样的格式。如果没有-说明容器启动时忘了加-p需要重建容器。第三步确认 Linux 的防火墙没有拦截。Ubuntu 默认可能是ufw开启状态sudo ufw status如果Status: active就把对应端口放开sudo ufw allow 8080/tcp第四步确认 VMware 网络模式。如果虚拟机是 NAT 模式Windows 访问虚拟机 IP 没问题如果你改成了桥接模式虚拟机的 IP 可能和 Windows 不在同一个网段需要先确认 IP。这个“从内往外、逐层排查”的思路比任何一键修复工具都可靠。7.3 完整排查链路二Docker 服务起不来另一个高频问题是执行任意 docker 命令都报“Cannot connect to the Docker daemon”。第一反应sudo systemctl status docker如果显示Active: failed看日志sudo journalctl -u docker --no-pager | tail -50日志里最常出现的是failed to load listeners: listen tcp 0.0.0.0:2375: bind: address already in use这说明 2375 端口被其他进程占了常见的原因是之前手动启动过 dockerd或者有残留进程。处理办法sudo pkill dockerd sudo systemctl start docker如果日志提示unable to configure the Docker daemon with file /etc/docker/daemon.json那就是daemon.json写坏了检查 JSON 格式重点看是不是多了或少了一个逗号、引号是不是成对的。修复后再重启sudo systemctl daemon-reload sudo systemctl restart docker7.4 磁盘空间虚悬镜像与构建缓存跑一段时间 Docker 后磁盘空间会很紧张。/var/lib/docker目录只增不减。执行docker system df会看到镜像、容器、构建缓存各占多少空间。清理套路分三步docker system prune -a清理所有未使用的镜像、停止的容器、悬空数据卷和构建缓存。注意-a会删除所有没被容器引用的镜像如果这些镜像你还需要别加-a只执行docker system prune。docker builder prune -f单独清理构建缓存这个通常能释放好几个 GB。如果你启了带日志的应用日志文件也可能很大。看看du -sh /var/lib/docker/containers/*找到大文件后可以限制容器日志大小。最佳做法是在/etc/docker/daemon.json里加上{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }然后重启 Docker新容器就会自动遵守日志上限。这个配置我建议你从第一天就加上省得以后手动清日志。最后说一个我个人的使用习惯。我会在虚拟机里建一个/data目录所有容器的数据卷都挂在/data/应用名下面这样备份、迁移、清理非常直观。每次新建容器前先在脑子里过一遍这个容器的数据放哪里、端口怎么映射、要不要随系统启动、和哪些容器要通信。想清楚再敲启动命令比反复尝试改配置高效得多。一开始你可能觉得这些流程繁琐但等你按这套思路跑通 MySQL、Redis、GitLab 这些应用之后再回头看 Docker 的文档就会感觉顺眼很多——因为你已经知道它的运行逻辑剩下的都只是参数细节而已。
返回列表