查看: 135|回复: 1

WSL2 Ubuntu 开发环境配置实战与踩坑记录

[复制链接]
发表于 3 小时前 | 显示全部楼层 |阅读模式
本文基于 Windows 11 Pro 系统,结合 WSL2 和 Ubuntu 24.04,记录从零配置一套完整的全栈开发环境的每一步。内容涵盖 WSL2 全局配置、系统初始化、Zsh 与 Oh My Zsh 的安装与调优、Git 与 SSH 多 Key 管理、Node.js / nvm 以及 Python / uv 的安装配置,并整理了大量实践中遇到的典型错误及其解决方案。以下所有操作均来自实际测试,版本号与步骤均可复现。

一、环境前置

操作系统:Windows 11 Pro 26200,WSL 版本 2.7.3.0(内核 6.6.114.1-1),WSL 发行版为 Ubuntu 24.04。默认 Shell 计划更改为 Zsh + Oh My Zsh,代理方案使用 Mihomo Party(Clash 系列)的 TUN 模式,网络模式为 NAT。

二、.wslconfig 全局配置

WSL 2 的全局配置文件位于 Windows 端的 C:\Users\<用户名>\.wslconfig。建议配置如下:
  1. [wsl2]
  2. networkingMode=NAT
  3. memory=4GB
  4. processors=4
  5. swap=2GB
  6. localhostForwarding=true
复制代码

关键说明:
networkingMode=NAT 是默认且最稳定的模式,WSL 在 Hyper-V 内部 NAT 子网中运行,通过 Windows 主机 NAT 出网。如果不限制内存和 CPU,WSL 默认会吃掉一半物理内存,运行大型构建(如 webpack、TypeScript)时容易让 Windows 卡死,因此必须显式设置 memory 和 processors 上限。localhostForwarding=true 允许 Windows 主机通过 localhost:port 直接访问 WSL 内的服务,但不会暴露给局域网其他机器。

注意不要使用 networkingMode=mirrored,虽然理论上能共用 Windows 网络栈,但与 VMware、Hyper-V、Docker Desktop 等多虚拟化环境严重冲突,会报错 0x8007054f。

配置生效命令:
  1. wsl --shutdown
  2. # 等待约 8 秒确保完全关闭
  3. wsl
复制代码

验证资源限制是否生效:使用 free -h 查看内存和 swap,使用 nproc 查看处理器数量。

三、Ubuntu 系统初始化

3.1 换国内源
Ubuntu 24.04 使用新的 deb822 格式,源文件位于 /etc/apt/sources.list.d/ubuntu.sources。使用以下命令替换为清华源:
  1. sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g; s@//security.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list.d/ubuntu.sources
复制代码

更新软件包列表并升级:
  1. sudo apt update && sudo apt upgrade -y
复制代码

3.2 安装基础工具链
  1. sudo apt install -y build-essential git curl wget vim zsh unzip ca-certificates gnupg lsb-release net-tools dnsutils
复制代码

gcc/g++/make 等编译工具(build-essential)是编译很多原生模块(如 node-gyp)的必备条件;net-tools 和 dnsutils 提供 ifconfig、nslookup、dig 等网络诊断命令。

四、Zsh + Oh My Zsh + 插件 + 主题

4.1 安装 Oh My Zsh
推荐使用 Gitee 镜像加速国内用户:
  1. sh -c "$(curl -fsSL https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh)"
复制代码

如果 TUN 代理稳定,也可以直接用 GitHub 官方脚本。

4.2 设置 Zsh 为默认 Shell
  1. chsh -s $(which zsh)
复制代码

注意:chsh 修改的是登录 shell,需要退出 WSL 重新进入(关闭 WSL 终端再打开)才能生效。

4.3 安装两个实用插件
  1. git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
  2. git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
复制代码

踩坑提示:不要使用不存在的 Gitee 镜像链接(如 gitee.com/playjokes/...),会导致 404。如果无法访问 GitHub,请在 Gitee 搜索真实可用的镜像。

4.4 启用插件与随机主题
编辑 ~/.zshrc,修改以下内容:
  1. ZSH_THEME="random"
  2. ZSH_THEME_RANDOM_CANDIDATES=(
  3. "robbyrussell" "ys" "bureau" "candy" "clean" "fishy"
  4. "gnzh" "jonathan" "kolo" "mh" "muse" "sorin" "fox" "kphoen"
  5. )
  6. plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
复制代码

然后执行 exec zsh 应用。每次打开新终端会随机切换主题,可以使用 echo $RANDOM_THEME 查看当前使用的主题。

4.5 关于酷炫主题(可选)
如果需要 agnoster、powerlevel10k 等带图标和 Git 状态的主题,需要在 Windows Terminal 中设置 Nerd Font 字体(如 MesloLGS NF),下载地址:www.nerdfonts.com/font-downloads。然后在 Windows Terminal 设置 → Ubuntu profile → 外观 → 字体中选择该字体。不急的话纯 ASCII 主题也足够。

4.6 常见踩坑:compinit 报错

如果曾经安装后又卸载了 Docker Desktop,或者 Docker Desktop 的 WSL Integration 残留,开终端时可能出现:

compinit:527: no such file or directory: /usr/share/zsh/vendor-completions/_docker

这是死链残留。修复方法:
  1. ls -la /usr/share/zsh/vendor-completions/_docker
  2. sudo rm -f /usr/share/zsh/vendor-completions/_docker
  3. rm -f ~/.zcompdump*
  4. exec zsh
复制代码

五、Git 配置

5.1 全局基础配置
  1. git config --global user.name "你的名字"
  2. git config --global user.email "你的邮箱"
  3. git config --global init.defaultBranch main
  4. git config --global core.autocrlf input
  5. git config --global pull.rebase false
复制代码

core.autocrlf input 的意义:WSL 是 Linux 环境,提交时使用 LF;该模式在提交时自动将 CRLF 转为 LF,签出时不转换,最适合跨平台团队。

5.2 SSH Key 配置

方案 A(推荐,最干净):在 WSL 内独立生成 Key
  1. ssh-keygen -t ed25519 -C "your-email@example.com"
复制代码

将公钥添加到 GitHub:cat ~/.ssh/id_ed25519.pub 复制内容后登录 GitHub 添加。

方案 B:复用 Windows 已有的 SSH Key
  1. mkdir -p ~/.ssh
  2. cp /mnt/c/Users/<你的用户名>/.ssh/id_ed25519 ~/.ssh/
  3. cp /mnt/c/Users/<你的用户名>/.ssh/id_ed25519.pub ~/.ssh/
  4. cp /mnt/c/Users/<你的用户名>/.ssh/known_hosts ~/.ssh/ 2>/dev/null
  5. chmod 700 ~/.ssh
  6. chmod 600 ~/.ssh/id_ed25519
  7. chmod 644 ~/.ssh/id_ed25519.pub
复制代码

注意:不要使用软链接(ln -s /mnt/c/...),因为 /mnt/c 是 9P 文件系统挂载,不支持 Linux 权限模型,SSH 看到 .ssh 目录权限为 777 时会拒绝使用私钥。

方案 C(兼容旧仓库):生成 RSA 4096 位密钥
  1. ssh-keygen -t rsa -b 4096 -C "your-email"
复制代码

5.3 解决 GitHub SSH 22 端口被干扰的问题

国内 ISP 偶尔会干扰 GitHub 的 22 端口,表现为 ssh -T git@github.com 无响应或连接失败。解决方案:使用 GitHub 提供的 443 端口入口(ssh.github.com)。在 ~/.ssh/config 中添加:
  1. Host github.com
  2. Hostname ssh.github.com
  3. Port 443
  4. User git
  5. IdentityFile ~/.ssh/id_ed25519
  6. IdentitiesOnly yes
复制代码

设置文件权限:chmod 600 ~/.ssh/config

测试连接:ssh -T git@github.com

5.4 多 Key 场景:内部仓库 RSA + GitHub Ed25519

典型配置示例:
  1. # GitHub 走 443 + Ed25519
  2. Host github.com
  3. Hostname ssh.github.com
  4. Port 443
  5. User git
  6. IdentityFile ~/.ssh/id_ed25519
  7. IdentitiesOnly yes
  8. # 公司内部仓库走 22 + RSA
  9. Host company
  10. Hostname 192.168.1.201
  11. Port 8022
  12. User git
  13. IdentityFile ~/.ssh/id_rsa
  14. IdentitiesOnly yes
  15. # Gitee
  16. Host gitee.com
  17. Hostname gitee.com
  18. Port 22
  19. User git
  20. IdentityFile ~/.ssh/id_ed25519
  21. IdentitiesOnly yes
复制代码

IdentitiesOnly yes 必须添加,否则 SSH 会尝试 agent 中的所有 key,导致 GitHub 返回 "Too many authentication failures" 错误。

之后可以这样 clone:git clone company:group/repo.git

5.5 首次连接的 "authenticity" 提示

SSH 的 TOFU(Trust On First Use)机制会在第一次连接新主机时询问是否信任其 host key。回答 yes 即可,主机指纹会保存到 ~/.ssh/known_hosts。只有看到 "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!" 这样的感叹号警告才需要警惕。

六、Node.js / nvm 配置

6.1 安装 nvm
  1. curl -o- https://gitee.com/mirrors/nvm/raw/master/install.sh | bash
复制代码

安装脚本会自动将环境变量写入 ~/.zshrc(如果当前使用 zsh)。检查是否成功:打开 ~/.zshrc 末尾应包含以下内容:
  1. export NVM_DIR="$HOME/.nvm"
  2. [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
  3. [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
复制代码

6.2 配置 nvm 下载源(解决下载 Node 慢的问题)

nvm 从 nodejs.org 下载二进制文件,国内访问极不稳定,即使开了代理也经常超时。因此需要在 ~/.zshrc 中添加:
  1. export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node
复制代码

然后重新加载配置文件:source ~/.zshrc

安装 Node.js:
  1. nvm install 18.20.8
  2. nvm install --lts
  3. nvm alias default lts/*
  4. nvm use default
复制代码

6.3 npm 镜像的思考

关键区别:nvm 下载源(node 二进制)与 npm registry(包下载)是两回事。如果 TUN 代理稳定,npm 直连 npmjs.org 速度完全 OK,不必改 registry。改用淘宝镜像反而可能带来延迟叠加、私有包丢失、代理关闭后变慢等问题。如果确实要改:
  1. npm config set registry https://registry.npmmirror.com
  2. # 删除:
  3. npm config delete registry
复制代码

6.4 .npmrc 最佳实践

用户级 ~/.npmrc(一次配置,全局生效):
  1. npm config set audit false
  2. npm config set fund false
复制代码

audit=false 不仅关闭广告,还能修复 npm 8 + 私服环境下常见的 EPIPE 错误(见下文)。

项目级 .npmrc(提交到 Git,团队共享)示例:
  1. registry=http://192.168.1.100:8081/repository/npm-group/
  2. strict-ssl=false
  3. fund=false
  4. audit=false
复制代码

npm 配置优先级(从高到低):命令行参数 > 项目根 .npmrc > 父目录 .npmrc > 用户级 ~/.npmrc > 全局配置 > npm 内置默认值。

6.5 解决 npm EPIPE 报错

实际场景:在大型 Vue2 + webpack4 项目中使用 npm i,所有 HTTP 请求都返回 200,但在 reify(解压写入 node_modules)阶段报:

npm ERR! code EPIPE
npm ERR! syscall write
npm ERR! errno -32
npm ERR! write EPIPE

根本原因:npm install 完成后会自动发起 npm audit,npm 8 + 私服(Nexus/Verdaccio)+ 大项目的组合下,audit 的并发 stream 处理有 bug,触发 EPIPE。在 .npmrc 中添加 audit=false 即可解决。

附加修复:提高文件描述符限制:
  1. ulimit -n 65536
  2. echo 'ulimit -n 65536' >> ~/.zshrc
  3. sudo tee -a /etc/security/limits.conf <<'EOF'
  4. * soft nofile 65536
  5. * hard nofile 65536
  6. EOF
复制代码

6.6 如果 npm 依然不稳定,直接换 pnpm

pnpm 使用硬链接 + 内容寻址存储,并发控制更稳健,在 WSL 2 上实测比 npm 稳定得多。

安装方式:
  1. npm install -g pnpm
  2. # 或者:
  3. curl -fsSL https://get.pnpm.io/install.sh | sh -
  4. source ~/.zshrc
复制代码

用法与 npm 基本一致:pnpm install、pnpm add react、pnpm run dev。原先的 .npmrc 配置 pnpm 也会读取。

6.7 ENOTEMPTY 错误

npm ERR! code ENOTEMPTY 通常是因为上次 npm i 半成功留下的脏状态。彻底清理:
  1. rm -rf node_modules
  2. rm -f package-lock.json yarn.lock pnpm-lock.yaml
  3. npm cache clean --force
  4. ulimit -n 65536
  5. npm i
复制代码

七、Python / uv 配置

uv 是 Astral 公司推出的 Python 包管理器,用 Rust 编写,一站式替代 pyenv + pip + pipx + poetry + virtualenv,速度比 pip 快 10-100 倍,2024-2025 年已成为 Python 生态的事实标准。

安装:
  1. curl -LsSf https://astral.sh/uv/install.sh | sh
  2. source ~/.zshrc
  3. uv --version
复制代码

常用命令速查:

安装指定版本 Python 解释器:uv python install 3.12
列出已安装版本:uv python list
创建项目:uv init myproject && cd myproject
添加依赖:uv add requests
删除依赖:uv remove requests
运行脚本:uv run python xxx.py
同步依赖:uv sync
单文件脚本依赖:uv run --with requests script.py
临时运行工具:uvx ruff check .(类似 npx)
安装独立 CLI 工具:uv tool install ruff

基础工作流示例:
  1. uv python install 3.12
  2. uv init test-proj && cd test-proj
  3. uv add requests
  4. uv run python -c "import requests; print(requests.__version__)"
复制代码

uv 自动管理虚拟环境,无需手动创建和激活。

八、跨系统协作

8.1 Git 凭据复用 Windows(HTTPS 场景)

如果需要使用 HTTPS 方式 clone 仓库,可以复用 Windows 的 Git Credential Manager:
  1. git config --global credential.helper manager
  2. # 或者指定绝对路径:
  3. git config --global credential.helper '"/mnt/c/Program Files/Git/mingw64/bin/git-credential-manager.exe"'
复制代码

不过推荐优先使用 SSH key,更纯粹稳定。

8.2 VS Code 集成

在 Windows 上安装好 VS Code 后,在 WSL 中进入项目目录直接运行 code .,会自动安装 Remote-WSL server 端,编辑器在 Windows 窗口运行,而终端、调试、文件系统都运行在 WSL 中。

8.3 文件位置铁律

项目代码务必存放在 WSL 原生路径下(如 ~/projects/),绝不要放在 /mnt/c/ 或 /mnt/f/ 等 Windows 挂载盘上。原因:

9P 协议挂载的 Windows 磁盘性能极慢,IO 比原生路径慢 10 倍以上;
git status、npm install 等操作会卡顿到怀疑人生;
文件监听(HMR)也可能出问题。

如果项目原本在 Windows 盘,建议直接在 WSL 中重新 clone 一份到 ~/projects/。

九、常见踩坑速查

下表整理了实际使用中最常遇到的问题与解决方案:
  1. 现象                                 原因                                      修复
  2. WSL 内 ping IP 通但域名解析失败       Clash TUN 拦截了 DNS / 镜像模式问题       调整 Clash 代理排除 WSL 网段
  3. Destination Host Unreachable          ARP 失败(火绒“对外 ARP 攻击拦截”误伤)  关闭火绒“对外 ARP 攻击拦截”
  4. ssh: Connection closed by ... port 22 ISP 干扰 GitHub 22 端口                  使用 ssh.github.com:443
  5. npm ERR! EPIPE                        npm 8 + 私服 audit 流崩溃                 .npmrc 加 audit=false
  6. ENOTEMPTY: directory not empty        上次 npm i 半成功                         删 node_modules + lock 文件 + npm cache clean --force
  7. nvm install 卡住                       nodejs.org 下载超时                      export NVM_NODEJS_ORG_MIRROR
  8. No acceptable C compiler found         未装 build-essential                      sudo apt install build-essential
  9. compinit:527: no such file ...         Docker Desktop 死链残留                  删死链 + rm ~/.zcompdump* + exec zsh
  10. rm: cannot remove ...: Is a directory  用 rm 删目录                             使用 rmdir(空)或 rm -r(非空)
  11. PowerShell 脚本中文注释报错           UTF-8 无 BOM 被按 GBK 解码               用记事本另存为 UTF-8 with BOM 或改用 PowerShell 7
  12. rm -rf 误删                           没有回收站,永久消失                       安装 trash-cli,用 trash 替代
复制代码

十、完整 ~/.zshrc 参考(含代理函数)
  1. export ZSH="$HOME/.oh-my-zsh"
  2. ZSH_THEME="random"
  3. ZSH_THEME_RANDOM_CANDIDATES=(
  4. "robbyrussell" "ys" "bureau" "candy" "clean" "fishy"
  5. "gnzh" "jonathan" "kolo" "mh" "muse" "sorin" "fox" "kphoen"
  6. )
  7. plugins=(git zsh-autosuggestions zsh-syntax-highlighting)
  8. source $ZSH/oh-my-zsh.sh
  9. ulimit -n 65536
  10. export NVM_DIR="$HOME/.nvm"
  11. [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
  12. [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
  13. export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node
  14. proxy_on() {
  15. export hostip=$(ip route show | grep -i default | awk '{print $3}')
  16. export http_proxy="http://$hostip:7890"
  17. export https_proxy="http://$hostip:7890"
  18. export all_proxy="socks5://$hostip:7890"
  19. echo "Proxy on: $http_proxy"
  20. }
  21. proxy_off() {
  22. unset http_proxy https_proxy all_proxy
  23. echo "Proxy off"
  24. }
  25. alias ll='ls -lah'
  26. alias ..='cd ..'
  27. alias ...='cd ../..'
复制代码

十一、初始化清单(按顺序执行)

提供一份可复制的命令序列,方便在全新 WSL 环境中快速配置:
  1. sudo sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g; s@//security.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list.d/ubuntu.sources
  2. sudo apt update && sudo apt upgrade -y
  3. sudo apt install -y build-essential git curl wget vim zsh unzip ca-certificates gnupg net-tools dnsutils
  4. sh -c "$(curl -fsSL https://gitee.com/mirrors/oh-my-zsh/raw/master/tools/install.sh)"
  5. chsh -s $(which zsh)
  6. # 退出 WSL 重新进入后继续执行以下命令
  7. git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
  8. git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
  9. # 编辑 ~/.zshrc 添加配置(参见上文),然后执行 exec zsh
  10. curl -o- https://gitee.com/mirrors/nvm/raw/master/install.sh | bash
  11. source ~/.zshrc
  12. nvm install --lts
  13. nvm alias default lts/*
  14. nvm use default
  15. curl -LsSf https://astral.sh/uv/install.sh | sh
  16. source ~/.zshrc
  17. uv python install 3.12
  18. # 完成
复制代码

通过以上步骤,可以在较短时间内获得一套稳定、高效的 WSL2 Ubuntu 开发环境。所有配置均经过实际测试,对于避免常见陷阱和提升开发效率有直接帮助。
回复

使用道具 举报

发表于 3 小时前 | 显示全部楼层

Re: WSL2 Ubuntu 开发环境配置实战与踩坑记录

非常感谢分享这么详尽的实战记录!尤其 .wslconfig 里内存和CPU限制的提醒太关键了,我之前没设上限,开个 Webpack 编译直接卡死,加完 4GB 限制后 Windows 这边流畅多了。 想请教一个细节:您提到 mirrored 模式与 VMware 冲突报错 0x8007054f,我恰好也装了 VMware Workstation,目前用的是默认 NAT 模式没遇到问题。如果未来尝试 mirrored 模式,除了关掉 VMware 服务外,有没有办法让两者共存?或者您建议直接放弃 mirrored 模式、坚持用 NAT?另外,文中的 sed 换源命令对 Ubuntu 24.04 的新 deb822 格式确实管用,之前我手动改 sources 老踩坑,一键替换省事很多,赞一个。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-6-5 15:32 , Processed in 0.029492 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部