使用 Windows Linux Subsystem 配置开发环境

最新版的 Windows 10 提供了”Windows Subsystem Linux“功能,可以在 Windows 下跑 Linux,大大提升开发效率。本文将介绍如何在 WSL 下搭建 PHP 开发环境。

微软前些日子公布了 Windows Subsystem Linux(下简称WSL),当时还只有 Insider Preview 支持安装,作为普通用户的我就没有尝试。这两天不知道伴随哪次更新,标准的专业版也可以安装了,就试着配了一下,发现效果还比较理想,基本可以替代之前的 IIS 或者 VirtualBox 方案。这里简单记录一下。

(2016-12-02 更新)随着最近一次 1607 更新,家庭版也可以安装了,效果基本一样。
(2018-01-21 更新)已知 Yarn 在非 ~/ 开头的目录里 install 会出问题

安装 WSL

开始 > 设置 > 系统 > 应用和功能 > 拖到最下面“程序和功能”。然后点击“启用或关闭 Windows 功能”,找到“适用于 Linux 的 Windows 子系统(beta)”,启动之。

启用 Windows Subsystem Linux

之后系统会要求重启,听它的。

然后打开命令行(或者 PowerShell,下同),输入 bash,提示需要切换到开发者模式。按照提示切过去,然后再次运行 bash,系统会安装需要的组件。这个过程会比较久,大概源都在国外吧。安装完成后又要重启,之后 WSL 就算安装成功。

再次打开命令行,输入 bash,就可以进入 Linux 子系统了。

WSL 其实就是 Ubuntu 14.04.5,所以安装包直接用 apt-get 就可以。嫌慢的话可以换上国内的源,不赶时间就让它慢慢更新。

sudo apt-get update
sudo apt-get upgrade

配置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,避免出现端口冲突。

安装 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 控制台,只要按下图进行配置即可。

配置 cmder 支持 WSL

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

修改 cmder 启动时默认打开的 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 控制台了。

进入 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 密码,二是卸了重装……因为我当时没找到真正的原因(就是上面这个),所以选择了后者。现在我推荐一个解决方案:

  1. 安装后,进入 MySQL 控制台,输入 DESC mysql.user;
  2. 如果返回 45 rows(行),则不需要升级系统内建表,改干嘛干嘛;如果少于这个数,就要执行 mysql_upgrade
  3. 刚才的窗口不要动,新开一个窗口,执行 mysql_upgrade --upgrade-system-tables -u root -p
  4. 执行完毕回到刚才的窗口,在 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新版本也比老版本容易配置了,当然,也可能是我之前不会。


参考:

The main PPA for PHP (5.5, 5.6, 7.0) with many PECL
Support for the new Windows 10 bash shell
手把手安装 RVM 以及为什么 RVM is not a function
How To Install MySQL on Ubuntu 14.04

Mac OS上各种开发环境的配置(未完成)

Mac OS下各环境的配置。

很多开发人员喜欢 Mac OS,因为它基于FreeBSD,有原生的命令行工具,配置各种开发环境都很方便。我个人偏爱Windows,我觉得各种可视化用起来更爽。

这篇文章介绍如何在Mac OS 10.10 Yosemite上配置各种开发环境,范围以前端所需为主。

Xcode

无论你是否准备开发iOS或者Mac OS上的应用,Xcode最新版都是必须的。因为里面包含了系统必须的命令行工具和编译工具,没有它们支持,我们就无法安装后面那些东西。

好在Xcode是免费的,虽然体积巨大(而且早年不支持断点续传,我第一遍Xcode装了半个月),但只要你有恒心有毅力,智商正常,就都能装上。

方法:

  1. 打开App Store
  2. 搜索Xcode
  3. 安装
  4. 安装完成后,在命令行里运行xcode-select -p,如果显示/Applications/Xcode.app/Contents/Developer则表明Xcode 命令行工具已经安装成功,否则的话,执行xcode-select --install安装

homebrew

工欲善其事,必先利其器。在*nix环境下装东西,一个好的包管理工具是必须的。我使用的是Homebrew,它的安装非常简单:

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

因为Mac OS默认包含并启动了Ruby环境,所以此时系统就开始执行homebrew的安装。关于brew的用法,可以看它的官网,或者运行brew help阅读帮助。

nodejs

有了homebrew,一切都好办了。

brew install nodejs
node -v

不过我更喜欢标准版,在nodejs的官网下载dmg安装包,直接安装即可。

ruby

Mac OS默认包含ruby,不过我喜欢最新版,所以还是拜托给homebrew好了。

brew install ruby

homebrew会把包安装在/usr/local/Cellar目录下,然后通过软链接链接到/usr/local。有些系统默认包含的组件已经注册在/usr/local或者/usr/bin,创建链接可能会失败。不用担心,homebrew提供了详细的帮助信息,仔细阅读,按照提示一步一步做,就OK了。

Python & httpie

python我用的很少,耳闻3和2差别巨大,也就不敢追新。所以我用系统自带的Python,只是安装了 httpie 这个工具来调试远程数据。安装一样是通过homebrew:

brew install httpie
http httpie.org

apache httpd

Apache httpd是Mac OS的默认组件,直接运行sudo apachectl start即可开启apache服务器,然后访问 http://localhost/ 就能看到默认页面了。

系统默认的文档地址为 /Library/WebServer/Documents,把静态的页面放进去,就能正常浏览,用来测试还是蛮方便的。不过我觉得不算太实用。因为一来埋得很深,通过Finder无法直接到达;二来作为公司配的开发机,一般来说我不建议在公共目录里做东西。

不过配置起来也不复杂。打开 /etc/apache2/extra/httpd-vhost.conf,里面应该有两个没有真正起作用的范例配置。基本上按照那里即可。

先放出去,回头再补充好了……