Windows下Docker搭建开发环境:WSL2与docker-compose实战指南 📅 发布时间:2026/9/9 16:26:36 👁 浏览次数: 我先说下这篇指南的定位它是写给在Windows上做日常开发的兄弟们的尤其是那些被中间件安装折磨过的人。咱们平时要用MySQL、Redis、Elasticsearch、Kafka这一堆东西以前是逐个下载安装包、配置环境变量、调权限、改配置换台电脑又得从头再来。现在用Docker把这一切打包成“一条命令拉起所有服务”本地开发环境从“半天搭好”变成“十分钟搞定”这才是这篇指南要解决的核心问题。文章不会讲太深的理论重点放在Windows上的实操保证你照着做能跑起来。1. Windows下用Docker搭建开发环境的整体思路1.1 为什么Windows开发环境需要Docker介入在Docker之前Windows本地开发最头疼的事情就是中间件安装。以MySQL为例要去官网下载几百兆的安装包装的时候要注意选版本、设密码、配服务装完还得用Navicat或者命令行连上去验证。更麻烦的是RedisWindows官方根本不提供稳定版本只能去GitHub上找第三方编译的包版本陈旧不说时不时还崩一下。Elasticsearch更狠它依赖JDK版本不匹配直接启动失败而且它对中文分词、内存配置的要求又多很多人折腾一下午就为让一个ES实例跑起来。Docker的思路完全不一样它把中间件连同运行环境一起打包成镜像你用docker run就能拉起一个完整的服务不需要在宿主机上安装任何中间件本体。所有数据通过数据卷持久化到本地删掉容器数据还在。换电脑时只要把docker-compose.yml文件拷过去一条命令全部恢复。这个方案在Windows上的可行性很高关键前提是Docker Desktop依赖WSL2或Hyper-V运行Linux容器。微软这几年把WSL2做得越来越好它不是一个简单的虚拟机而是一个和Windows深度集成的轻量级Linux环境启动快、内存占用可控、文件互访方便。Docker Desktop基于WSL2后端跑容器性能和Linux本机差距很小日常开发完全够用。1.2 整体架构WSL2 Docker Desktop docker-compose这套环境的完整链路是这样的最底层是WSL2提供一个真正的Linux内核中间层是Docker Engine跑在WSL2发行版里负责管理容器再上层是Docker Desktop提供一个Windows侧的图形界面让你管理容器、镜像、卷最上层才是我们的业务——中间件容器通过docker-compose统一编排。我个人强烈建议用docker-compose而不是逐个docker run。原因很直接中间件之间通常有依赖关系比如你的应用要连MySQL、写Redis、查ES用compose可以在一个yml文件里定义全部服务一个命令全部启动一个命令全部停止端口、数据卷、网络、环境变量全部集中管理。后期加一个中间件只需要在yml里加一个服务块不用记那一长串docker run参数。还有一个细节要注意Docker Desktop默认创建一个名为docker-desktop的WSL发行版来跑Docker引擎你不需要手动操作这个发行版。但如果你电脑里还有自己的WSL发行版比如Ubuntu两者可以共存互不干扰。docker-compose文件放在Windows文件系统还是WSL文件系统里都行不过放Windows侧访问更方便Docker Desktop会自动处理路径转换。1.3 选型考量镜像版本、端口规划、数据持久化中间件选型看起来简单实际操作中有几个坑提前避掉能省很多事。先说镜像版本MySQL选8.0而不是5.7因为8.0是当前主流新的应用基本都跑在8.0上Redis选7.x或最新稳定版Elasticsearch别选太新的版本要和你的客户端库版本配套我会在后面的章节里给出一套经过验证的组合。端口规划是另外一个容易忽略的问题。本地开发时多个项目共用一套中间件是常态所以端口规划要统一——MySQL用3306、Redis用6379、Elasticsearch用9200、Kafka用9092你的所有项目都连接这些固定端口省得每个项目改一套配置。如果某个端口被占用优先考虑用netstat -ano | findstr 3306查清楚是谁占用的而不是硬改中间件端口因为中间件端口一动所有项目的连接配置都要跟着动。数据持久化是必须做好的。容器本身是“用完即扔”的一旦容器删除容器内部的MySQL数据、Redis快照、ES索引全部清空。所以所有需要持久化的组件必须把数据目录挂载到宿主机我用本地的D:\docker-data\目录统一管理所有中间件的数据建议你也这样做好处是数据集中、备份方便、清理简单。2. 环境准备从零安装Docker Desktop到WSL2配置2.1 安装Docker Desktop前的系统检查与准备安装Docker Desktop前先确认几个前提条件不然装到一半容易卡住。第一系统要求Windows 10 64位专业版/企业版/教育版或者Windows 11任意版本。Windows 10家庭版也可以装但需要手动开启Hyper-V操作麻烦一些最推荐的方式是装WSL2把Docker Desktop的后端切到WSL2家庭版也能跑得很顺。第二CPU要支持虚拟化并且要在BIOS里开启。你可以打开任务管理器在“性能”标签页里看“虚拟化”那一行是不是“已启用”如果显示“已禁用”需要重启进BIOS打开Intel VT-x或AMD-V。第三内存建议至少8GB16GB更舒服因为WSL2本身会占用一部分内存加上中间件容器的开销8GB会比较紧张。有一个问题特别常见Docker Desktop启动时报virtualization support wasnt detected或者weve detected that you have an incompatible version of windows。这个报错90%是虚拟化没开或WSL2没装全。解决办法先确认BIOS里虚拟化已开启然后以管理员身份打开PowerShell分别执行以下三条命令dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart wsl --set-default-version 2执行完重启电脑再打开Docker Desktop大概率能解决。2.2 WSL2环境安装与内存限制配置WSL2是Docker Desktop运行Linux容器的核心底座所以先要把WSL2装好。在PowerShell里执行wsl --install会自动安装默认的Ubuntu发行版如果不想装Ubuntu也可以执行wsl --install -d Ubuntu-22.04指定版本。装完后需要设置WSL默认版本为2因为WSL1和WSL2的内核机制完全不同Docker Desktop只支持WSL2。这里有个容易踩的坑WSL2默认会分配最多50%的物理内存给它使用如果你的电脑是16GB内存Docker跑起来后WSL2最多吃掉8GB再叠加Windows自己用的部分内存告急很正常。解决办法是在用户目录下创建一个.wslconfig文件内容如下[wsl2] memory6GB processors4 swap4GB localhostForwardingtrue设置完在PowerShell里执行wsl --shutdown让配置生效重启Docker Desktop后内存占用就可控了。这里的localhostForwardingtrue很关键它保证Windows里可以通过localhost直接访问WSL2里运行的容器端口不用记那些复杂的IP。2.3 Docker Desktop安装与国内镜像加速配置WSL2准备好之后去Docker官网下载Docker Desktop Installer.exe双击安装一路Next就行。安装过程中会询问用Windows容器还是Linux容器开发中间件场景选Linux容器。装完启动第一次打开会提示接受协议选Accept即可。Docker Desktop装完后第一件事就是配置镜像加速。国内直接拉Docker Hub的镜像速度非常不稳定几十兆的镜像可能拉半天更别提ES、Kafka这种几百兆的大镜像。做法是在Docker Desktop的Settings里找到Docker Engine编辑配置文件加入以下registry-mirrors配置{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com, https://docker.mirrors.ustc.edu.cn ] }提示镜像加速地址一直有变动网上的教程可能过时。如果你配置后发现某些地址失效就去搜一下当前可用的加速源。配置完成后点Apply RestartDocker Desktop会重启。验证方式在命令行执行docker info看到Registry Mirrors下面列出了你配置的地址就表示生效了。实测配置加速后拉取mysql:8.0镜像的速度能从十几分钟降到一两分钟提升非常明显。3. Docker基础操作镜像、容器、数据卷、网络3.1 镜像与容器的核心概念和常用命令Docker的底层原理不复杂但理解几个核心概念能避免很多操作失误。镜像是一个只读模板里面包含完整的运行环境容器是镜像的运行实例可以启动、停止、删除。类比的话镜像就像安装程序的ISO文件容器就是安装运行起来的那个程序。每次docker run都会从镜像创建一个新容器对容器做的所有修改在容器删除后都会丢失除非你提交成新镜像或挂载了数据卷。常用的操作命令并不需要背很多日常工作主要就是这几个# 拉取镜像 docker pull mysql:8.0 # 查看本地镜像 docker images # 运行一个一次性容器比如测试连接 docker run -it --rm mysql:8.0 mysql -h127.0.0.1 -uroot -p # 查看运行中的容器 docker ps # 查看所有容器包括已停止的 docker ps -a # 进入容器内部 docker exec -it 容器名 bash # 查看容器日志 docker logs -f 容器名 # 删除容器 docker rm -f 容器名这些命令是最高频的遇到忘记参数时直接docker --help查比搜索引擎快得多。3.2 数据卷挂载与容器生命周期管理数据卷volume是Docker持久化数据的标准方式它把宿主机的一个目录直接挂载到容器内部某个路径。容器写这个路径就是在写宿主机磁盘容器删了数据还在。挂载方式是-v 宿主机路径:容器内路径宿主机路径用绝对路径。我自己管理数据的习惯是所有中间件数据统一放在D:\docker-data\服务名下。例如MySQL的数据映射到D:\docker-data\mysql\dataRedis的快照文件映射到D:\docker-data\redis\data。这样做有个好处到了要清理环境的时候直接把这个目录删掉就是彻底重置不会留下任何残留。容器生命周期管理有一个很重要的原则先停再删不要直接删。因为直接docker rm -f会跳过优雅停止的过程对MySQL这类对数据一致性敏感的服务可能造成数据损坏。正确顺序是docker stop 容器名等几秒钟让它正常退出再docker rm 容器名。如果容器卡住了说明有进程挂起用docker rm -f强制删除也行但这是最后手段。3.3 docker-compose的统一编排优势docker-compose相当于一个声明式编排工具你在yml文件里声明所有服务的配置它来负责创建、启动、停止。它的价值不仅在于节省命令输入更重要的是配置即代码——你的环境配置全部沉淀在一个文件里可以放进git仓库团队里任何人拉下来就能跑同样的环境。我们可以用一个docker-compose.yml管理MySQL、Redis、Elasticsearch、Kafka四个服务然后通过docker-compose up -d一键启动。启动顺序由compose的depends_on字段控制比如你的应用需要SQL先启动、Redis再启动但这种依赖只是启动顺序不代表服务内部已经完全初始化完成所以应用层还是要做好重试连接。docker-compose的常用命令也需要熟记# 构建并启动所有服务后台运行 docker-compose up -d # 启动指定服务 docker-compose up -d mysql # 查看服务状态 docker-compose ps # 查看日志 docker-compose logs -f # 停止所有服务 docker-compose down # 停止并删除所有数据卷彻底清理慎用 docker-compose down -v写这个文件不算难但有几个坑需要在后面逐个中间件说明。接下来就到重头戏常用中间件的一键部署。4. 常用中间件一键部署MySQL、Redis、Elasticsearch、Kafka4.1 MySQL 8.0容器化部署与参数调优MySQL是后端开发绕不开的第一个中间件容器化部署最关键的是数据持久化和字符集设置。关于字符集我在Windows上遇到过不少乱码问题统一使用utf8mb4基本能解决因为utf8mb4是MySQL 8.0的默认字符集它支持emoji和所有Unicode字符和咱们用的UTF-8编码完全兼容。一个完整的MySQL容器启动命令如下docker run -d \ --name mysql-8.0 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123456 \ -e TZAsia/Shanghai \ -v D:/docker-data/mysql/data:/var/lib/mysql \ -v D:/docker-data/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf \ --restartalways \ mysql:8.0参数逐个解释-d表示后台运行--name指定容器名-p 3306:3306把宿主机的3306端口映射到容器的3306-e MYSQL_ROOT_PASSWORD设置root密码第一次初始化时生效-v把容器内的数据目录映射到本地保证容器删除后数据不丢--restartalways表示Docker重启时自动拉起这个容器保证你电脑重启后中间件能自动恢复。关于配置文件我建议单独创建一个D:\docker-data\mysql\conf\my.cnf内容如下[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci default-time-zone08:00 max_connections500 innodb_buffer_pool_size512Mdefault-time-zone08:00很重要不然容器默认使用UTC时区你存进数据库的时间会比北京时间晚8个小时排查问题时会很困惑。innodb_buffer_pool_size设置InnoDB的缓冲池大小512M是开发环境的合理值太小会频繁刷盘太大浪费内存。注意如果MySQL第一次启动时没有挂载配置文件后期再挂载上去可能不会立即生效因为有些参数在初始化时已经写入系统表了。最稳妥的做法是第一次启动时就把配置挂载好。4.2 Redis 7.x容器化部署与数据持久化配置Redis相比MySQL简单不少没有复杂的用户体系只需要关注密码、持久化和基本配置。我用的启动命令是docker run -d \ --name redis-7 \ -p 6379:6379 \ -e TZAsia/Shanghai \ -v D:/docker-data/redis/data:/data \ -v D:/docker-data/redis/conf/redis.conf:/etc/redis/redis.conf \ --restartalways \ redis:7.2 redis-server /etc/redis/redis.conf注意最后一段redis-server /etc/redis/redis.conf这是指定容器启动时使用的配置文件路径。如果省略这段容器会用默认配置启动。默认配置下Redis没有任何密码保护端口直接暴露在Windows本地开发时问题不大但如果Docker Desktop的网络环境比较复杂建议还是配置密码。我的redis.conf核心配置如下requirepass redis123456 appendonly yes appendfsync everysecrequirepass设置访问密码客户端连接时用redis-cli -a redis123456验证。appendonly yes开启AOF持久化appendfsync everysec表示每秒同步一次AOF文件这样Redis崩溃时最多丢一秒数据本地开发完全够用。/data目录是Redis持久化文件的默认存放位置AOF文件会写到这里并且和宿主机目录做了映射。4.3 Elasticsearch 8.x容器化部署与中文分词支持Elasticsearch是中间件里最费劲的一个它依赖JDK、对系统参数敏感、内存配置不当会启动失败。容器化部署最大的好处是把JDK依赖打包进镜像省掉了宿主机装JDK的麻烦。但Windows上跑ES还有一个特别坑的问题ES对vm.max_map_count有要求Linux默认值是65530ES要求至少262144否则启动会报错。在Linux上可以执行sysctl -w vm.max_map_count262144修改在WSL2里也可以执行同样的命令但WSL2重启后配置会丢失所以需要写进WSL的启动脚本里或者每次启动容器前手动执行。ES 8.x的启动命令如下docker run -d \ --name elasticsearch-8 \ -p 9200:9200 \ -e discovery.typesingle-node \ -e ES_JAVA_OPTS-Xms512m -Xmx512m \ -e TZAsia/Shanghai \ -v D:/docker-data/elasticsearch/data:/usr/share/elasticsearch/data \ -v D:/docker-data/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ --restartalways \ docker.elastic.co/elasticsearch/elasticsearch:8.11.0discovery.typesingle-node声明单节点模式因为本地开发不需要集群。ES_JAVA_OPTS限制JVM堆内存为512M如果不设置ES会按机器物理内存的一半分配堆内存16GB内存的电脑直接分8GB给JVM很容易拖垮整个系统。数据目录和插件目录都做了挂载这样以后安装分词插件如IK中文分词时把插件jar包拷到宿主机的plugins目录重启容器就能加载。ES 8.x默认开启了安全认证访问http://localhost:9200需要用户名密码。第一次启动时控制台会打印出elasticsearch用户的初始密码要记得保存。如果想省掉认证的麻烦可以在启动命令里加上-e xpack.security.enabledfalse关闭安全认证本地开发无所谓但如果你要模拟生产环境建议留着。关于IK分词插件在Windows上操作是这样的先到GitHub下载对应ES版本的IK插件包解压后把整个文件夹放到D:\docker-data\elasticsearch\plugins\ik目录下然后重启ES容器。版本必须和ES版本精确对应ES 8.11.0要下载8.11.0版本的IK不然插件加载不了。4.4 Kafka容器化部署与Windows端口映射特殊处理Kafka是这套环境里最麻烦的一个主要原因是它内部机制复杂对外暴露的端口不止一个。Kafka使用ZooKeeper或KRaft模式管理集群元数据且客户端连接时要通过advertised.listeners找到broker地址。在容器里部署时如果这个配置不对你在Windows上用代码连Kafka会一直超时。推荐用Bitnami的Kafka镜像配合KRaft模式来简化部署。在docker-compose里它的配置是这样的kafka: image: bitnami/kafka:3.6 container_name: kafka-3 ports: - 9092:9092 environment: - KAFKA_CFG_NODE_ID0 - KAFKA_CFG_PROCESS_ROLEScontroller,broker - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS0kafka:9093 - KAFKA_CFG_LISTENERSPLAINTEXT://:9092,CONTROLLER://:9093 - KAFKA_CFG_ADVERTISED_LISTENERSPLAINTEXT://127.0.0.1:9092 - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAPCONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT volumes: - D:/docker-data/kafka/data:/bitnami/kafka restart: always关键点在第9行KAFKA_CFG_ADVERTISED_LISTENERSPLAINTEXT://127.0.0.1:9092。Kafka启动后会把127.0.0.1:9092这个地址广播给客户端Windows上的应用连Kafka时就是用这个地址。如果这个地址写成容器内部的主机名比如kafka:9092Windows应用就解析不了。这是个经典问题很多人在Windows上用Docker跑Kafka连接失败原因就在这。验证Kafka是否正常启动可以看日志输出启动完成后日志里会有started (kafka.server.KafkaRaftServer)这样的信息。然后可以下载一个Kafka客户端工具比如Offset Explorer连接127.0.0.1:9092测试能连上就说明部署成功。4.5 常用中间件的docker-compose完整配置参考把上面所有中间件整合成一个docker-compose.yml这是整套方案的核心文件。我在本地用的就是这份配置实测下来稳定跑了大半年version: 3.8 services: mysql: image: mysql:8.0 container_name: mysql-8.0 ports: - 3306:3306 environment: - MYSQL_ROOT_PASSWORDroot123456 - TZAsia/Shanghai volumes: - D:/docker-data/mysql/data:/var/lib/mysql - D:/docker-data/mysql/conf/my.cnf:/etc/mysql/conf.d/my.cnf restart: always redis: image: redis:7.2 container_name: redis-7 ports: - 6379:6379 environment: - TZAsia/Shanghai volumes: - D:/docker-data/redis/data:/data - D:/docker-data/redis/conf/redis.conf:/etc/redis/redis.conf restart: always command: redis-server /etc/redis/redis.conf elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0 container_name: elasticsearch-8 ports: - 9200:9200 environment: - discovery.typesingle-node - ES_JAVA_OPTS-Xms512m -Xmx512m - TZAsia/Shanghai - xpack.security.enabledfalse volumes: - D:/docker-data/elasticsearch/data:/usr/share/elasticsearch/data - D:/docker-data/elasticsearch/plugins:/usr/share/elasticsearch/plugins restart: always kafka: image: bitnami/kafka:3.6 container_name: kafka-3 ports: - 9092:9092 environment: - KAFKA_CFG_NODE_ID0 - KAFKA_CFG_PROCESS_ROLEScontroller,broker - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS0kafka:9093 - KAFKA_CFG_LISTENERSPLAINTEXT://:9092,CONTROLLER://:9093 - KAFKA_CFG_ADVERTISED_LISTENERSPLAINTEXT://127.0.0.1:9092 - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAPCONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT volumes: - D:/docker-data/kafka/data:/bitnami/kafka restart: always这份配置对端口、环境变量、数据卷都做了统一定义直接保存为docker-compose.yml在文件所在目录打开命令行执行docker-compose up -d四个中间件全部启动。首次启动需要拉取四个镜像总共大概2GB左右网络快的话几分钟就完事。之后每次启动都是秒级完成方便得很。5. Windows一键部署脚本编写与开机自启5.1 编写start-all.bat一键启动脚本docker-compose解决了服务编排问题但Windows用户还是习惯双击一个文件就搞定所有事情。我写了一个start-all.bat脚本配合docker-compose使用实现“双击启动、双击停止”。echo off chcp 65001 nul title Docker Local Environment Manager echo echo Docker Local Middleware Manager echo echo. rem 检查Docker Desktop是否运行 tasklist /fi imagename eq Docker Desktop.exe | findstr /i Docker Desktop.exe nul 21 if errorlevel 1 ( echo [INFO] Docker Desktop is not running, starting it... start C:\Program Files\Docker\Docker\Docker Desktop.exe echo [INFO] Waiting for Docker Engine to be ready... timeout /t 20 /nobreak nul ) else ( echo [INFO] Docker Desktop is already running. ) rem 等待Docker Engine就绪 echo [INFO] Checking Docker Engine connection... :check_docker docker info nul 21 if errorlevel 1 ( echo Waiting for Docker Engine... timeout /t 3 /nobreak nul goto check_docker ) echo [INFO] Docker Engine is ready. echo. rem 切换到docker-compose.yml所在目录 cd /d D:\docker-compose rem 启动所有服务 echo [INFO] Starting all middleware services... docker-compose up -d echo. echo [INFO] All services started. Checking status... docker-compose ps echo. pause这个脚本的关键逻辑有三处第一用tasklist检查Docker Desktop进程是否在跑没跑则自动启动它第二用docker info循环探测Docker Engine是否就绪因为Docker Desktop软件启动后Docker Engine还需要几秒才能响应第三跳转到docker-compose.yml所在目录再执行命令确保能找到配置文件。配套的stop-all.bat也很简单echo off chcp 65001 nul echo Stopping all middleware services... cd /d D:\docker-compose docker-compose down echo All services stopped. pause5.2 开机自启配置与Windows服务化如果希望电脑开机后中间件自动就绪可以这样配置把start-all.bat的快捷方式放入shell:startup启动文件夹或者用Windows任务计划程序创建一个开机任务触发条件选“计算机启动时”操作指向start-all.bat并勾选“使用最高权限运行”。这里有一个实测出来的细节Docker Desktop被WSL2拖慢启动是常态如果开机自启脚本在Docker Engine就绪前就执行docker-compose up -d会报Cannot connect to the Docker daemon错误。所以脚本里的循环探测逻辑是必须的不能直接timeout 5秒就开跑。探测超时可以设长一点比如最多等60秒超过60秒还没就绪就提示用户手动检查Docker Desktop状态。另外还有一个端口占用的隐患如果Windows上之前装过原生的MySQL、Redis服务它们的端口会一直占用3306、6379启动docker-compose时会报port is already allocated。彻底解决方法是把原生服务卸载或停用别让它们和Docker抢端口。查端口占用用netstat -ano | findstr 3306然后根据PID在任务管理器里找到对应进程关掉。5.3 资源占用过高的优化.wslconfig与Docker资源限制整套环境跑起来以后四个中间件加WSL2内存占用大概在2.5GB到3GB之间处理器占用在空闲时基本是0。但如果你电脑配置一般还是建议做两层优化。第一层是.wslconfig里限制WSL2的总内存和CPU数前面已经提到过。这里补充一个关键点设置localhostForwardingtrue能确保Windows应用通过localhost访问容器内的服务这个开启后性能开销可以忽略。第二层是给每个容器设置资源限制。docker-compose里可以给每个服务加deploy字段限制CPU和内存services: elasticsearch: ... deploy: resources: limits: memory: 1g cpus: 1.0这样即使ES内部JVM设置出错也不会拖垮整个系统。本地开发环境的首要目标是稳定资源够用就行没必要给中间件分配大量内存。6. 常见问题排查与避坑实操记录6.1 Docker Desktop启动失败与WSL2故障排查这类问题几乎每个Windows用户都遇到过最集中的表现有两种。一种是Docker Desktop启动后在任务栏图标转圈点击后弹窗报Docker Desktop failed to start because virtualisation support wasnt detected。这个报错的核心原因是虚拟化功能未启用或WSL2未正确安装。按前面第2节的方法启用Windows功能并安装WSL2后重启大概率能解决。如果仍然报错执行bcdedit /set hypervisorlaunchtype auto管理员权限开启Hypervisor。另一种是Docker Desktop启动成功但docker ps却提示Cannot connect to the Docker daemon at unix:///var/run/docker.sock。这说明Docker Desktop的引擎没起来或者WSL发行版卡住了。先检查WSL状态wsl --status和wsl -l -v如果发行版显示Stopped执行wsl --shutdown再重启Docker Desktop。如果发行版卡在Converting状态把Docker Desktop退出在PowerShell执行wsl --shutdown再重新启动Docker Desktop。6.2 镜像拉取慢、拉取超时的应对方案镜像加速已经在前文提过但即便配置了加速源某些镜像特别是docker.elastic.co这种第三方仓库的镜像仍然可能拉取超时。我的经验是如果某个镜像反复拉取失败先用docker pull看具体报错信息如果报dial tcp: lookup xxx on ...: no such host说明镜像域名解析失败或镜像源不可用换一个加速源或直接改镜像仓库地址。还有一种玄学问题加速源有时候明明配置了但拉取还是走官方源。检查方法很简单docker info看Registry Mirrors里是否有配置的地址。如果没有说明Docker Engine没加载配置文件回到Settings里确认是否点过Apply Restart。6.3 Windows下连接中间件连接超时的排查思路服务都启动了但应用连不上这是最常见的“假成功”场景。排查顺序很重要我总结了一个经验流先确认容器在跑docker ps看STATUS是Up还是Exited再确认端口映射docker port 容器名然后用宿主机本机连一下mysql -h127.0.0.1 -uroot -p如果本机能连而应用不能连检查应用的连接串是不是写错了地址或端口。还有一个容易被忽略的问题Docker Desktop在Windows上重启后WSL2的网络地址可能会变化。正常来说localhost映射是稳定的但如果你在代码里写的是WSL2的IP地址而非localhost重启后可能就连不上了。我的建议是统一用localhost不要用具体IP。6.4 乱码问题bat脚本中文乱码与容器日志乱码Windows下写批处理脚本时中文输出乱码是常态。这个问题的根源在于编码格式不匹配bat文件默认用GBK/ANSI编码保存而Windows终端默认代码页是936GBK如果文件保存为UTF-8chcp 65001切到UTF-8代码页后正常但如果不切中文全乱码。我在start-all.bat里第一行就写了chcp 65001 nul这样整个脚本运行期间的输出都切到UTF-8代码页。注意保存bat文件时选UTF-8编码带BOM不带BOM的话第一行可能会被终端误读。容器日志乱码是另一种情况尤其常见于MySQL和Elasticsearch。MySQL日志乱码多是因为系统时区或字符集配置不对检查my.cnf里character-set-serverutf8mb4是否生效。ES日志乱码则可能是Windows终端不支持ANSI颜色代码用docker logs命令时叠加了颜色控制字符不影响实际内容把输出重定向到文件再查看就没有乱码了。6.5 常用操作问题速查表我这里整理了一份速查表都是我实际操作中遇到过的问题和解决方案问题现象可能原因解决方案Docker Desktop启动报virtualisation support not detectedBIOS虚拟化未开启或Hyper-V未启用BIOS开启Intel VT-x/AMD-V启用Windows虚拟机平台功能docker ps连接不上的daemonDocker Engine未就绪或WSL卡住重启Docker Desktopwsl --shutdown后重启端口3306被占用Windows原生MySQL服务占用了端口停用Windows服务或改端口镜像拉取慢或超时加速源失效或网络原因更换加速源或手动指定镜像仓库地址Elasticsearch启动报vm.max_map_count超限WSL2内核参数不满足ES要求在WSL发行版中执行sudo sysctl -w vm.max_map_count262144Kafka客户端连接超时advertised.listeners配置为容器内主机名设置为PLAINTEXT://127.0.0.1:9092Windows重启后中间件没有自动恢复容器未设置重启策略启动容器时加--restartalwaysMySQL写入中文乱码字符集配置不正确设置character-set-serverutf8mb4WSL2内存占用过大WSL2默认占用50%物理内存配置.wslconfig限制内存上限bat脚本中文乱码编码格式不匹配保存为UTF-8 with BOM脚本开头加chcp 650017. 我踩过的一些坑和后续还能怎么扩展有件事情我印象特别深第一次在Windows上搭Kafka时所有容器都显示Up但我用Java代码怎么也连不上报错一直提示连接超时日志里也没看到什么有价值的信息。后来排查了大半天最后发现就是advertised.listeners写的是容器名kafka:9092Windows宿主机根本解析不了这个地址。改成127.0.0.1:9092之后一切正常。从那以后我养成了一个习惯凡是涉及容器间通信的配置先想清楚调用方在哪个网络环境里再决定配置什么地址。容器内部互相访问用容器名宿主机访问用localhost或127.0.0.1。还有一个建议不要用Docker Desktop自带的Kubernetes功能来跑这套中间件。K8s是为多节点集群设计的本地开发用上它只会增加复杂度和资源开销。Docker Compose已经完全满足日常需求别把简单问题搞复杂。最后聊一下扩展方向。这套环境装上以后很自然的下一步就是加监控组件Prometheus加Grafana可以采集Docker容器的CPU、内存、网络指标加一个Portainer可以提供一个Web界面管理容器比Docker Desktop自带的仪表盘更直观。如果你是做微服务的还可以集成Nacos或Consul作为注册中心在同一个compose文件里加一个服务块就完事了。善用这套模板以后你每加入一个中间件只需要写好它的启动配置测试通过后沉淀进yml文件就能持续积累出一份属于你自己的“开发环境全家桶”。