微软前些日子公布了 Windows Subsystem Linux(下简称WSL),当时还只有 Insider Preview 支持安装,作为普通用户的我就没有尝试。这两天不知道伴随哪次更新,标准的专业版也可以安装了,就试着配了一下,发现效果还比较理想,基本可以替代之前的 IIS 或者 VirtualBox 方案。这里简单记录一下。
(2016-12-02 更新)随着最近一次 1607 更新,家庭版也可以安装了,效果基本一样。
(2018-01-21 更新)已知 Yarn 在非 ~/
开头的目录里 install 会出问题
安装 WSL
开始 > 设置 > 系统 > 应用和功能 > 拖到最下面“程序和功能”。然后点击“启用或关闭 Windows 功能”,找到“适用于 Linux 的 Windows 子系统(beta)”,启动之。

之后系统会要求重启,听它的。
然后打开命令行(或者 PowerShell,下同),输入 bash,提示需要切换到开发者模式。按照提示切过去,然后再次运行 bash,系统会安装需要的组件。这个过程会比较久,大概源都在国外吧。安装完成后又要重启,之后 WSL 就算安装成功。
再次打开命令行,输入 bash,就可以进入 Linux 子系统了。
WSL 其实就是 Ubuntu 14.04.5,所以安装包直接用 apt-get 就可以。嫌慢的话可以换上国内的源,不赶时间就让它慢慢更新。
sudo apt-get update
sudo apt-get upgrade
配置Apache
【2020-04-06 更新】现在已经没这个问题了,建议直接删掉 apache。
这次我本来打算用 Nginx,装上之后启动不了,Google 之,似乎是 WSL 对 IP v6 的支持有问题,遂卸掉继续用 Apache。反正本地开发嘛,性能并发不是什么问题。
Ubuntu 自带 Apache 2.4.7,直接 sudo service apache2 start 启动就好。不过这里遭遇到 vhost 的问题,我配置的虚机怎么都不生效,最后在 stack overflow 上找到解决方案,说是 000-default 和自定义的主机冲突,禁用掉默认配置就好了。
sudo a2enmod vhost_alias
sudo a2dissite 000-default
sudo a2ensite 001-mysite
然后还需要调整一下模块,比如要进行 WordPress 开发,就要保证重定向生效。
sudo a2enmod php7.1
sudo a2enmod rewrite
另外,Apache 2.4 要求配置目录的“访问条件”,不然不能访问(会返回 “403 Forbidden”,改目录权限也没有用),所以要增加一行:
<Directory "/path/to/my/site">
...
Require all granted # 允许所有来源
AllowOverride All # 允许重定向,WordPress 必备
...
</Directory>
全部配置好之后,重启 apache,访问配置的域名,就可以了。
安装 Nginx
不知道什么时候 Nginx 可以用了,反正我某天试着配了一下,突然就可以用了。
sudo apt install nginx
安装完配置一下即可,不过需要注意,apache 默认启动并占据 80 端口,所以使用 nginx 前必须卸载或者关掉 Apache,避免出现端口冲突。
安装 PHP
添加 PHP 源。
sudo add-apt-repository ppa:ondrej/php
需要注意,以前那个 ppa:ondrej/php5-5.6 的源已经被移除了,5.5 到 7.1 都用 ondrej/php 这个新源。如果非要用 5.4 的话,还有个 php5-oldstable 的源。
这里顺便把几个可能用到的组件也装上。
sudo apt-get install php
sudo apt-get install php-mysql
sudo apt-get install php-xdebug
sudo apt-get install php-apcu
sudo apt-get install php-xml
sudo apt-get install php-mcrypt
配置 Xdebug
配置好 PHP 之后,开启 Xdebug 并不复杂。以我安装的 PHP7.1为例,安装之后,配置文件都在 /etc/php/7.1/apache2/conf.d/
这个文件夹里,找到 20-xdebug.ini 并添加以下几行,然后重启 apache,即可。
xdebug.remote_enable=on
xdebug.remote_autostart=on
xdebug.idekey=PHPSTORM
使用 cmder 替换 PowerShell
PowerShell 也好,自带的命令行也好,都不好用。要么字体难看得要死,要么中文输入有问题,而且不支持多窗口。这里推荐 cmder,很好用,体验提升明显。
cmder 支持打开窗口并执行启动脚本,可以一键进入 Linux 控制台,只要按下图进行配置即可。

然后再修改启动时默认的 tab。

启用 Ruby
这个版本的 Ubuntu 集成了 rvm,通过 rvm list
可以看到已经安装了 Ruby 2.3.0。但是直接运行 ruby 却提示没有安装,运行 rvm use 2.3.0 提示
RVM is not a function, selecting rubies with ‘rvm use …’ will not work.
You need to change your terminal settings to allow shell login.
Please visit https://rvm.io/workflow/screen/ for example.
这个很奇怪,以前没有遇见过。通过 Google 得知,这是因为默认的登录方式没有读取 ~/.bash_login
里的配置信息,没有加载到 rvm 需要的方法,所以需要在启动 WSL 的时候增加参数 --login
,所以回到上一步,修改启动脚本,问题解决。
%windir%\system32\bash.exe ~ -cur_console:p --login
(这里我还去掉了zsh,因为这台电脑似乎没有安装这个包,我不知道是不是默认不安装的问题。)
安装 MySQL
【2017-03-25 更新】下面提到的坑跟我用“旧”配置——0.6.0 有关。这个配置参考自 digital ocean 的文章,实际上 Oracle 已经推出了新版本的配置文件,使用新版配置文件安装 MySQL 就不会遇到这个问题。新版配置文件的链接在此。其它步骤相同。
原以为安装 MySQL 最简单,没想到也有坑……主要是 5.7 的坑。
我比较喜欢新版本,所以自然就准备上 5.7。Ubuntu 自带的源是 5.5 或者 5.6,所以要先更新一下:
wget http://dev.mysql.com/get/mysql-apt-config_0.6.0-1_all.deb
sudo dpkg -i mysql-apt-config_0.6.0-1_all.deb
sudo apt-get update
好了,接下来直接安装就好:
sudo apt-get install mysql-server
根据提示信息安装 MySQL Server 5.7,设置 root 密码。这个阶段多半不会出问题。安装完成之后,运行 mysql -uroot -p,输入刚才设置的密码,不出意外的话就可以进入 MySQL 控制台了。

接下来我们通常要设置开发用户,此时问题也就来了。(这个问题在我的几台机器上,包括 VPS 表现不一,时有时无,所以我不太确定到底什么情况下会发生。)
CREATE USER 'someone'@'localhost' IDENTIFIED BY 'password';
执行这句 SQL 将创建一个用户,看起来完全不会有问题,结果却报错了:ERROR 1054 (42S22): Unknown column 'plugin' in 'mysql.user'
(报错的列可能不同,但原因是一样的)。Google 之,原来随着 MySQL 版本升级,系统内建表的结构也发生着变化,5.7 需要的字段比起 5.5 甚至 5.4 多了不少。虽然我们直接安装的 5.7,也不耽误它按照老的结构创建表……
这个时候有两个选择,一是手工把差的列加上,另一个则是运行官方提供的升级脚本 mysql_upgrade
。为表达对官方的信任,我选择了后者。退出 MySQL,回到 SSH,执行脚本:
mysql_upgrade --upgrade-system-tables -u root -p
升级完成之后,再 mysql -uroot -p,输入密码,登录不进去了!WTF!怎么回事?!
又是一通 Google,原来 5.7 之后,开发团队移除了 mysql.user
表里的 password
字段,用 authentication_string
取而代之,然而这个字段并没有复制之前 password
的值,所以原来的密码就失效了!这是什么鬼……
这里我们又有两个选择,一是想办法修改 root 密码,二是卸了重装……因为我当时没找到真正的原因(就是上面这个),所以选择了后者。现在我推荐一个解决方案:
- 安装后,进入 MySQL 控制台,输入 DESC mysql.user;
- 如果返回 45 rows(行),则不需要升级系统内建表,改干嘛干嘛;如果少于这个数,就要执行
mysql_upgrade
- 刚才的窗口不要动,新开一个窗口,执行 mysql_upgrade --upgrade-system-tables -u root -p
- 执行完毕回到刚才的窗口,在 MySQL 环境下执行
UPDATE `mysql`.`user`
SET `authentication_string`=PASSWORD('password')
WHERE `user`='root';
文件互访
在 WSL 里访问系统中的文件比较容易,使用 /mnt/盘符/路径
即可。
如果要在 Windows 里访问 WSL 里的文件,它们位于 C:\Users\你的用户名\AppData\Local\lxss\
有待解决的问题
有了 WSL,各种依赖 Linux 环境的东西都可以随便跑了,利用 apt-get
安装更新也都很方便。侦听端口要完全没有问题。但其实两个环境是隔绝的,Windows 里不能执行 Ubuntu 的东西,反之亦然。这样一来,诸如 Phpstorm 的 File Watcher 包括测试都无法正常发挥作用。解决方案有待进一步发掘。
临时解决方案就是通过命令行启动各种 watch,比如
sass watch
Yarn
在非 ~/
开始的目录里执行 yarn install
有一定机率会产生错误,具体原因不明,暂时无法稳定重现,反复重试之后倒是也能装成功。这个是 WSL 的锅,只能等待 Windows 更新。
总结
时代在发展,科技在进步。按照 GitHub 刚刚发布的报告,微软已经是开源贡献第一大公司,Windows 拥抱 Linux 之后我们也可以在 Windows 下进行PHP开发了。世界真美好啊!
顺便Ubuntu新版本也比老版本容易配置了,当然,也可能是我之前不会。
参考:
欢迎吐槽,共同进步