这次我们来看在 Windows 上搭建 Docker 开发环境的第二部分。很多朋友在安装完 WSL 和 Docker Desktop 后,发现容器网络不通、服务访问不了,或者 WSL 子系统本身用起来不顺手,这通常是因为基础设置没到位。这篇文章不讲概念,直接解决三个核心问题:如何对 WSL 虚拟机进行基础优化、如何高效安装常用软件,以及如何正确配置防火墙规则让容器网络畅通无阻。
如果你已经装好了 WSL 和 Docker Desktop,但感觉环境“能用但不顺手”,或者容器服务总在本地访问失败,那么这篇文章的内容正是你需要的。我们会从 WSL 的包管理、镜像源、常用工具链安装讲起,再到 Docker 容器与 Windows 宿主机的网络互通,以及 Windows 防火墙的关键配置。目标是让你得到一个稳定、高效且网络透明的 Docker on WSL 开发环境。
1. 核心能力速览:本文解决什么问题?
在深入操作之前,我们先明确本文能帮你达成的目标。这不是一个从零开始的安装教程,而是针对“已安装但未优化”环境的深度设置指南。
| 能力项 | 说明与目标 |
|---|---|
| 环境定位 | 针对已安装 WSL 2 和 Docker Desktop 的 Windows 系统,进行生产级优化。 |
| 核心功能 | 1.WSL 基础设置:配置软件源、安装基础工具、优化 Shell 环境。 2.软件生态安装:涵盖开发、调试、运维常用工具链。 3.网络与防火墙:打通 WSL、Docker 容器与 Windows 宿主机的网络隔离,解决访问不通问题。 |
| 硬件门槛 | 无特殊要求,主要依赖已开启虚拟化的 CPU 和足够内存。WSL 2 本身对资源使用更高效。 |
| 启动方式 | 所有操作均在 PowerShell 或 WSL 终端中通过命令完成,无需图形化复杂配置。 |
| 适合场景 | Windows 下的 Docker 开发、Linux 环境学习、需要宿主机与容器网络互访的微服务调试、CI/CD 本地搭建。 |
| 最终效果 | 获得一个软件齐全、更新迅速、网络无阻的 Linux 子系统,Docker 容器可被宿主机及其他设备无缝访问。 |
2. 适用场景与使用边界
2.1 谁需要做这些设置?
- 后端开发者:在 Windows 上使用 Docker 运行 MySQL、Redis、Nginx 等服务,需要从宿主机(Windows)用图形化工具(如 Navicat, Another Redis Desktop Manager)连接。
- 全栈开发者:前端项目在 Windows,后端 API 在 Docker 容器中,需要解决跨环境联调时的网络请求问题。
- 运维与测试人员:需要在本地搭建接近生产的环境,进行服务编排和测试,要求网络拓扑清晰。
- 学生与学习者:希望获得一个干净、高效的 Linux 学习环境,避免频繁重装系统。
2.2 使用边界与注意事项
- 非从零安装指南:本文假设你已成功安装 WSL 2 和 Docker Desktop。如果未安装,请先参考官方文档完成第一步。
- 防火墙风险提示:调整防火墙规则会改变系统网络行为。本文提供的规则旨在放行开发流量,请勿在生产服务器或对安全要求极高的个人主机上随意放行所有端口。
- 网络配置差异:不同的网络环境(如公司内网、校园网、使用特定代理)可能导致本文方案需要微调。请理解原理后灵活调整。
- WSL 发行版选择:本文以 Ubuntu 为例,但原理适用于任何 WSL 发行版(如 Debian, CentOS Stream)。命令可能因包管理器(
apt/yum/dnf)而异。
3. 环境准备与前置检查
在开始优化之前,请确保你的基础环境是就绪的。打开 PowerShell(管理员身份),执行以下检查命令。
3.1 确认 WSL 与 Docker 状态
# 1. 查看已安装的 WSL 发行版及其状态 wsl -l -v # 预期输出示例: # NAME STATE VERSION # * Ubuntu Running 2 # 如果 STATE 不是 Running,使用 `wsl -d Ubuntu` 启动(将 Ubuntu 替换为你的发行版名称)。 # 确保 VERSION 为 2,以获得更好的性能和完整的系统调用兼容性。 # 2. 检查 Docker Desktop 是否运行 docker --version # 应输出 Docker 版本号,如 `Docker version 24.0.7, build afdd53b` # 3. 运行一个测试容器,验证 Docker 引擎正常工作 docker run --rm hello-world # 如果成功,会看到 “Hello from Docker!” 等信息。3.2 检查虚拟化与网络基础
- 虚拟化已开启:这通常在安装 WSL 2 时已解决。如果之前遇到过 “Virtualization is disabled” 错误,需进入 BIOS/UEFI 设置开启 Intel VT-x 或 AMD-V。
- WSL 2 内核更新:确保使用最新版 WSL 2 内核。可通过 Microsoft Store 中的 “Windows Subsystem for Linux Update” 或运行
wsl --update来更新。 - 防火墙默认状态:了解当前防火墙是开启还是关闭。我们将在后续配置中与之协作,而非简单关闭。
4. WSL 虚拟机基础设置
一个“开箱即用”的 WSL 镜像往往不是最佳状态。我们首先对其进行优化,提升日常使用体验。
4.1 更新系统与更换软件源
启动你的 WSL 发行版(例如 Ubuntu),执行以下操作。国内用户强烈建议更换镜像源以加速下载。
# 1. 备份原有的源列表 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak # 2. 编辑源列表文件(这里以 Ubuntu 22.04 为例,使用清华源) # 你可以根据你的发行版和版本,从镜像站官网获取对应的源内容。 sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list sudo sed -i 's@//.*security.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list # 3. 更新软件包列表并升级所有已安装的包 sudo apt update && sudo apt upgrade -y注意:如果你使用 Debian、CentOS 等,请替换为对应的镜像源(如阿里云、中科大)。这一步能极大缩短后续软件安装时间。
4.2 安装基础工具链
这些工具是开发、调试和系统管理的基础。
# 安装常用工具包 sudo apt install -y \ curl wget git vim nano htop net-tools iputils-ping dnsutils \ # 网络与编辑工具 build-essential pkg-config autoconf libtool \ # 编译工具链 software-properties-common apt-transport-https ca-certificates gnupg lsb-release # 软件源管理4.3 配置 Shell 环境(可选但推荐)
优化你的~/.bashrc或~/.zshrc,让终端更好用。
# 编辑 bashrc vim ~/.bashrc在文件末尾添加以下内容:
# 自定义别名 alias ll='ls -alF' alias la='ls -A' alias l='ls -CF' alias dps='docker ps --format \"table {{.ID}}\\t{{.Names}}\\t{{.Status}}\\t{{.Ports}}\"' alias dcup='docker-compose up -d' alias dcdown='docker-compose down' # 设置更醒目的命令提示符 (PS1) export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' # 使能颜色输出 export LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:'保存退出后,执行source ~/.bashrc使配置立即生效。
5. 软件安装:打造全能开发环境
基础系统设置好后,我们来安装一些在开发、容器管理和日常使用中高频出现的软件。
5.1 版本管理工具
# 安装 Git(如果未安装) sudo apt install -y git git --version # 安装并配置 Git 用户信息(请替换成你自己的) git config --global user.name "Your Name" git config --global user.email "your.email@example.com" git config --global core.editor vim5.2 容器与编排相关工具
虽然 Docker Desktop 提供了核心引擎,但一些 CLI 工具能让操作更便捷。
# Docker Compose (Docker Desktop 通常已包含,但可确保独立安装) sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose --version # 可选:Lazydocker - 终端下的 Docker 图形化管理工具 curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash5.3 网络诊断与开发工具
# 网络诊断工具 sudo apt install -y netcat-openbsd traceroute mtr tcpdump # HTTP 测试工具 (curl 已安装,可加装 httpie) sudo apt install -y httpie # 端口扫描工具 (nmap),用于检查端口开放情况 sudo apt install -y nmap5.4 编程语言环境(按需安装)
# Node.js (通过 NodeSource 安装 LTS 版本) curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - sudo apt install -y nodejs node --version && npm --version # Python3 及 pip (通常已预装,确保最新) sudo apt install -y python3 python3-pip python3-venv python3 --version && pip3 --version # Java (OpenJDK 17) sudo apt install -y openjdk-17-jdk java -version6. 网络核心:理解 WSL 2 与 Docker 的网络架构
这是解决“访问不通”问题的关键。你必须理解数据流是如何走的。
6.1 WSL 2 的网络模式
WSL 2 采用虚拟化技术,运行在一个轻量级 Hyper-V 虚拟机上。因此:
- WSL 2 拥有独立的虚拟网络:它有一个与 Windows 宿主机不同的 IP 地址段。
- 出站连接(Outbound):从 WSL 内部访问外部互联网(如
curl baidu.com)是通的,因为 Windows 宿主机会为其做 NAT(网络地址转换)。 - 入站连接(Inbound):从外部(Windows 宿主机或其他局域网设备)访问 WSL 内部的服务,默认是受阻的。这是大多数问题的根源。
6.2 Docker Desktop on WSL 2 的网络模式
Docker Desktop 在 WSL 2 集成模式下,Docker 守护进程和容器都运行在 WSL 2 的 Linux 内核中。
- 容器网络:Docker 容器默认创建在
bridge网络(如172.17.0.0/16)上。 - 端口映射:当你使用
-p 8080:80运行容器时,Docker 会将容器的 80 端口映射到WSL 2 虚拟机的 8080 端口。 - 关键点:这个映射发生在 WSL 2 内部。要从 Windows 访问这个服务,你需要能够访问到 WSL 2 虚拟机的 IP 和端口。
6.3 当前网络拓扑
[你的电脑 Windows Host] (IP: 192.168.1.100) | | (Hyper-V 虚拟交换机) | [WSL 2 虚拟机] (IP: 172.xx.xx.xx) <-- Docker 守护进程在此运行 | | (Docker bridge) | [Docker 容器] (IP: 172.17.0.2) 运行着 Nginx (端口 80)当你执行docker run -p 8080:80 nginx后:
- 在 WSL 2 内部,访问
172.xx.xx.xx:8080或localhost:8080可以连通 Nginx。 - 在 Windows 上,访问
localhost:8080通常也能通,因为 Docker Desktop 和 Windows 做了特殊的localhost转发。 - 但是,如果你想从同一局域网下的另一台手机(IP: 192.168.1.101)访问你电脑上的这个 Nginx,你需要访问
192.168.1.100:8080。此时,流量需要经过 Windows 防火墙,并正确转发到 WSL 2,再转发到 Docker 容器。默认情况下,这一步会失败。
7. 防火墙配置:打通入站访问通道
Windows Defender 防火墙是保护系统的重要组件,我们不能简单关闭它。正确的做法是添加明确的入站规则,放行特定的开发端口。
7.1 确定需要放行的端口
首先,在 WSL 2 中查看 Docker 映射了哪些端口到 WSL 2 的 IP 上。
# 在 WSL 2 终端中执行 # 查看 WSL 2 的 IP 地址 ip addr show eth0 | grep inet # 输出类似:inet 172.27.112.186/20 brd 172.27.127.255 scope global eth0 # 记下这个 IP,例如 172.27.112.186 # 查看当前运行的容器及其端口映射 docker ps --format "table {{.Names}}\t{{.Ports}}" # 输出示例: # NAMES PORTS # my-nginx 0.0.0.0:8080->80/tcp这个例子中,容器的 80 端口被映射到了 WSL 2 的0.0.0.0:8080。这意味着 WSL 2 的 8080 端口正在监听。
7.2 在 Windows 防火墙中添加入站规则
我们需要允许外部流量访问 WSL 2 虚拟机的 IP 和端口。由于 WSL 2 的 IP 可能会变,最稳妥的方法是允许访问WSL 2 的虚拟网卡。
方法一:使用 PowerShell 命令(推荐,精准控制)以管理员身份打开 Windows PowerShell,执行以下命令:
# 1. 创建一个新的入站规则,允许 TCP 流量通过特定端口 # 将 `8080` 替换为你实际需要开放的端口号 New-NetFirewallRule -DisplayName "WSL2 Docker Port 8080" -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow # 2. 如果你需要开放一个端口范围(例如 8000-9000) New-NetFirewallRule -DisplayName "WSL2 Docker Ports 8000-9000" -Direction Inbound -LocalPort 8000-9000 -Protocol TCP -Action Allow # 3. 查看已创建的规则,确认是否生效 Get-NetFirewallRule -DisplayName "WSL2 Docker*" | Format-Table DisplayName, Enabled, Direction, Action方法二:通过高级安全 Windows Defender 防火墙(图形界面)
- 在 Windows 搜索栏输入“高级安全 Windows Defender 防火墙”,打开它。
- 点击左侧“入站规则”,然后右侧“新建规则...”。
- 选择“端口”,点击“下一步”。
- 选择“TCP”,并输入“特定本地端口”,如
8080或8000-9000,点击“下一步”。 - 选择“允许连接”,点击“下一步”。
- 何时应用规则:全选(域、专用、公用),点击“下一步”。
- 输入规则名称,例如 “WSL2 Docker Port 8080”,点击“完成”。
7.3 验证防火墙规则是否生效
在 Windows PowerShell 中,使用Test-NetConnection或telnet来测试端口是否可被访问。
# 首先,在 WSL 2 中启动一个测试服务(如果还没运行) # 在 WSL 2 终端里运行: # docker run -d -p 8080:80 --name test-nginx nginx # 然后在 Windows PowerShell 中测试 Test-NetConnection -ComputerName 127.0.0.1 -Port 8080 # 如果成功,会显示 `TcpTestSucceeded : True` # 也可以测试从 Windows 宿主机的 IP 访问(需要知道你的 Windows IP,例如 192.168.1.100) Test-NetConnection -ComputerName 192.168.1.100 -Port 8080如果从本机 IP 测试失败,但从127.0.0.1成功,说明防火墙规则可能未正确应用,或者规则作用域(公用/专用网络)不对。
7.4 处理 WSL 2 IP 变化问题
WSL 2 的 IP 在每次重启后可能会变。上述防火墙规则是基于端口,而不是基于 IP,所以通常不受影响。但如果你需要更稳定的方案(例如固定 WSL 2 的 IP),可以配置 WSL 2 使用静态 IP,但这涉及修改.wslconfig和 Windows 路由表,较为复杂。对于大多数开发场景,基于端口的防火墙规则已足够。
8. 功能测试与效果验证
现在,让我们通过一系列测试来验证环境是否完全畅通。
8.1 测试 1:基础容器访问(宿主机 -> 容器)
目的:验证从 Windows 宿主机能否访问 WSL 2 内 Docker 容器暴露的服务。
- 在 WSL 2 中启动测试容器:
docker run -d --rm -p 8080:80 --name web-test nginx:alpine - 在 WSL 2 内部验证:
curl http://localhost:8080 # 应返回 Nginx 欢迎页面的 HTML 代码。 - 在 Windows 中验证:
- 打开浏览器,访问
http://localhost:8080。 - 或在 PowerShell 中执行:
curl http://localhost:8080(如果已安装 curl)。 - 预期结果:成功看到 Nginx 欢迎页面。
- 打开浏览器,访问
8.2 测试 2:跨设备访问(手机/其他电脑 -> 你的电脑)
目的:验证局域网内其他设备能否访问你电脑上 Docker 容器运行的服务。
- 确保测试设备与你的电脑在同一局域网。
- 在测试设备上:
- 打开浏览器。
- 输入
http://<你的电脑Windows IP>:8080。例如http://192.168.1.100:8080。
- 预期结果:
- 成功:看到 Nginx 欢迎页面。说明防火墙规则生效,网络通路完整。
- 失败:页面无法打开或超时。需要按以下步骤排查。
8.3 测试 3:WSL 2 内部服务访问(容器 -> 容器,或 主机 -> WSL 2 非容器服务)
目的:验证 WSL 2 内部网络(非 Docker 网络)的互通性。
- 在 WSL 2 中启动一个简单的 Python HTTP 服务(不使用 Docker):
python3 -m http.server 8888 & - 从 Windows 访问此服务:
- 浏览器访问
http://localhost:8888。 - 注意:对于 WSL 2 内非 Docker 的服务,Docker Desktop 的
localhost转发可能不生效。此时你需要使用 WSL 2 的 IP 进行访问。 - 获取 WSL 2 IP:
hostname -I。 - 在 Windows 浏览器访问
http://<WSL2_IP>:8888。
- 浏览器访问
- 预期结果:能看到 Python 服务列出的文件目录。如果失败,同样需要检查防火墙是否放行了 8888 端口。
9. 常见问题与排查方法
即使按照步骤操作,也可能遇到问题。下表列出了常见现象及其解决方法。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
Windows 访问localhost:8080失败 | 1. Docker Desktop 服务未运行。 2. 容器未成功启动或端口映射错误。 3. Windows 与 WSL 2 的 localhost转发异常。 | 1. 检查 Docker Desktop 托盘图标是否正常。 2. 在 WSL 2 中运行 docker ps查看容器状态和端口映射。3. 在 WSL 2 中运行 curl localhost:8080测试。 | 1. 重启 Docker Desktop。 2. 检查 docker run -p参数是否正确。3. 尝试在 Windows 中访问 http://<WSL2_IP>:8080。 |
局域网设备访问Windows_IP:8080失败 | 1. Windows 防火墙阻止入站连接。 2. 路由器或网络策略阻止。 3. Windows 网络配置文件为“公用”。 | 1. 在 PowerShell 用Test-NetConnection -ComputerName 127.0.0.1 -Port 8080测试本地。2. 用 Test-NetConnection -ComputerName <Windows_IP> -Port 8080从本机测本机IP。3. 检查防火墙规则是否启用且作用域正确。 | 1. 按本文第 7.2 节添加入站规则。 2. 将网络配置文件从“公用”更改为“专用”(在 Windows 网络设置中)。 3. 暂时关闭防火墙测试(仅用于排查,完成后请重新打开并配置规则)。 |
| WSL 2 IP 无法 ping 通 | WSL 2 虚拟网络适配器状态异常。 | 在 Windows PowerShell 中运行ipconfig,查看是否有vEthernet (WSL)适配器及其 IP。 | 1. 在 PowerShell 中执行wsl --shutdown彻底关闭 WSL,然后重启。2. 重置网络: netsh winsock reset(管理员权限),重启电脑。 |
| Docker 容器无法访问外部网络 | WSL 2 内部的 DNS 或网络配置问题。 | 在容器内执行ping 8.8.8.8和ping baidu.com。 | 1. 检查 WSL 2 的/etc/resolv.conf,确保 DNS 服务器正确。2. 在 Docker Desktop 设置中,尝试重置 Kubernetes 或恢复出厂设置。 |
| 端口冲突,无法绑定 | 该端口已被其他进程占用。 | 在 WSL 2 中运行sudo netstat -tulpn | grep :8080查看占用进程。 | 1. 停止占用端口的进程。 2. 为 Docker 容器映射另一个端口,如 -p 8081:80。 |
| WSL 2 启动慢或卡住 | 虚拟化资源分配或系统休眠问题。 | 观察wsl -l -v输出状态。 | 1. 创建或修改C:\Users\<你的用户名>\.wslconfig文件,限制内存和CPU。2. 避免将 WSL 文件放在机械硬盘或网络驱动器。 |
10. 最佳实践与使用建议
完成所有配置后,遵循以下建议可以让你的 Docker on WSL 2 环境更稳定、高效。
- 端口规划:为不同的开发项目规划不同的端口范围,并在防火墙中成组放行。例如,Web 前端用
3000-3999,后端 API 用8000-8999,数据库用3306, 5432, 6379等。 - 使用 Docker Compose:对于多容器应用,始终使用
docker-compose.yml来定义服务、网络和卷。这便于版本控制和一键启停。 - 项目目录放在 WSL 2 文件系统内:虽然可以从
/mnt/c/访问 Windows 文件,但将项目代码放在 WSL 2 的原生文件系统(如~/projects/)内,性能会好得多,也能避免文件权限问题。 - 定期更新:定期运行
sudo apt update && sudo apt upgrade以及更新 Docker Desktop 和 WSL 2 内核,以获得安全补丁和性能改进。 - 备份
.wslconfig:如果你创建了自定义的.wslconfig文件来分配内存或处理器,请备份它。重装系统或 WSL 后可以快速恢复。 - 善用
docker system prune:定期清理无用的 Docker 镜像、容器和卷,释放磁盘空间。可以添加-a和--volumes标志进行深度清理(谨慎使用)。 - 网络问题优先排查防火墙:当遇到任何“能本地访问,不能远程访问”的问题时,首先怀疑 Windows 防火墙,并按照本文第 7 节的方法进行验证和规则添加。
通过以上步骤,你不仅解决了 WSL 2 和 Docker 的基础使用问题,更构建了一个网络透明、工具齐全、易于维护的本地开发环境。这套环境能让你像在 Linux 服务器上一样自如地使用 Docker,同时享受 Windows 宿主机的便利。下次当你需要部署一个复杂的微服务栈进行本地调试时,这些关于网络和防火墙的知识将至关重要。