Windows Server + Apache + PHP + MariaDB のサーバ構築

クラウド

Windows Server 上で PHP プログラムが動作する環境を構築します。
Web サーバに Apache、データベースに MariaDB を使用します。

Apache の設定
まずは Apache 側の設定を説明いたします。

Apache のインストール
以下の URL より Apache をダウンロードします。

Apache Lounge
https://www.apachelounge.com/download/

2021/08/30 時点の最新版は、Apache 2.4.48 Win64(httpd-2.4.48-win64-VS16.zip)になります。

Apacheの最新バイナリ

解凍したフォルダ(Apache24)を任意の場所に移動します。
今回は C ドライブ直下に配置します。

Apacheのフォルダ


Visual C++ ランタイムのインストール
Windows 用 Apache のバイナリは Visual C++ でビルドされているので、VC のランタイムが必要になります。
※すでにインストールされている場合は必要ありません。

以下の URL よりダウンロードします。

最新のサポートされる Visual C++ のダウンロード
https://support.microsoft.com/ja-jp/topic/最新の…

64bit の場合は vc_redist.x64.exe になります。

VCランタイムのダウンロード

ダウンロードしたファイルを実行することでランタイムがインストールされます。

httpd.conf の設定
Apache の設定ファイルであるhttpd.confを編集します。
httpd.confは、c:\Apache24\confにあります。
サーバの環境にもよりますが、おおむね以下の部分を編集すれば良いかと思います。

説明の便宜上、設定値の横にコメントを入れている箇所がありますが、Apache が起動しなくなる場合があるため、基本的にコメント行と設定行は分けてください。

●ServerRoot ディレクティブ(Apache Core
Apache の配置先フォルダを設定します。

Define SRVROOT "c:/Apache24"
ServerRoot "${SRVROOT}"

●Listen ディレクティブ(Apache MPM
httpdがリクエストを受信するポート番号を設定します。
IP アドレスとの組み合わせも可能です。
通常 HTTP であれば 80、HTTPS であれば 443 がデフォルトで使用されるポート番号です。

#Listen 12.34.56.78:80
Listen 80
Listen 443

●LoadModule ディレクティブ(Apache モジュール mod_so
ロードするモジュールを設定します。
使用可能なものは概ねすでに記述されていますので、必要となるモジュールのコメントを外します。

LoadModule rewrite_module modules/mod_rewrite.so # コメント外す

●ServerName ディレクティブ(Apache Core
アクセスされるドメイン名を設定します。
ポート番号との組み合わせも可能です。

#ServerName www.example.com:80
ServerName mydomain.com

●DocumentRoot ディレクティブ(Apache Core
公開ディレクトリを設定します。

#DocumentRoot "${SRVROOT}/htdocs"
DocumentRoot "c:/web/public"

●ドキュメントルートのディレクトリ設定
ドキュメントルートのディレクトリ内で適用するディレクティブを以下のように設定します。

#<Directory "${SRVROOT}/htdocs">
<Directory "c:/web/public">
	#Options Indexes FollowSymLinks
	Options FollowSymLinks

	#AllowOverride None
	AllowOverride All

	Require all granted
</Directory>

以下、各ディレクティブの説明です。

・<Directory> ディレクティブ(Apache Core
ディレクティブの適用をディレクトリ単位に指定できます。

・Options ディレクティブ(Apache Core
特定のディレクトリに対してどの機能が使用可能かを制御します。
デフォルトでは以下の2つがOptionsで設定されています。

Indexes
ディレクトリの中身が見えてしまう可能性があるので、セキュリティの観点から通常設定しません。
FollowSymLinks
サーバがこのディレクトリ内でシンボリックリンクをたどれるようにします。

・AllowOverride ディレクティブ(Apache Core
Noneが指定された場合、.htaccessは完全に無視されます。
.htaccessを有効にしたい場合はAllを指定します。

・Require ディレクティブ(Apache モジュール mod_authz_core
アクセスの許可を設定します。
all grantedではすべてのアクセスを許可します。
<Directory>ディレクティブや<Files>ディレクティブ内で使用できます。
ちなみに以下のような指定が可能です。

Require all granted # すべて許可
Require all denied # すべて拒否
Require ip 192.168.10.1 # 指定のIPアドレスからのアクセスのみ許可
Require ip 192.168.10.1/24 # 指定のIPアドレスの範囲からのアクセスのみ許可
Require host example.com # 指定のドメインからのアクセスのみ許可

●.htaccess の設定
デフォルトでは、.htaccess<Files>ディレクティブを用いて使用禁止にされています。
.htaccessを利用したい場合は、これを編集します。

<Files ".ht*">
    #Require all denied
    Require all granted
</Files>

・<Files> ディレクティブ(Apache Core
ディレクティブの適用範囲をファイル名で制限します。
ファイルの指定には正規表現も使用できます。

●<VirtualHost> ディレクティブ(Apache Core
リクエストの仕方によって複数の設定を活かすことが可能です。

異なるドメイン名でのアクセスがある場合:

<VirtualHost *:80>
	ServerName mydomain.org
	DocumentRoot "${SRVROOT}/htdocs"
</VirtualHost>
<VirtualHost *:80>
	ServerName mydomain.com
	DocumentRoot "c:/web/public"
</VirtualHost>

mydomain.orgでアクセスされた場合はc:\Apache24\htdocsmydomain.comでアクセスされた場合はc:\web\publicが公開されます。
サーバの IP アドレスに複数のドメインが割り当てられているときに利用可能です。

異なる IP アドレスでのアクセスがある場合:

<VirtualHost 192.168.1.1>
	ServerName mydomain.org
	DocumentRoot "${SRVROOT}/htdocs"
</VirtualHost>
<VirtualHost *:80>
	ServerName mydomain.com
	DocumentRoot "c:/web/public"
</VirtualHost>

上記は内部(イントラネット内)からのアクセスと外部からのアクセスを分けるときの例です。
192.168.1.1 でアクセスされた場合はc:\Apache24\htdocs、その他の IP アドレスでアクセスされた場合はc:\web\publicが公開されます。
サーバが複数の IP アドレスを持っているときも同様に利用可能です。


<VirtualHost>を利用すると各ディレクティブの設定がまとまって見やすいので、例え1つの設定しかなくとも、<VirtualHost>で設定しておく方が良いかもしれません。

<VirtualHost *:80>
	ServerName mydomain.com
	DocumentRoot "c:/web/public"
	<Directory "c:/web/public">
		Options FollowSymLinks
		AllowOverride All
		Require all granted
	</Directory>
</VirtualHost>


Apache のサービス化
Apache をサービス化します。
サービス化することで、Windows の再起動時にも自動的にhttpdが立ち上がります。
管理者権限のコマンドプロンプトより、以下のように入力します。

>cd \Apache24\bin
>httpd.exe -k install # サービス化
Installing the 'Apache2.4' service
The 'Apache2.4' service is successfully installed.
Testing httpd.conf....
Errors reported here must be corrected before the service can be started.

サービス化されたかどうか確認してみます。
「スタートメニュー」→「Windows 管理ツール」→「サービス」をクリックします。

サービス一覧画面

サービスに登録され、スタートアップの種類が「自動」になっています。

Apache の起動・停止
管理者権限のコマンドプロンプトより、以下のように入力します。

>cd \Apache24\bin
>httpd.exe -k start # Apacheの起動
>httpd.exe -k stop # Apacheの停止
>httpd.exe -k restart # Apacheの再起動
>httpd.exe -k uninstall # サービス解除

GUI からの操作も可能です。
c:\Apache24\binにあるApacheMonitor.exeを実行します。
タスクトレイの当該アイコンを右クリックし、Open Apache Monitor を選択します。

Apache Monitorの起動

右側に Start や Stop などの操作ボタンがあり、画面中央に操作結果が表示されます。

Apache Monitor

ポートの開放
httpdがリクエストを受信するポートを開放します 。
「スタートメニュー」→「Windows 管理ツール」→「セキュリティが強化された Windows Defender ファイアウォール」をクリックします。

セキュリティが強化された Windows Defender ファイアウォール

受信規則から新しい規則を作成します。

新しい受信規則

ウィザードにしたがってそれぞれ入力していきます。

規則の種類:ポート
プロトコルおよびポート:TCP、特定のローカルポート 80
操作:接続を許可する
プロファイル:ドメイン、プライベート、パブリック
名前:HTTP

受信規則の作成

受信規則が作成できました。

HTTPの受信規則


サーバ事業者側のサービスが独自のセキュリティ設定を持っている場合、そのセキュリティ設定を変更するまではポートが開放されません。
例えば AWS【Amazon Web Services】では、コンソールからセキュリティグループのインバウンドルールを追加する必要があります。

AWS の例:
上部メニューの「サービス」から「EC2」を選択し、インスタンス一覧画面を表示します。
該当のインスタンスを選択し「セキュリティ」タブをクリックすると、このインスタンスのセキュリティグループが表示されているのでそれをクリックします。
「インバウンドルール」タブにある「Edit inbound rules」をクリックするとインバウンドルールの編集画面が表示されます。

インバウンドルールの編集

「ルールを追加」をクリックすると行が増えるので、タイプ「HTTP」を選択し、ソース「Anywhere-IPv4」を選択します。
右下「ルールを保存」をクリックすれば完了です。

ここまでの設定で、一旦ブラウザから静的ページが見える状態になったかと思います。

It works!


PHP の設定
以下の URL より PHP をダウンロードします。

PHP for Windows
https://windows.php.net/download/

ここでは PHP7 の Thread Safe 版を使用します。
2021/08/30 時点の最新版は、PHP 7.4.23(php-7.4.23-Win32-vc15-x64.zip)になります。

PHPのダウンロード

解凍した中身を任意の場所に配置します。
今回は C ドライブ直下に php74 フォルダを作成し、中身をすべて移動します。

PHPのフォルダ

次に PHP の設定ファイルであるphp.iniを編集します。
php.iniは、c:\php74に配置します。
サンプルとしてphp.ini-developmentなどのファイルがあるので、これをコピーしてphp.iniを作成します。
プログラムの内容にもよりますが、おおむね以下の部分を編集すれば良いかと思います。

# 拡張モジュールのロード(コメント外す)
extension=curl
extension=fileinfo
extension=gd2
extension=mbstring
extension=mysqli
extension=openssl
extension=pdo_mysql

# 追記
extension_dir = "c:\php74\ext" # 拡張モジュールの場所
date.timezone = Asia/Tokyo # タイムゾーンの設定

必須というわけではありませんが、実行環境によっては設定変更が必要なパラメタをいくつか挙げてみます。
必要に応じて編集してください。

max_execution_time = 30 # 最大実行時間 [秒]、30秒過ぎると強制終了します
max_input_time = 60 # リクエストを受け付ける最大時間 [秒]、受信に60秒以上かかると強制終了します
memory_limit = 128M # スクリプトが確保できる最大メモリサイズ [byte]
error_reporting = E_ALL # エラー出力レベル、お勧めは"E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT"
display_errors = On # エラーを画面に出力(Offで出力しない)
log_errors = On # エラーをerror_logに出力(Offで出力しない)
post_max_size = 8M # POSTデータの最大サイズ [byte]
upload_max_filesize =2M # アップロードファイルの最大サイズ [byte]
session.gc_maxlifetime = 1440 # セッションデータが最短で破棄される時間 [秒]、お勧めは86400

パラメータの詳細については以下を参照してください。
参考: php.ini ディレクティブのリスト


Apache 側の設定も PHP の実行環境に合わせて編集が必要となります。
c:\Apache24\conf\httpd.confを編集します。

# 編集
<IfModule dir_module>
    DirectoryIndex index.html index.php # index.phpを追加
</IfModule>

# 追記
LoadModule php7_module "c:/php74/php7apache2_4.dll"
AddHandler application/x-httpd-php .php
PHPIniDir "c:/php74"

・DirectoryIndex ディレクティブ(Apache モジュール mod_dir
リクエストがファイル名を指定しなかった場合に表示するファイルを設定します。
デフォルトではindex.htmlのみ設定されているので、index.phpを追加します。

・IfModule ディレクティブ(Apache Core
当該モジュールが存在するときに処理されるディレクティブを指定するために利用します。

・AddHandler ディレクティブ(Apache モジュール mod_mime
拡張子とハンドラを紐づけます。
この記述により拡張子 “.php” のファイルは PHP プログラムとして扱われます。


最後に Apache を再起動します。
ここまでの設定で、PHP のスクリプトが動作する状態になっているかと思います。
ドキュメントルートにphpinfo();を記述したindex.phpを置いて確認してみましょう。

phpinfo


MariaDBの設定
以下の URL より MariaDB をダウンロードします。

Download MariaDB Server
https://mariadb.org/download/

ここでは MariaDB10 の Windows Installer 版を使用します。
2021/08/30 時点の最新版は、MariaDB 10.6.4(mariadb-10.6.4-winx64.msi)になります。

MariaDBのダウンロード

ダウンロードしたファイルをダブルクリックしてインストーラを起動、ウィザードにしたがってそれぞれ入力していきます。
今回は C ドライブ直下の “MariaDB 10.6” フォルダにインストールします。

MariaDBインストールウィザード1

「User settings」の画面では、root ユーザのパスワードを入力します。
character set に UTF8 を設定しておくと良いかと思います。

MariaDBインストールウィザード2

「Database settings」の画面では、 使用するポート番号や innodb の設定値を入力します。
これらの設定値は後からでも変更可能なので、そのままにしておいても構いません。

MariaDBインストールウィザード3

Service Name: サービスに登録する名称
TCP port: 使用するポート番号
Buffer pool size: データとインデックスを保存するためのバッファの大きさ
Page size: テーブルスペースのページサイズ

インストールが完了すると、MariaDB がサービスに登録されます。
「スタートメニュー」→「Windows 管理ツール」→「サービス」をクリックして確認します。

MariaDBサービス

無事登録されました。

※MariaDB の実行には、.NET Framework 4 が必要です。
※必要に応じてインストールあるいは有効化してください。

役割と機能の追加ウィザード


次に MariaDB の設定ファイル(c:\MariaDB 10.6\data\my.ini)を編集します。

[mysqld]
datadir=C:/MariaDB 10.6/data
port=3306 # ★使用ポート番号、必要に応じて変更
innodb_buffer_pool_size=127M # ★バッファの大きさ、必要に応じて変更
#character-set-server=utf8 # ★コメント化
character-set-server=utf8mb4 # ★4バイト文字に対応
# 追記
skip-character-set-client-handshake # クライアントからの文字コード指定を無視
default_password_lifetime = 0 # パスワードが無期限有効
default_authentication_plugin= mysql_native_password # ユーザー認証の方法を従来型にする

[client]
port=3306
plugin-dir=C:/MariaDB 10.6/lib/plugin

パラメータの詳細については以下を参照してください。
参考: 5.1.4 サーバーオプション、システム変数およびステータス変数リファレンス

以下はチューニング用の設定値です。
必要に応じて追記してください。

[mysqld]
# スロークエリーログ
slow_query_log=ON # スロークエリーログをとる、デフォルトOFF
long_query_time=0.5 # 0.5秒を超えるクエリーがログに吐きだされる、デフォルト10
slow_query_log_file=C:/MariaDB 10.6/log/slow.log # ログの吐きだし先

# 以下、設定値はデフォルト値です

# 同時接続数
max_connections=151 # クライアント同時接続数
open_files_limit=4184 # mysqldで使用可能なファイルディスクリプタの数

# バッファ
#InnoDBのデータとインデックスをキャッシュするバッファのサイズ(推奨は物理メモリの8割)
innodb_buffer_pool_size=134217728
# コミットされていないトランザクションのためのバッファのサイズ
innodb_log_buffer_size=16777216
# フルスキャンのレコードバッファ
read_buffer_size=131072
# キーを使用したソートで読み込まれた行がキャッシュされるバッファ
read_rnd_buffer_size=262144
# ソート時に使用されるバッファ
sort_buffer_size=2097152

# クエリキャッシュ
# クエリキャッシュ最大サイズ
query_cache_limit=1048576
# クエリキャッシュで使用するメモリサイズ
query_cache_size=1048576
# クエリキャッシュのタイプ(0:off, 1:ON SELECT SQL_NO_CACHE以外, 2:DEMAND SELECT SQL_CACHEのみ)
query_cache_type=OFF

# InnoDBの更新ログを記録するディスク上のファイルサイズ
innodb_log_file_size=2097152

# クライアントからサーバーに送信できるパケットの最大長
max_allowed_packet=16777216

# MEMORYテーブルの最大サイズ。このサイズを超えたMEMORYテーブルはディスク上に作成
max_heap_table_size=16777216

# コネクションタイムアウト時間
wait_timeout=28800

クエリキャッシュは MySQL 8.0 より非推奨になりましたが、MariaDB 10.6 には存在します。
参考: MySQL 8.0: Retiring Support for the Query Cache

設定が終ったらサービスを再起動します。
「スタートメニュー」→「Windows 管理ツール」→「サービス」でサービス画面を立ち上げ、「MariaDB」を選択し、左側の「サービスの再起動」をクリックします。

正常に動作しているかmysqlコマンドで確認してみましょう。
「スタートメニュー」→「MariaDB 10.6」→「Command Prompt」をクリックします。

MariaDBのコマンドプロンプト

コマンドプロンプトが立ち上がるので、root ユーザでmysqlコマンドを実行します。
パスワードはインストール時に設定したものを入力します。

C:\Windows\system32>mysql -u root -p
Enter password: **************

よく使われるコマンドの一覧です。
これらを実行して確認してください。

MariaDB [(none)]> status; # ステータスの参照
MariaDB [(none)]> show status; # サーバーステータス変数の参照
MariaDB [(none)]> show variables; # サーバーシステム変数の参照
MariaDB [(none)]> show variables like '%buffer%'; # 変数名の絞り込み

MariaDB [(none)]> show databases; # データベース一覧
MariaDB [(none)]> use DB; # データベースの切り替え

MariaDB [(none)]> show table status from DB; # テーブルステータスの参照
MariaDB [(none)]> show tables from DB; # テーブル一覧
MariaDB [(none)]> show fields from DB.TABLE1; # テーブルのフィールド一覧

# データベースの作成
MariaDB [(none)]> create database DB2 character set utf8mb4;
# ユーザーアカウント権限
MariaDB [(none)]> grant all on DB2.* to USER2@localhost identified by 'PASSWORD';
# ユーザーアカウント権限
MariaDB [(none)]> grant select,update,delete on *.* to USER3@12.34.56.78;

MariaDB にアクセスする PHP スクリプトをドキュメントルートに配置して実行してみます。

<?php
// DB接続テスト
$host = 'localhost';
$user = 'USER2';
$passwd = 'PASSWORD';
$dbname = 'DB2';

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
try{
	$db = new mysqli($host, $user, $passwd, $dbname);
	$db->set_charset('utf8mb4');

	$db->query('begin');
	$db->query('select * from TABLE1;');

	$db->rollback();
	$db->close();

}catch(mysqli_sql_exception $e){
	print 'errno='.$e->getCode().': '.$e->getMessage().': sqlstate: '.$db->sqlstate."\n";
}
?>

TABLE1 がないのでエラーになりましたが、connectはできているようです。

errno=1146: Table 'db2.table1' doesn't exist: sqlstate: 42S02


以上で終わりです。


参考: Windows Server に Let’s Encrypt を導入する

コメント