WSL2+PhpstormでPHP開発(docker なし、複数PHP)
この投稿の通りに WSL2 上に Docker を利用してコンテナーで Apache を動かした時、xdebug を使用するとものすごく遅くなってしまって、仕事に使い物にならなかったです。
xdebug はできる限りに使いたかったため工夫してみたところ、Apache は WSL2 上で直接動かして、そのほかは Docker コンテナー上で動かしてみようと思いました。しかし、一つの環境の中で複数の PHP バージョンを動かす必要があり、いろいろ調べた結果、Apache の vhost ごとに PHP バージョンを指定できる方法を見つけました。
本投稿は、WSL2 上で 複数の PHP バージョンを Apache の vhost ごとに動作する設定をメモしたものです。ほぼ以下の英語の記事の手順を従っています。
WSL2 に Apache をインストールする
$ sudo apt update
$ # Apacheと必要なモジュールをインストール
$ sudo apt install -y apache2 libapache2-mod-fcgid
$ apache2 -v # Apache バージョンの確認
WSL2 に php-fpm をインストールする
$ # レポジトリを管理するUbuntuのパッケージPPA
$ sudo apt install -y software-properties-common
$ sudo add-apt-repository ppa:ondrej/php # PHP PPA Repositoryを追加
$ sudo apt-get update
$ sudo apt install -y php5.6-fpm # PHP 5.6をインストール
$ sudo apt install -y php7.2-fpm # PHP 7.2をインストール
$ sudo apt install -y php8.0-fpm # PHP 8.0をインストール
複数の PHP バージョンのコマンドを実行するために設定する
update-alternatives コマンドをつかって、PHP バージョンを切り替えることができます。
$ update-alternatives --list php # 利用できる PHP バージョンの確認
/usr/bin/php5.6
/usr/bin/php7.2
/usr/bin/php8.0
$ sudo update-alternatives --config php # PHP バージョンの切り替え
There are 3 choices for the alternative php (providing /usr/bin/php).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/bin/php8.0 80 auto mode
1 /usr/bin/php5.6 56 manual mode
2 /usr/bin/php7.2 72 manual mode
3 /usr/bin/php8.0 80 manual mode
Press <enter> to keep the current choice[*], or type selection number:
複数の PHP バージョンで Apache を構成する
必要な Apache モジュールを有効にする
FPMおよびFastCGIをApacheサーバーと統合するために実行する必要があるようです。
$ sudo a2enmod actions fcgid alias proxy_fcgi # Apache モジュールを有効化
Apache の vhost の設定を行う
PHP 5.6 用サンプル
$ sudo mkdir /var/www/php56 # サンプルページのドキュメントルートを作成
$ echo "<?php phpinfo(); ?>" | sudo tee /var/www/php56/index.php # サンプルページを作成
$ sudo vi /etc/apache2/sites-available/php56.example.com.conf # vhostの設定
<VirtualHost *:80>
ServerName php56.example.com
DocumentRoot /var/www/php56
ErrorLog ${APACHE_LOG_DIR}/php56-error.log
CustomLog ${APACHE_LOG_DIR}/php56-access.log combined
<FilesMatch \.php$>
# Apache 2.4.10+ can proxy to unix socket
SetHandler "proxy:unix:/var/run/php/php5.6-fpm.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
$ sudo a2ensite php56.example.com # サンプルを有効にする。
PHP 7.2 用サンプル
$ sudo mkdir /var/www/php72
$ echo "<?php phpinfo(); ?>" | sudo tee /var/www/php72/index.php
$ sudo vi /etc/apache2/sites-available/php72.example.com.conf
<VirtualHost *:80>
ServerName php72.example.com
DocumentRoot /var/www/php72
ErrorLog ${APACHE_LOG_DIR}/php72-error.log
CustomLog ${APACHE_LOG_DIR}/php72-access.log combined
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
$ sudo a2ensite php72.example.com
PHP 8.0 用サンプル
$ sudo mkdir /var/www/php80
$ echo "<?php phpinfo(); ?>" | sudo tee /var/www/php80/index.php
$ sudo vi /etc/apache2/sites-available/php80.example.com.conf
<VirtualHost *:80>
ServerName php80.example.com
DocumentRoot /var/www/php80
ErrorLog ${APACHE_LOG_DIR}/php80-error.log
CustomLog ${APACHE_LOG_DIR}/php80-access.log combined
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.0-fpm.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
$ sudo a2ensite php80.example.com
Apache と php-fpm を起動する
$ sudo service apache2 start
$ sudo service php5.6-fpm start
$ sudo service php7.2-fpm start
$ sudo service php8.0-fpm start
WSL2に接続できるように Windows の hosts を設定する
C:\Windows\System32\drivers\etc\hosts
ファイルをメモ帳などで開いて以下の設定を追記します。
127.0.0.1 php56.example.com
::1 php56.example.com
127.0.0.1 php72.example.com
::1 php72.example.com
127.0.0.1 php80.example.com
::1 php80.example.com
Xdebug をインストールする
各々の PHP バージョンンに対して xdebug をインストールします。
$ sudo apt install -y php-pear
$ pecl install xdebug
$ sudo apt install php5.6-xdebug
$ sudo apt install php7.2-xdebug
$ sudo apt install php8.0-xdebug
とりあえず php8.0-fpmに対して xdebug の設定を行います。
$ sudo vi /etc/php/8.0/fpm/php.ini
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_port = 9003
xdebug.idekey = PHPSTORM
xdebug.log = /tmp/php8.0-fpm-xdebug.log
xdebug.client_host = 《WSL2のホストIPアドレス》 も設定する必要がありますが、動的に変わる値(?)のため、WSL2 を起動する時に自動的に設定するようにします。
PHP をコマンドで実行する時のためには、cli 用 php.ini に xdebug の設定を行う必要があります。
$ sudo vi /etc/php/8.0/cli/php.ini
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_port = 9003
xdebug.idekey = PHPSTORM
xdebug.log = /tmp/php8.0-cli-xdebug.log
ただし、WSL2では /etc/rc.local
などを起動時に実行することはできないようです。しかし、起動時に /sbin/mount -a
コマンドが呼び出されるため、これをフックする方法を利用して実現できます。以下はそのための設定です。
fstab
はマウントするファイルシステムの情報を記述するファイルであり、再起動もしくは mount -a
を実行する際に設定が反映されるようです。
$ echo 'none none rc defaults 0 0' | sudo tee -a /etc/fstab
$ sudo chmod +x /sbin/mount.rc
$ sudo vi /sbin/mount.rc
#!/bin/bash
sed -i -e '/xdebug.client_host/d' /etc/php/8.0/fpm/php.ini
echo -n 'xdebug.client_host = ' >> /etc/php/8.0/fpm/php.ini
echo `awk '/nameserver/ {print $2}' /etc/resolv.conf` >> /etc/php/8.0/fpm/php.ini
sed -i -e '/xdebug.client_host/d' /etc/php/8.0/cli/php.ini
echo -n 'xdebug.client_host = ' >> /etc/php/8.0/cli/php.ini
echo `awk '/nameserver/ {print $2}' /etc/resolv.conf` >> /etc/php/8.0/cli/php.ini
service apache2 start
service php5.6-fpm start
service php7.2-fpm start
service php8.0-fpm start
下の4行は、WSL2 を起動する際に自動的に Apache2 と php-fpm が起動されるように追加します。
ブラウザーで確認する
PhpStorm の Xdebug 設定を行う
※Laravel を動かす時の注意点
Windows の hosts を設定する時
Windows の hosts を設定する時、127.0.0.1の代わりにlocalhostと設定しないと接続しない。Apache の Listen のポートに対して、IPv4 と IPv6 の関連でブラウザーや Postman からうまく接続できないです。そのため、Apache の設定を変える必要があります。以下は、Laravel に接続するための例です。(WSL2 上の Apache の ports.conf、vhost、Winsows のhosts 順番)
Listen 127.0.0.1:80
Listen [::1]:80
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
<VirtualHost *:80>
ServerName laravel.sample.com
ServerAlias laravel.sample.com
DocumentRoot /home/user/project_path/public
ErrorLog ${APACHE_LOG_DIR}/laravel-error.log
CustomLog ${APACHE_LOG_DIR}/laravel-access.log combined
Options Indexes FollowSymLinks
<Directory "/home/user/project_path/public/">
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.0-fpm.sock|fcgi://localhost/"
</FilesMatch>
</VirtualHost>
127.0.0.1 laravel.sample.com
::1 laravel.sample.com
Laradoc などコマンド実行時は Docker を利用している場合
php artisan optimize
を実行する際にルートパスを設定しているため、プロヘクト配置場所に対して Docker 内のパスと WSL2 内のパスが一致する必要があります。WSL2 でシンボリックリンクなどを利用して解決できます。
例えば、docker-compose で /home/user/project_path/:/var/www/src
のようにマウントしているのであれば、以下のようにシンボリックリンクを作成します。
$ ln -s /home/user/project_path /var/www/src
WSL2 上でファイルのアクセスを確認
Apache が Laravel のソースコードを実行できるように所有権とアクセス権限を以下のように変更します。
$ chown -R user:www-data /home/user/project_path/*
$ chmod -R g+w /home/user/project_path/*
Laravel で必須の Apache モジュールを有効にする
mod_rewriteが利用可能ではなければ、Laravel は動きません。
$ cat /etc/apache2/mods-available/rewrite.load # モジュールがあるか確認する
$ sudo a2enmod rewrite # モジュールを起動
$ sudo service apache2 restart # Apache の再起動
結果的に構築された構成をまとめた図
ログ書き込みでパーミッションエラーになる時
WSL2 で利用しているユーザーを Apache グループに追加して、Apache でログを書いても、コマンド実行する時ログを書いても問題ないようにします。
$ groups 《ユーザー名》 # ユーザーが属しているグループを確認する。
《ユーザー名》 : 《ユーザー名》
$ sudo usermod -g www-data 《ユーザー名》 # ユーザーを www-dataグループに追加する。
$ groups 《ユーザー名》
《ユーザー名》 : www-data
※参考
- GitHub「How to Install Multiple PHP Version with Apache on Ubuntu 18.04 & 16.04」、(https://gist.github.com/evgv/cf3bd8bea2031ec8155f5f1cd4f81e32 閲覧日:2022年10月8日)
- Debian「sid の libapache2-mod-fcgid パッケージに関する詳細」、(https://packages.debian.org/ja/sid/libapache2-mod-fcgid 閲覧日:2022年10月8日)
- Apache HTTP Server Version 2.5「mod_fcgid」、(https://httpd.apache.org/mod_fcgid/en/mod/mod_fcgid.html 閲覧日:2022年10月8日)
- Ubuntu「bionic-updates の software-properties-common パッケージに関する詳細」、(https://packages.ubuntu.com/ja/bionic-updates/software-properties-common 閲覧日:2022年10月8日)
- Tutorial Crawler「Ubuntu 20.04に複数のPHPバージョンをインストールする方法」、(https://tutorialcrawler.com/ubuntu-debian/ubuntu-20-04に複数のphpバージョンをインストールする方法/ 閲覧日:2022年10月8日)
- softelメモ「Ubuntu18.04のLAMP環境で複数phpバージョン対応」、(https://www.softel.co.jp/blogs/tech/archives/6477 閲覧日:2022年10月8日)
- いろいろ備忘録日記「WSL で デフォルトユーザ を変更する方法」、(https://devlights.hatenablog.com/entry/2021/05/29/070000 閲覧日:2022年10月8日)
- Qiita「WSL2でスタートアップスクリプトを実行するHack」、(https://qiita.com/amenoyoya/items/41a2334cbc1facb87864 閲覧日:2022年10月8日)
- Qiita「fstabについて」、(https://qiita.com/kihoair/items/03635447591358210772 閲覧日:2022年10月8日)
- Qiita「6つの演習でだいたい分かるDockerネットワーク」、(https://qiita.com/amenoyoya/items/8992fc1659e07b4bb7d6a 閲覧日:2022年10月12日)
- @IT「Linuxがほぼそのまま動くようになった「WSL2」のネットワーク機能:Windows 10 The Latest」、(https://atmarkit.itmedia.co.jp/ait/articles/1909/09/news020.html 閲覧日:2022年10月12日)
- ラボラジアン「Ubuntu で 複数のバージョンの PHP を使う手順」、(https://laboradian.com/use-php72-with-ubuntu1604/ 閲覧日:2022年10月13日)
- Qiita「Ubuntu 20.04にPHPを複数インストールして切り替える方法(PPA・apt)」、(https://qiita.com/murakami77/items/a9945f2a8e51ca3791de 閲覧日:2022年10月13日)