Virtualmin(LEMP)+Laravel

0
1076

VirtualminでLEMP環境を構築し、Laravelを動かしてみます。
LEMPはLAMP(Linux+Apache+MySQL/MariaDB+PHP)のApacheをNginxに替えたものですが、NではなくEなんですね(「エンジンエックス」だからEngineの「E」ってことなんでしょうか、そもそも何で「Nginx」なんてスペルにした?とは思いますが…)。
サーバ環境自体はVirtualbox/Vagrantで生成します(「Virtualbox / vagrant のすゝめ」参照)。
IPはprivate_networkの「192.168.33.25」としました。
同サーバにWebminを入れてVirtualminの「install.sh」を実行する直前まで進めます(「Webmin / Virtualmin のすヽめ」参照)。
install.shはデフォルトではLAMP環境を構築しますが、ここでオプションにLEMPを指定するとLEMP環境が構築されるんですね。

sh install.sh -b LEMP

途中で聞かれるホスト名は「lemp.com」としておきます。
環境構築が終わったらLaravelのインストールも行なってしまいます(「Laravel環境構築」参照)。
インストール先は「/home/lemp/product/laratest」としました。Virtualminインストール後の初期設定で「lemp.com」としての仮想ホスト環境を構築すると「lemp」とユーザーが自動的に生成され、「/home/lemp」がホームディレクトリになります。このホームディレクトリ配下に「product」ディレクトリを作成し、そこに「laratest」という名称でLaravelのプロジェクトを構築したと言うことです。
つまり、この仮想ホストにおけるドキュメントルートとしては「/home/lemp/product/laratest/public」と設定する必要があります。

Nginxの設定ファイル「/etc/nginx/nginx.conf」ですが、中を見るとVirtualminの初期設定により自動的に「lemp.com」に関する定義が反映されています。便利ですね。
ただ、以下の点に関して対処が必要です。

  • IPアドレスの変更(デフォルトでは「10.0.2.15」になっている)
  • ドキュメントルートの変更(デフォルトでは「/home/lemp/public_html」になっている)
  • 実在しないパスが指定された場合に無条件にドキュメントルート直下のindex.phpを呼び出すようにする必要がある

最初の2点はVirtualminでのLAMP環境構築時にも同じ問題がありましたが、単にデフォルト値として期待される値が設定されていないと言うだけの問題であり、「10.0.2.15」となっている箇所を「192.168.33.25」に、「/home/lemp/public_html」となっている箇所を「/home/lemp/product/laratest/public」に変更すれば良いです。

最後の1点はLAMP(Apache)ではドキュメントルート直下の「.htaccess」(Laravelインストール時に自動生成)で以下のように対処していた問題です。

RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteRule ^ index.php [L] 

ディレクトリもしくはファイルとして実在しないパスが指定された場合は無条件に「index.php」を呼び出すようにしています。
これと同等の対処を行うためには「lemp.com」に関する設定内容に以下を追加します。

location / {    
  try_files $uri $uri/ /index.php?$query_string;
}

ドキュメントルート直下から「$url」で指定されたパスに該当するファイルもしくはディレクトリが存在すればその処理を行い、存在しなければドキュメントルート直下の「index.php」を呼び出すと言う設定です。
(蛇足ながら)本件含めて、Apacheでは「.htaccess」を用いることで特定のディレクトリ配下限定かつ動的な(Webサーバの再起動を必要としない)設定が可能であったのに対してNginxではそれに相当する仕組みがないため、「.htaccess」の恩恵にあずかっていた身としては少々やり辛く感じる部分はあります。ただ、「.htaccess」に関してはドキュメントルート配下の様々なディレクトリ階層で指定可能であり、かつ上位ディレクトリでの設定は下位ディレクトリに継承される(下位ディレクトリで独自に上書きすることは可能)と言う性質上、下位ディレクトリでの設定内容を確定するためにはその上位ディレクトリ全てにおいて「.htaccess」の存在確認やその設定内容の取得が必要となるため、「.htaccess」が有効であることで処理性能的にマイナスの影響を与えていると言う側面もあったようです。
一長一短ありと言ったところですが、どちらが良いかと言う判断はなかなか難しいですね。

と言うことで、上記で触れた内容反映後の「lemp.com」関連の記述内容は以下のようになるかと思います。

server { 
  server_name lemp.com www.lemp.com;
  listen 192.168.33.25;
  root /home/lemp/product/laratest/public;
  index index.html index.htm index.php;
  access_log /var/log/virtualmin/lemp_access_log;
  error_log /var/log/virtualmin/lemp_error_log;
  fastcgi_param GATEWAY_INTERFACE CGI/1.1;
  fastcgi_param SERVER_SOFTWARE nginx;
  fastcgi_param QUERY_STRING $query_string;
  fastcgi_param REQUEST_METHOD $request_method;
  fastcgi_param CONTENT_TYPE $content_type;
  fastcgi_param CONTENT_LENGTH $content_length;
  fastcgi_param SCRIPT_FILENAME /home/lemp/product/laratest/public$fastcgi_script_name;
  fastcgi_param SCRIPT_NAME $fastcgi_script_name;
  fastcgi_param REQUEST_URI $request_uri;
  fastcgi_param DOCUMENT_URI $document_uri;
  fastcgi_param DOCUMENT_ROOT /home/lemp/product/laratest/public;
  fastcgi_param SERVER_PROTOCOL $server_protocol;
  fastcgi_param REMOTE_ADDR $remote_addr;
  fastcgi_param REMOTE_PORT $remote_port;
  fastcgi_param SERVER_ADDR $server_addr;
  fastcgi_param SERVER_PORT $server_port;
  fastcgi_param SERVER_NAME $server_name;
  fastcgi_param PATH_INFO $fastcgi_path_info;
  fastcgi_param HTTPS $https;
  location / { 
    try_files $uri $uri/ /index.php?$query_string;
  } 
  location ~ \.php(/|$) { 
    try_files $uri $fastcgi_script_name =404;
    fastcgi_pass unix:/var/php-nginx/160812801910909.sock/socket;
  } 
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  listen 192.168.33.25:443 default ssl;
  ssl_certificate /home/lemp/ssl.cert;
  ssl_certificate_key /home/lemp/ssl.key;
}

上記書き換え後にNginxを再起動します。

systemctl restart nginx.service

まずはブラウザから「https://192.168.33.25」とアクセスして、Laravelのデフォルト画面が表示されることを確認しましょう(基本)。
ただ、上記呼び出し自体は「/etc/nginx/nginx.conf」の設定変更時に触れた、実在しないパス指定時は「index.php」を呼び出すと言う設定に依存しない処理であるため、Laravelのルーティングに準じてURLに指定されたパス情報が想定通りのコントローラ+メソッドの呼び出しに変換されるところまで確認できて初めてNginx+Laravelの動作環境構築完了です。