開発環境見直し for WORDPRESS on WSL

2017/11/09 追記:
LAN内の他のPCからアクセスするには、コントロールパネル ≫ Windows Defender ファイヤーウォール の新規受信規則で、ポート80番を開けないといけません。


ちょっと前に今の仕事の開発環境を新しくしたのですが、Windows 10 Fall Creators Update(以下、FCU)で、Windows Subsystem for Linux(WSL)がベータ版から正式版に変わったんで、また見直し。見直しというか、Wordpress用。

HyperVを使った前のやつは、こっち、でCIFSマウントしているディレクトリへのアクセスがたまにエラー?で読み取れなくなるぐらいで、特に不自由もなかったんですが、WSLの記事をググると、思いの他進化しているので、WORDPRESSでのお手軽サイト構築用の環境として整備することにした。

Windows10 FCU からは、限定的ですが、ネットワークフォルダをマウントすることができて、WSLはかなり実用的な開発ツールセットになってきています。しぶしぶMac使っている人(そんな奴いるのか?)は、やっと大好きな(笑) 使い慣れたWindowsでウェブ系のお仕事ができます!( ̄▽ ̄)

BoWそのものは、マイクロソフトストアからインストールできるので、もう説明要らないでしょう。Windows10 FCUから開発者モードにする必要もなくなったし。

手順を記録しとこう、という備忘録です。特にこれといって新しいことが書かれているわけではなく、グーグル先生に聞いた内容を自分用にまとめたものなので、あまり参考にはなりません。あしからず。

>>以下の手順を全自動で行うシェルスクリプト

■ パッケージのインストール
apt コマンドで、必要なパッケージをインストールしていきます。sudo するのがかったるいので、全部 root で作業します。
の、前に・・・、まず、/etc/apt/source.list の中のリポジトリを日本のものに差し替えるのが定石だそうですので、変更してからにします。
また、mysql-serverをインストールする最中に、root パスワードを入力するように促されるので適当に。

sudo su -

sed -i.orig -e 's%http://archive.ubuntu.com/ubuntu/%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g' /etc/apt/sources.list
apt update
apt -y upgrade

apt -y install apache2 apache2-doc mysql-server mysql-client
apt -y install php php-mbstring php-mysql php-sqlite3 php-gd php-mcrypt libapache2-mod-php 

php の方は、必要なモジュールを別途 apt でインストールする必要があります。・・・その辺はまぁ適当に。

■ Apache2 設定
まず、そのまま “service apache2 start” とかやると、ワーニングがでます。まぁ、無視すりゃいいんですが、気になるので・・・。
/etc/apache2/apache2.conf を開いて下記2行を追記します。

AcceptFilter http none
AcceptFilter https none

あと、開発するファイル等が入った、ドライブなり、フォルダなりを apacheから見えるようにしないといけません。
windows.confは、僕の環境では、下記のような感じ

#
# /etc/apache2/sites-available/windows.conf
#
<Directory "/mnt/d/devel">
AllowOverride All
Options All
Require all granted
</Directory>
Alias /devel /mnt/d/devel

で、有効化します。

a2ensite windows

php.iniの修正も若干必要ですかね。デフォルトで2MBしかアップロードできませんし、開発環境なんで、memory_limitは無制限にしたい。
ってなわけで、/etc/php/7.0/apache2/php.ini で、以下の項目を修正

  • date.timezone
  • memory_limit
  • post_max_size
  • upload_max_filesize

それと、まぁ、ほとんど使わないと思いますが・・・DocumentRootが /var/www/html で設定されているのですが、これのオーナーとグループを自分のユーザーにしときましょう。いちいち sudo してコピーするのメンドクサイでしょう。ついでにホームディレクトリにリンクを作っときましょう。

#一度 root を exit して・・・
exit
#myuserは自分のアカウントで置き換える
sudo chown -R myuser:myuser /var/www/html
ln -s /var/www/html ~/wwwroot
# root に戻る
sudo su -

■ MySQL 設定
次、mysql。apacheと同じく、”service mysql start” とかやると、僕の環境ではワーニングが出ます。これも無視すればいいんでしょうけど・・・。
mysqlユーザーのホームディレクトリを作ってやります。すでにあればやる必要なし。

mkdir /home/mysql
chown mysql:mysql /home/mysql
usermod -d /home/mysql mysql

mysql の 文字コードを UTF8にしときます。
/etc/mysql/my.cnf を開いて、下記を追記

[client]
default-character-set = utf8

[mysql]
default-character-set = utf8

[mysqld]
character-set-server = utf8

ここで、一旦 mysql を起動して、mysqlクライアントからユーザー、データベースを作っちゃいましょう。

service mysql start
mysql -u root -p

ここから mysql シェル

まずユーザー(wpuser)を作成。パスワードは適当に 0000 とか。
> CREATE USER wpuser IDENTIFIED BY '0000';

WORDPRESS用のデータベースを作っときます。
> CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8;

作ったユーザーに、データベースの権限を全許可します。
> GRANT all privileges ON wordpress.* TO wpuser

> quit

あと、phpMyAdmin は必須っすね。aptコマンドでインストールしてもいいんですが、最新のものをマニュアルで入れときます。

#一旦rootを抜けて、一気に片付けましょう。
exit
cd /var/www/html
wget -O - https://files.phpmyadmin.net/phpMyAdmin/4.7.5/phpMyAdmin-4.7.5-all-languages.tar.gz | tar xvzf -
mv phpMyAdmin-4.7.5-all-languages phpMyAdmin
cd phpMyAdmin
cat config.inc.sample.php | sed -r 's/^(\$cfg\['\''blowfish_secret'\''\]) *= *'\''.*'\''/\1 = '\''32_moji_no_randamu_na_ei_suuji_x'\''/g' > config.inc.php

WSLではサービスとして動かすことができないので、bash を終わらせるとapache,mysqlのデーモンが全部落ちます。まぁバックグラウンドで走らせてしまうと、Windows Serverの顔が立たない(^^;ので致し方ありません。
bashを立ち上げるたびに、

sudo sh -c 'service mysql start; service apache2 start' 

とかやる必要があります。まぁこれは、alias 一個作っとけばいいだけなんすけどね。

WORDPRESSでのサイト構築ではもう十分な感じ。でも WSLのubuntuで docker が動いたらこんなメンドクサイことしないで済むのになぁ・・・。いずれ対応してくれることを祈る。

実際にはシェルスクリプトにすることで、インストールしてコマンド一発で、LAMP環境をセットアップできるようしています。
そのスクリプトは、こっち。

開発環境の見直し。

「Byte range lock とは何ぞや???」

結論から言うと、その方面に詳しくないので全然わからない。検索結果を拾い読みしていくと、ファイル全体をロックするのではなく、バイト単位で範囲を指定してロックする、というものらしい。

事の始まりは、開発環境を一新したことがきっかけだった。

長年 Windowsユーザーである私は、Win32版のApache/MySQL/Perl,PHP(俗にいうWAMP環境)をセットアップして使ってきた。しかし、これらサーバー類のWindows版とLinuxなどのUNIX互換OS上のそれらとの挙動の違いなどが最近非常に気になり出しはじめ、その違いを吸収するようなコードをアプリケーションに組み込む量が多くなってきた。本来なら必要のないコード。

で、ApacheやMySQLなどのWindows版を使うのをやめ、Hyper-Vの仮想マシン(内部仮想スイッチ+WinNATで外に出るよう構築)にサーバー類を移すことにした。幸いここ数年 CentOSをいじるようになってきたのでLinuxサーバーの構築は慣れているので開発環境の移行は結構すんなりできた。

仮想化ソフトは色々あるんですが・・・まぁある程度のスペックのPCとWindows8.1以降なら迷わずWindowsに標準でついてくるHyper-V がベストだと思います。

仮想マシンを立ち上げるには、 Powershell(要権限昇格) を使うとスマート。GUIなHyperVマネージャは仮想マシン作るときだけでいいかなと。

仮想マシンの列挙
>> Get-VM

起動とシャットダウンは・・・
>> Start-VM -Name CentOS7
>> Stop-VM -Name CentOS7

コンソールにアクセスしたければ、vmconnectを実行
>> vmconnect localhost CentOS7 

もし仮想マシンがWindowsなら、リモートデスクトップで立ち上げとか。
>> mstsc /v:仮想マシンのIPアドレス

しかし、ファイルの編集などは使い慣れた Windows上のエディタ環境を使いたいしソース管理もTortoiseSVNで引き続き行いたいので、仮想マシン上に cifs-utilsをyumでインストール。Windows上のDドライブをまるごと共有し、Linux側から マウントさせ、そのディレクトリをhttpd.confで適切なURLにマッピングしてやれることでWindows上でファイルを編集しつつ、そのコードは仮想マシン上のLAMPで動くという、理想的な環境のできあがり。
図にすると、下記のような感じ。

実際に、構築して使ってみると、これが快適すぎて、もっと早くにしとけばよかった。仮想マシンをエクスポートしてバックアップしとけばPC買い替えたときもラク。

はじめ仮想スイッチを内部専用にしたせいで仮想マシン側からホスト外にアクセスできず困ってたんですが・・・PowerShellの下記コマンドでNATを設置?することで解決。

PS>> New-NetNat -Name VMNatNetwork -InternalIPInterfaceAddressPrefix 10.0.0.0/24

確認には、
PS >> Get-NetNat | fl *
Store                            : Local
TcpFilteringBehavior             : AddressDependentFiltering
UdpFilteringBehavior             : AddressDependentFiltering
UdpInboundRefresh                : False
Active                           : True
Caption                          :
Description                      :
ElementName                      :
InstanceID                       : VMNatNetwork;0
ExternalIPInterfaceAddressPrefix :
IcmpQueryTimeout                 : 30
InternalIPInterfaceAddressPrefix : 10.0.0.0/24
InternalRoutingDomainId          : {00000000-0000-0000-0000-000000000000}
Name                             : VMNatNetwork
TcpEstablishedConnectionTimeout  : 1800
TcpTransientConnectionTimeout    : 120
UdpIdleSessionTimeout            : 120
PSComputerName                   :
CimClass                         : root/StandardCimv2:MSFT_NetNat
CimInstanceProperties            : {Caption, Description, ElementName, InstanceID...}
CimSystemProperties              : Microsoft.Management.Infrastructure.CimSystemProperties

しかし、問題が一つ。Windows側に置いておいた SQLiteのデータベースファイルに読むことはできても、変更(書き込み)することが一切できなくなっていた。どうやら仮想マシン上のPHP等から CIFS経由で変更しようとすると、ロックされてタイムアウトしてしまう事象が発生。

いろいろ調べた結果、どうやら 仮想マシンのCentOSからCIFS でホスト上の共有フォルダをマウントする際に、Byte range lock を無効しないとロックされてアクセスできないよー的な記事(ほとんど英語だらけの外国の方の記事ばっかりヒットする)を見つけ、下記のように /etc/fstab に記述すると解決できた。

/etc/fstab  -----

//10.0.0.1/Devel  /mnt/devel cifs user=nakagawa,password=xxxxxx,uid=nakagawa,gid=admin,nobrl,defaults  0 0

ポイントは、nobrl というオプション。これをつけるとバイト範囲のロックを無効にする・・・らしい。が、意味は分からんが、とりあえず、SQLiteファイルの変更中(書込み処理)ロックされることはなくなった。

めでたし、めでたし。

※追記)
Windows API の LockFile/LockFileEx とか、Linuxとかだとfcntl とか? で CIFSマウントされたディレクトリ内のファイルの「byte range lock」に対応していないってことなのかな・・・う~む?

WiFiが使えない!?そうだ!ルーター化しよう。

と、いつもの素人発想の(今更CentOS6?)思いつき「やってみた」私的備忘録です(m_m)

関係ないですが・・・Windows10のAnniversary Updateして、WSL(BASH)入れたらいつのまにか、サービスにSSHサーバーが・・・。netstat -a | findstr LISTEN したら、22番ポートが立ち上がってるやんけ!しかも全解放状態で(笑) ググったらWindows10を開発者モードにするとSSHdがインストール?されるみたい・・・とほほ。とりあえずサービス無効にした。でも、こういうのちゃんと通知してくれないと・・・ある意味公式のバックドアやん・・・。まぁ、開発者モードだから文句は言えないか・・・。

本題です。

社内で割り当てられたIPアドレスは3つで、

  • 社内業務用PC(グループウェアとかメールとか専用・ガチガチにセキュリティ高め&監視対象)のWindows7
  • 開発用のメインPC(Windows10) Windows Defenderのみ
  • 検証用のサーバー(CentOS6.7)

Surface3でOneNoteをメモ帳代わりに常時使っているので、ちょっと前までは、メインPCのWindowsに、APモードで利用できるUSBドングルタイプの無線LAN子機をつけて通信させていました。内緒だけど(^^;

で、8/3のAnniversary Updateで、このUSBドングルの無線LAN子機のドライバがサポート外になったのか、APモードにすると設定画面が消えてしまい正常に繋げなくなりました。ドライバのバージョンアップを待っているのですが、どうも対応しなそうな感じ・・・。環境依存で何かエラーになってるのかなー?と思いつつ原因が分からず。とりあえず、ドライバのバージョンアップを気長に待ってみたい。

で、やっぱり社内LANに接続できないと、不便・・・ってことで、検証用のサーバーにクロスケーブルで接続させてCentOSをルーター代わりにしてNATすりゃいいや、と思い、以下の構成でとりあえずやってみる。

network

検証用サーバーにもSurface3にも余っているLAN口がないので・・・バッファローのUSB-NICを二つ買ってきてクロスケーブルで繋ぐ。思ったんだけど、わざわざクロスケーブル買う必要なかったかもしれない・・・最近のNICってケーブルの種類を自動認識するし。

Surface3に接続させたUSB3-NICは自動認識ですぐにリンクアップ完了。IPアドレスを10.0.0.2と指定。準備完了。
CentOS側は・・・USB2-NICは自動認識するも、やっぱり手動設定させなければ・・・めんどっちーな・・・。

まずはMACアドレス確認。(下記MACアドレスは実際の値ではありません。ご了承のほど)

# dmesg | tail
Slow work thread pool: Ready
usb 2-2: new high speed USB device number 2 using ehci_hcd
usb 2-2: New USB device found, idVendor=0b95, idProduct=7720
usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 2-2: Product: AX88772 
usb 2-2: Manufacturer: ASIX Elec. Corp.
usb 2-2: SerialNumber: 228729
usb 2-2: configuration #1 chosen from 1 choice
asix 2-2:1.0: eth1: register 'asix' at usb-0000:00:1d.7-2, ASIX AX88772 USB 2.0 Ethernet, aa:bb:cc:dd:ee:ff
usbcore: registered new interface driver asix

フムフム、ちゃんとeth1として認識してますな。ドライバは既に入ってんすね。ラクショー・ラクショー。MACアドレス(aa:bb:cc:dd:ee:ff)をコピーして、
設定ファイルをコピーして適当に修正後、リンクアップして確認・・・。

# cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth1
# vi /etc/sysconfig/network-scripts/ifcfg-eth1
(ここでMACとかGATEWAYとかIPとかUUIDとか修正)
(UUIDは /usr/bin/uuidgen で。)

(リンクアップして確認する)
# ifup eth1
Determining if ip address 10.0.0.1 is already in use for device eth1...

# ifconfig
eth0      Link encap:Ethernet  HWaddr 11:22:33:44:55:66  
          inet addr:192.168.1.101  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:178189 errors:0 dropped:0 overruns:0 frame:0
          TX packets:144306 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:128726184 (122.7 MiB)  TX bytes:49793405 (47.4 MiB)
          Interrupt:16 

eth1      Link encap:Ethernet  HWaddr aa:bb:cc:dd:ee:ff
          inet addr:10.0.0.1  Bcast:10.0.0.255  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:76 errors:0 dropped:0 overruns:0 frame:0
          TX packets:76 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:8996 (8.7 KiB)  TX bytes:8996 (8.7 KiB)

ここで一旦クロスケーブルで接続して、Surface3側からpingしてみると、ちゃんと開通。
とりあえず、CentOS(eth1:10.0.0.1)とSurface3(10.0.0.2)の接続完了。

このままだと、社内LAN(192.168.1.0/24)にはパケットが飛ばないので、ここからNATの設定を試みる。
とりあえず、教科書どおりにやってみる。

# vi /etc/sysctl.conf
(net.ipv4.ip_forward = 1 に修正:異なるNIC間の転送を許可する。)

(設定を有効化)
# sysctl -p

(10.0.0.0/24のパケットを社内LANに繋がっているNICにNATして流す.用語の使い方間違ってます(m_m)
# iptables -t nat -A POSTROUTING -o eth0 -s 10.0.0.0/24 -j MASQUERADE

(surface3からのパケットを社内LANへそのまま転送許可する。
# iptables -I FORWARD 1 -i eth1 -o eth0 -s 10.0.0.0/24 -j ACCEPT
# iptables -I FORWARD 1 -m state --state ESTABLISHED,RELATED -j ACCEPT

ここでsurface3側から開発者用PC(192.168.1.102)にpingを打ってみると、ちゃんとパケットが到達。
この状態で、surface3の通知エリアにあるネットワークアイコンを見ると、ビックリマークが消え、インターネットアクセスに変わってます。一応surface3のEdgeで会社のホームページを見てみる。\(^O^)/

オールOK。設定を保存。

# service iptables save
iptables: ファイアウォールのルールを /etc/sysconfig/iptables に保存中: [  OK  ]

(ここでiptablesを再起動)
# service iptables restart
iptables: チェインをポリシー ACCEPT へ設定中nat filter [  OK  ]
iptables: ファイアウォールルールを消去中: [  OK  ]
iptables: モジュールを取り外し中:[  OK  ]
iptables: ファイアウォールルールを適用中: [  OK  ]
iptables: 追加のモジュールを読み込み中:nf_conntrack_ftp nf_conntrack_netbios_ns [  OK  ]

ってなわけで、CentOSの簡易ルーター化完了。

本当は、このUSB2-NICがCentOSマシンに接続された時だけ、上記手順をスクリプト化したファイルを実行させたり、USB2-NICが取り外された時に元の状態に戻すスクリプトを実行させたりしたいのですが、USB2-NICの接続状態を監視したりする方法とか、そういうのはどうやるんだろう・・・?

また暇になったら調べてみようっと。

Windows10でデフラグを無効にしてはいけない・・・

だ、そうです。
まぁ、今更感がマックスなんですが・・・Windows7 で、SSDをデフラグで最適化する、というのは御法度でした・・・よね???なんか自信なくなってきた。。。

Windows7からWindows10にアップグレードしたPCは、Windows7での設定を忠実に反映するので、ドライブのデフラグの設定は全ドライブ「無効」になっていました・・・orz 勝手にアップグレードするクセに、そういう所は気を利かせないんでつね。。。マイクロソフトさん・・・・そういうとこなんだよ・・・嫌われるのは・・・・(笑) あ、嘘です(m_m)

Windows10ではドライブのメディアの種類を検出して最適化を行ってるそうです。SSDをデフラグ(最適化)すると、Trimを発行してくれるそうで・・・↓参照。

ssd-defrag

Windows8のときって、自動メンテナンスが有効だった時、SSDもデフラグしてしまう、という問題を前に見たことあったんだけど、Windows10ではその対策ってされているのかな~・・・

ちなみに、SSD-RAID0構成の VAIO Z21 では、「最適化は使用できません」という表示で、デフラグ自体ができません。どうやらドライブのメディアの種類が SSD で、Trimコマンド非対応の場合は、デフラグ自体できないようになっているみたいです。
その辺は気を利かせてくれるのね・・・。。。

原因判明

Microsoft Edge がまともに設定できない件 の原因がやっと分かった。

僕はてっきり、コントロールパネルの「インターネット オプション」は、旧デフォルトブラウザ 『Internet Explorer 11 』の専用の設定だと思い込んでいた・・・。Windows10デフォルトのブラウザ Microsoft Edge もこの「インターネットオプション」を参照してるのね・・・OMG!!!

んで、Edgeの設定やら動作不良の原因が、どうやら、「インターネット一時ファイル」が破損しているのが原因やった・・・というのがオチ。
Windows7 のとき、この「インターネット一時ファイル」を置くフォルダを、Lightroomのキャッシュや各種一時ファイル(要するにドライブが壊れてしまっても構わないファイル)専用に購入したSSDドライブ(ジャンクに近い状態の格安商品)に設定していました。
たぶんこのドライブのACL(セキュリティー設定)をいいかげんに設定してたせいか、Windows10にアップグレードする過程で、おそらく このドライブのフォルダに Microsoft Edge がちゃんと書き込めるように適切な設定が為されていない状態だったようだ・・・推測ですけどね・・・。

インターネットのプロパティー ⇒ 閲覧の履歴 設定 ⇒ フォルダーの移動 をクリックして、デフォルトの状態に戻したら、あっけなく解決した。。。
あああ、結局のところ、僕が悪かった。こういうトラブルは往々にして自分が変なカスタマイズしてトラブルを起こすことが多い。

Microsoft Edge 様、「できない奴」呼ばわりして責任転嫁して、ごめんなさいっッッッッッ!