微软前些日子公布了 Windows Subsystem Linux(下简称WSL),当时还只有 Insider Preview 支持安装,作为普通用户的我就没有尝试。这两天不知道伴随哪次更新,标准的专业版也可以安装了,就试着配了一下,发现效果还比较理想,基本可以替代之前的 IIS 或者 VirtualBox 方案。这里简单记录一下。
(2016-12-02 更新)随着最近一次 1607 更新,家庭版也可以安装了,效果基本一样。
安装 WSL
开始 > 设置 > 系统 > 应用和功能 > 拖到最下面“程序和功能”。然后点击“启用或关闭 Windows 功能”,找到“适用于 Linux 的 Windows 子系统(beta)”,启动之。
之后系统会要求重启,听它的。
然后打开命令行(或者 PowerShell,下同),输入 bash,提示需要切换到开发者模式。按照提示切过去,然后再次运行 bash,系统会安装需要的组件。这个过程会比较久,大概源都在国外吧。安装完成后又要重启,之后 WSL 就算安装成功。
再次打开命令行,输入 bash,就可以进入 Linux 子系统了。
安装 PHP,配置Apache
WSL 其实就是 Ubuntu 14.04.5,所以安装包直接用 apt-get 就可以。嫌慢的话可以换上国内的源,不赶时间就让它慢慢更新。
sudo apt-get update
sudo apt-get upgrade
然后添加 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
这次我本来打算用 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,访问配置的域名,就可以了。
使用 cmder 替换 PowerShell
PowerShell 也好,自带的命令行也好,都不好用。要么字体难看得要死,要么中文输入有问题,而且不支持多窗口。这里推荐cmder,很好用,体验提升明显。
cmder 支持打开窗口并执行启动脚本,可以一键进入 Linux 控制台,只要按下图进行配置即可。
然后再修改启动时默认的 tab。
启用 Ruby
这个版本的 Ubuntu 集成了 rvm,通过 rvm list
可以看到已经安装了 Ruby 2.3.0。但是直接运行 ruby 却提示没有安装,运行rvm use 2.3.0 提示
这个很奇怪,以前没有遇见过。通过 Google 得知,这是因为默认的登录方式没有读取 ~/.bash_login
里的配置信息,没有加载到 rvm 需要的方法,所以需要在启动 WSL 的时候增加参数 --login
,所以回到上一步,修改启动脚本,问题解决。
%windir%\system32\bash.exe ~ -cur_console:p --login
(这里我还去掉了zsh,因为这台电脑似乎没有安装这个包,我不知道是不是默认不安装的问题。)
安装 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你的用户名AppDataLocallxss`
有待解决的问题
有了 WSL,各种依赖 Linux 环境的东西都可以随便跑了,利用 apt-get
安装更新也都很方便。侦听端口要完全没有问题。但其实两个环境是隔绝的,Windows 里不能执行 Ubuntu 的东西,反之亦然。这样一来,诸如 Phpstorm 的 File Watcher 包括测试都无法正常发挥作用。解决方案有待进一步发掘。
临时解决方案就是通过命令行启动各种 watch,比如
sass watch
总结
时代在发展,科技在进步。按照 GitHub 刚刚发布的报告,微软已经是开源贡献第一大公司,Windows 拥抱 Linux 之后我们也可以在 Windows 下进行 PHP 开发了。世界真美好啊!
顺便Ubuntu新版本也比老版本容易配置了,当然,也可能是我之前不会。