资讯动态

WSL2 + Webman + Swoole 开发环境搭建实录(下):跑通、访问与长期稳定运行

发布时间:2026/9/23 11:25:02 来源:尧图企业网站定制
WSL2 Webman Swoole 开发环境搭建实录下跑通、访问与长期稳定运行上篇把 WSL 里的 PHP/Swoole/Webman 项目跑到composer install通过中篇打通了 Windows MySQL/Redis 远程访问、Git/Gitee 工作流、Webman 配置改造为getenv().env。下篇本篇让配置生效、启动 Webman、浏览器访问踩坑、走完安装向导以及那些跑起来之后才会想到的长期稳定运行细节——IP 会变、时区、日志、资源限制。一、让配置生效重启 Webman中篇改了config/database.php、config/redis.php等文件也创建了.env但 Webman 进程还在用旧配置。必须重启。在 WSL 终端cd~/imSeverBase# 如果之前已经启动过先停掉php start.php stop# 重新启动前台方便看日志php start.php start前台启动能看到实时日志适合调试。如果想让它在后台跑php start.php start-d注意-d是守护进程模式日志会写到runtime/logs/不再打印到终端。开发阶段建议先前台跑看有没有报错稳定了再-d。补充坑如果php start.php stop报 “no process found”说明之前没启动或者已经停了直接start即可。如果start报 “Address already in use”说明有残留进程占着 8181# 查占用 8181 的进程ss-tlnp|grep8181# 或者lsof-i:8181# 杀掉kill-9PID或者php start.php restart补充坑Webman 有个reload命令用于平滑重启代码改动后不中断服务php start.php reload但改配置文件config/*.php需要restart不是reload。二、启动访问踩坑2.1 现象能启动浏览器打不开php start.php start启动成功显示监听0.0.0.0:8181但浏览器访问打不开。2.2 排查过程先确认服务本身有响应curlhttp://127.0.0.1:8181如果 curl 有输出哪怕是一个 302 跳转说明服务在跑问题在浏览器侧。我当时 curl 返回HTTP/1.1 302 Found Location: /install根因我在浏览器里用了https://localhost:8181访问。Webman 默认没配 SSL浏览器遇到 https 打不开会直接拦截或白屏不做自动降级。2.3 解决改用 http浏览器地址栏改http://localhost:8181正常打开跳转到/install安装向导。补充坑如果浏览器自动把http://跳成https://Chrome 的 HSTS 或“始终使用安全连接”设置手动在地址栏输入http://localhost:8181后回车或者清理该域名的 HSTS 记录chrome://net-internals/#hsts。补充坑如果curl http://127.0.0.1:8181完全无输出说明服务没起来检查 Webman 日志tail-fruntime/logs/webman.log2.4 302 跳 /install 是正常的Webman 某些发行版带安装向导的首次启动会跳转到/install。这是正常的走完安装向导就会进主界面。安装向导一般会让你填数据库连接信息DB_HOST、DB_PORT、DB_DATABASE、DB_USERNAME、DB_PASSWORDRedis 连接信息管理员账号注意如果你已经在.env里配好了数据库安装向导里填的可能会覆盖.env也可能读取.env作为默认值——取决于你的 Webman 发行版。走完向导后再检查一遍.env是否被改。三、验证 MySQL / Redis 连通走完安装向导后在 Webman 里触发一次数据库查询和一次 Redis 操作确认真的连上了 Windows 侧的服务。最直接的方式cd~/imSeverBase# 用一个临时脚本测试php-r require vendor/autoload.php; (Dotenv\Dotenv::createUnsafeImmutable(.))-load(); // 测试 MySQL try { \$pdo new PDO(mysql:host . getenv(DB_HOST) . ;port . getenv(DB_PORT) . ;dbname . getenv(DB_DATABASE), getenv(DB_USERNAME), getenv(DB_PASSWORD)); echo\MySQL OK:\. \$pdo-query(SELECT VERSION())-fetchColumn() . PHP_EOL; } catch (Exception \$e) { echo\MySQL FAIL:\. \$e-getMessage() . PHP_EOL; } // 测试 Redis try { \$redis new Redis(); \$redis-connect(getenv(REDIS_HOST), getenv(REDIS_PORT) ?: 6379); echo\Redis OK:\. \$redis-ping() . PHP_EOL; } catch (Exception \$e) { echo\Redis FAIL:\. \$e-getMessage() . PHP_EOL; } 补充坑如果 Redis 报了密码错误检查REDIS_PASSWORD是否为空。空字符串在new Redis()里可能需要显式auth()或不调用auth()取决于你的 php-redis 版本。空密码时直接connect即可不要传空密码。补充坑如果 MySQL 报SQLSTATE[HY000] [2002] Connection refused回去检查Windows MySQL 的bind-address 0.0.0.0是否生效防火墙 3306 是否放行.env里的DB_HOST是不是当前正确的宿主机 IP补充坑如果 MySQL 报SQLSTATE[HY000] [1045] Access denied说明授权没生效回去确认SELECTuser,hostFROMmysql.userWHEREuserroot;-- 应该有 root% 这一行四、WSL2 IP 会变的问题4.1 问题本质WSL2 是 NAT 模式宿主机的网关 IP 存在/etc/resolv.conf的nameserver行。但每次 WSL 重启这个 IP 可能变。你今天.env里写的172.31.176.1明天可能就是172.28.x.x。表现昨天还好好的 Webman今天启动后连不上 MySQL/Redis。4.2 为什么不用镜像网络模式WSL2 有个networkingModemirrored镜像网络模式可以让 WSL 里的127.0.0.1直接等于 Windows 宿主机一劳永逸。但这是 Windows 11 22H2 的独占功能。我的机器是 Windows 10强行设置会报 “not supported” 错误WSL 启动失败。所以 Windows 10 只能走自动更新脚本方案。4.3 方案自动更新 .env 脚本原理从/etc/resolv.conf读nameserver作为宿主机 IP写入.env。创建~/update-host-ip.shcat~/update-host-ip.shEOF #!/bin/bash HOST_IP$(grep nameserver /etc/resolv.conf | awk {print $2}) if [ -z $HOST_IP ]; then echo 无法获取宿主机 IP exit 1 fi ENV_FILE$HOME/imSeverBase/.env if [ ! -f $ENV_FILE ]; then echo .env 不存在: $ENV_FILE exit 1 fi sed -i s/^DB_HOST.*/DB_HOST$HOST_IP/ $ENV_FILE sed -i s/^REDIS_HOST.*/REDIS_HOST$HOST_IP/ $ENV_FILE echo 已更新 .env: DB_HOST$HOST_IP, REDIS_HOST$HOST_IP EOFchmodx ~/update-host-ip.sh注意如果你在 cmd 里粘贴多行会被自动换行拆开用nano ~/update-host-ip.sh手动创建或者用单行printf版本。4.4 使用方法每天启动 WSL 后在启动 Webman 之前~/update-host-ip.shcd~/imSeverBase php start.php start先更新 IP再启动 Webman。4.5 可选自动检查如果嫌每次手动跑麻烦可以在~/.bashrc末尾加一段开终端时自动检查 IP 是否变化变了才更新# 追加到 ~/.bashrcCURRENT_HOST_IP$(grepnameserver /etc/resolv.conf|awk{print $2})if[-n$CURRENT_HOST_IP][-f$HOME/imSeverBase/.env];thenENV_IP$(grep^DB_HOST$HOME/imSeverBase/.env|cut-d-f2)if[$ENV_IP!$CURRENT_HOST_IP];then~/update-host-ip.shfifi只有 IP 真的变了才触发更新每开一个终端只多一次判断开销极小。4.6 备选/etc/hosts 别名另一个思路把宿主机 IP 映射到一个固定别名winhost。# 追加到 ~/.bashrcexportwinhost$(grepnameserver /etc/resolv.conf|awk{print $2})if[!-n$(grep-P[[:space:]]winhost/etc/hosts)];thenprintf%s\t%s\n$winhostwinhost|sudotee-a/etc/hostsfi然后.env里写DB_HOSTwinhost REDIS_HOSTwinhost这样每次开终端自动更新/etc/hosts。缺点需要 sudo 权限第一次会提示输密码/etc/hosts在 WSL 重启后可能被重置所以逻辑放在.bashrc里每次检查。我选的是脚本方案简单直接不依赖 sudo。五、长期稳定运行的其他细节5.1 WSL 资源限制WSL2 默认吃 Windows 一半内存。我 64GB 机器默认给 WSL 32GB跑 Webman 用不上。在C:\Users\你的用户名\.wslconfig里[wsl2] memory8GB processors4 swap4GB我给了 4 核 8G跑 Webman Swoole 足够40 个进程空跑也没事。你机器配置高可以按需调。注意文件名是.wslconfig不是.wslconfig.txt[wsl2]段头只写一次改完wsl --shutdown重启才生效验证free -h看 Totalnproc看核数补充坑.wslconfig写错会导致 WSL 起不来。报 “The specified configuration is not valid” 时先wsl --shutdown把配置改回默认或删掉再重启。5.2 Composer 国内镜像如果composer install慢换阿里云镜像composerconfig-grepo.packagistcomposerhttps://mirrors.aliyun.com/composer/取消composerconfig-g--unsetrepos.packagist阿里云 Composer 镜像与 Packagist 官方实时同步国内速度明显提升。5.3 PHP 时区WSL 里 PHP 默认可能是 UTC和 Windows MySQL 的时间对不上。sudosed-is/^;date.timezone .*/date.timezone Asia\/Shanghai//etc/php/8.3/cli/php.ini如果sed没匹配到行首格式不同手动编辑sudonano/etc/php/8.3/cli/php.ini找到date.timezone改成date.timezone Asia/Shanghai验证php-recho date(Y-m-d H:i:s);注意PHP CLI 的php.ini改动只影响新的 CLI 进程已经跑着的 Webman 需要php start.php restart才生效。5.4 日志排查入口出问题先看日志Webman 日志~/imSeverBase/runtime/logs/webman.logtail-f~/imSeverBase/runtime/logs/webman.logWSL systemd 日志如果用了 systemd 管理服务journalctl-u服务名Swoole 相关错误一般在 Webman 日志里也会打印到启动终端补充坑runtime/logs/日志会一直增长长期跑要定期清理或配 logrotate。开发环境可以手动清rm-rf~/imSeverBase/runtime/logs/*注意不要删runtime/目录本身Webman 可能依赖目录结构。5.5 每天启动流程我每天的固定流程打开 WSL 终端 ↓ ~/update-host-ip.sh ↓ cd ~/imSeverBase ↓ php start.php start ↓ 浏览器 http://localhost:8181先更新 IP再启动 Webman最后访问。多一条命令但永远不用管 IP 变不变。5.6 关于稳定性之前 Windows 下单进程协程跑久了会卡死需要定期重启。搬到 WSL Swoole 后目前跑下来稳定很多。但这是开发环境不是线上环境。我没有配 systemd 自启、没有做进程守护Windows 也不休眠每天手动启动。这些在生产环境都是必须的但开发环境没必要过度工程。六、安全提醒本地开发可以生产必须改这部分在博客里一定要标注清楚避免读者照搬到生产环境。6.1 MySQLroot%我用了root% 简单密码图省事。生产环境必须-- 建专用用户限定来源 IP 段CREATEUSERwebman172.31.%IDENTIFIEDBY强密码;GRANTALLONyourdb.*TOwebman172.31.%;FLUSHPRIVILEGES;6.2 Redis 空密码 protected-mode no同理生产必须设requirepass并只监听内网地址。6.3.env泄露.env必须进.gitignore提交仓库用.env.example。如果不小心提交了gitrm--cached.envgitcommit-mremove .env密码已经暴露的话改密码别只删文件。6.4 防火墙开发环境放行 3306/6379 是为了 WSL 连。如果电脑经常接入公共网络建议用完后关掉防火墙规则或者 MySQL/Redis 只绑定 WSL 虚拟网卡地址不绑0.0.0.0七、整个系列总结三篇写完完整流程回顾上篇WSL2 基础 → PHP 8.3 → Swoole 6.2.2 编译 → 项目迁移 → composer install中篇Windows MySQL/Redis 远程开放 → WSL 客户端测试 → Git/Gitee/VS Code → Webman 配置改getenv().env下篇重启生效 → 启动访问踩坑https、302 /install→ 连通验证 → IP 会变处理 → 长期稳定运行细节最终状态项目状态WSL2 Ubuntu 24.04.1 LTS✅ systemd 开启PHP 8.3.6✅ 扩展齐全Swoole 6.2.2✅ 协程/curl/openssl/sockets 全开Webman 项目~/imSeverBase✅ 代码就位composer install通过VS Code Remote-WSL✅ 可正常编辑Git / Gitee✅ 已 initremote 配置好Webman 启动✅ 监听0.0.0.0:8181浏览器访问✅http://localhost:8181正常MySQL / Redis 连接✅ WSL 通过宿主机 IP 连通配置改造✅getenv().envIP 变化处理✅ 自动更新脚本最大的几个坑apt 锁冲突unattended-upgrades占锁手动解除ext-redis 版本冲突apt 源版本太低pecl 装 6.3.0https 打不开Webman 没配 SSL必须用 httpgetenv() ?: 默认值不加括号PHP 运算符优先级坑WSL2 IP 会变Windows 10 不能用镜像模式走脚本方案Dotenv 加载bootstrap.php里用createUnsafeImmutable否则getenv()读不到后续可能更新的方向如果以后升级到 Windows 11可以试镜像网络模式省掉 IP 脚本如果 WSL 里要跑更多服务.wslconfig资源再调如果要做生产部署systemd / supervisor / Docker 都可以再写一篇Xdebug PhpStorm 远程调试也是个大话题这是 2026-09 的版本后面还会继续踩坑有更新会补进来。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价