WordPress on App Service the hard way

# はじめに
Azure には[マーケットプレイス](https://azuremarketplace.microsoft.com/ja-jp/marketplace/)というサービスがあり、数クリックで [WordPress を App Service にデプロイする](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/WordPress.WordPress) ことができます。
この記事では、あえて手作業で App Service を作成し、WordPress をデプロイして、ついでに Azure の様々なツールを見ていこうということを目的としています。

なお、Azure アカウントは必要ですが、無料プランを使用するため 0 円で作成できます。

# 準備
- [Azure アカウント](https://docs.microsoft.com/ja-jp/learn/modules/create-an-azure-account/)
- ローカル PC への [Azure CLI](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli?view=azure-cli-latest) のインストール

Azure CLI をインストールする代わりに、ポータルから使用できる [Cloud Shell](https://docs.microsoft.com/ja-jp/azure/cloud-shell/overview) でも代用できますが、[Azure Files](https://azure.microsoft.com/ja-jp/pricing/details/storage/files/) にワーク領域が作成されるため、30-40円程度の課金が発生する可能性があります。


# App Service を作る
まずは、ポータルから App Service を作成します。
<img width="800" alt="screenshot_01-01.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/c207699a-b744-ada6-c85b-38c6e3ea45e0.jpeg">

リソースの作成から、Web App と入力して表示された「Web アプリ」を選択します。
<img width="800" alt="screenshot_01-02.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/3090ab78-4233-c01e-7719-f6da45637a8a.jpeg">
<img width="800" alt="screenshot_01-03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/4688c417-f215-f18f-9460-524ac8a02fa2.jpeg">

つづいて、作成する App Service の設定です。
作成する App Service の情報を指定します。

| リソースグループ       | 任意のリソースグループ名を指定してください     |
|:-----------------------|------------------|
| 名前             | 公開される App Service 名になります (example -> https://example.azurewebsites.net) |
| 公開 | コード |
| ランタイムスタック | PHP 7.3 |
| オペレーティングシステム    | Windows |
| 地域        | 任意のリージョンを指定してください。日本国内には 東日本(Japan East) と 西日本(Japan West) の2ヵ所があります |
| SKU とサイズ | [F1 (無償)](https://azure.microsoft.com/ja-jp/pricing/details/app-service/windows/) |

<img width="800" alt="screenshot_01-04.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/142608b0-a907-5dec-6baf-5d08b6a91811.jpeg">

「SKU とサイズ」が Free F1 以外になっている場合課金されてしまいますので、F1 になっていることを確認しましょう。
タイミングや利用状況によっては、F1 が選べない場合もありますが、その時は別のリージョンで探してみましょう。
一通り記入が完了したら [次: 監視 >] をクリックします。

<img width="800" alt="screenshot_01-06.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/512ef4bd-0ec3-1a9c-c2a2-88c29fd59900.jpeg">
[Application Insights](https://docs.microsoft.com/ja-jp/azure/azure-monitor/app/app-insights-overview) も今回は無効にします。
アプリケーションのパフォーマンス分析に非常に有用なサービスではありますが、従量課金のため、今回はコスト優先で無効にします。
「いいえ」を選択したら、[確認と作成] をクリックします。

<img width="800" alt="screenshot_01-07.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/90b6247b-dbeb-a511-1194-8ccee47d4275.jpeg">
作成される App Service の情報が表示されます。準備ができたら、[作成] ボタンで作成します。

[作成] をクリックすると、数秒後に App Service のデプロイページへ遷移します。
App Service のデプロイは通常1-2分程度で完了しますので、しばらく待ちましょう。
<img width="800" alt="screenshot_01-08.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/86c38c28-6fa9-8329-624c-fd8a2ff26636.jpeg">

デプロイが完了するとこんな画面が表示されます。
[リソースに移動] をクリックすると、作成した App Service の管理ページへアクセスできます。
<img width="800" alt="screenshot_01-09.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/f149b011-7920-365c-8c29-4637f0f54347.jpeg">

ようこそ、App Service へ。
これで、WordPress の実行環境が準備できました。
<img width="800" alt="screenshot_01-10.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/07b52ccd-0256-4fa3-e05d-53791c678e43.jpeg">

# WordPress を Azure CLI で デプロイする

つづいて、App Service に WordPress をデプロイします。
デプロイ方法は複数あります([Visual Studio Code から発行](https://docs.microsoft.com/ja-jp/azure/javascript/tutorial-vscode-azure-app-service-node-01?tabs=bash)、[展開してFTPでアップロード](https://docs.microsoft.com/ja-jp/azure/app-service/deploy-ftp)、など)が、今回は「WordPress の zip ファイルを Azure CLI でアップロードしてデプロイ」を試します。

デプロイを行う前に、まず、どのように展開されるのか確認してみましょう。
App Service の [高度なツール] を表示します。
<img width="800" alt="screenshot_02-01.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/fe9487e7-6237-1bdc-53d0-0125ea87c0a3.jpeg">

表示されたら [移動] をクリックします。
<img width="800" alt="screenshot_02-02.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/216d9fb3-8963-ce3d-abdd-6fb3f8cf30e8.jpeg">


App Service には Kudu と呼ばれる、管理用のアプリケーションが必ずセットで展開されます。
<img width="800" alt="screenshot_02-03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/82e24ffe-a23a-1d15-d3a1-12ae293db942.jpeg">

Windows と Linux では表示される内容や出来ることに若干の差がありますが、Windows の場合はファイル一覧表示と編集、プロセス一覧の確認が使用できます。


[Debug Console] から、CMD または Power Shell 好きな方を選択します(今回は CMD を使用)。
<img width="800" alt="screenshot_02-04.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/a3fe65f0-28fe-ccba-13fc-6080b892952e.jpeg">


このように、ファイル一覧とコマンドプロンプトのような画面が上下に並んで表示されます。
ファイル一覧とコマンドプロンプトは連動しており、ファイル一覧をクリックして階層を移動する、コマンドプロンプトからコマンドを入力するとそれぞれが更新されます。
<img width="800" alt="screenshot_02-05.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/4f408424-f960-8469-c03b-809456fd5650.jpeg">

アプリケーションは、 D:¥home¥site¥wwwroot に配置すると実行されますが、作成直後のためアプリケーションはありません。
<img width="800" alt="screenshot_02-06.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/8d705068-9d1c-8115-5c10-fe78191a81f6.jpeg">

実際に、[WordPress](https://ja.wordpress.org/) の zip バイナリを[ダウンロード](https://ja.wordpress.org/download/) して、App Service 上にデプロイします。


作業用のフォルダを作成して、Web ブラウザからダウンロードしても良いですが、せっかくなので、PowerShell によるダウンロード方法をご紹介します。
PowerShell より、Invoke-WebRequest コマンドレットを使用すると、Unix/Linux系でよく見る wget などと同じことが出来ます。

最新版の WordPress をダウンロードする場合

```powershell:
Invoke-WebRequest -Uri https://ja.wordpress.org/latest-ja.zip -OutFile WordPress-ja.zip
```

WordPress 5.3.2 をダウンロードする場合

```powershell:
Invoke-WebRequest -Uri https://ja.wordpress.org/WordPress-5.3.2-ja.zip -OutFile WordPress-ja.zip
```

WordPress の zip ファイルが準備できたら、Azure CLI を使用して App Service に対してデプロイします。
まずは、Azure CLI から Azure にログインします。

```powershell:
az login
```

Webブラウザが起動して Azure のアカウントを聞かれますので、サインインを行ってください。
つづいて、[az webapp deployment source config-zip](https://docs.microsoft.com/en-us/cli/azure/webapp/deployment/source?view=azure-cli-latest#az-webapp-deployment-source-config-zip) コマンドで、zip ファイルに格納されたアプリケーションを App Service にデプロイします。
```<group-name>``` に先ほど作成した App Service の リソースグループ名、```<app-name>``` に作成した App Service 名を指定します。

```powershell:
az webapp deployment source config-zip --resource-group <group-name> --name <app-name> --src clouddrive/<filename>.zip

例:
az webapp deployment source config-zip --resource-group rg-example-WordPress --name example-WordPress --src WordPress-ja.zip
```

zip push deployment の実行にはアプリケーションサイズにもよりますが、1-2分程度かかります。
実行すると下記のような出力が得られます。

```powershell:
PS D:\Home\Downloads\azure-WordPress> az webapp deployment source config-zip --resource-group rg-example-WordPress --name example-WordPress --src WordPress-ja.zip
Getting scm site credentials for zip deployment
Starting zip deployment. This operation can take a while to complete ...
Deployment endpoint responded with status code 202
{
  "active": true,
  "author": "N/A",
  "author_email": "N/A",
  "complete": true,
  "deployer": "Push-Deployer",
  "end_time": "2020-03-07T22:02:48.9242773Z",
  "id": "055589c815444ad18a848e0fa3b34523",
  "is_readonly": true,
  "is_temp": false,
  "last_success_end_time": "2020-03-07T22:02:48.9242773Z",
  "log_url": "https://example-wordpress.scm.azurewebsites.net/api/deployments/latest/log",
  "message": "Created via a push deployment",
  "progress": "",
  "provisioningState": null,
  "received_time": "2020-03-07T22:02:19.8813391Z",
  "site_name": "example-wordpress",
  "start_time": "2020-03-07T22:02:20.0689142Z",
  "status": 4,
  "status_text": "",
  "url": "https://example-wordpress.scm.azurewebsites.net/api/deployments/latest"
}
PS D:\Home\Downloads\azure-WordPress>

```

Azure CLI でデプロイすると、高度なツールで表示していた wwwroot フォルダの内容が更新され、 "wordpress" というフォルダが表示されました。
<img width="800" alt="screenshot_02-09.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/8236abf1-cada-c354-af65-71badcd4fdb8.jpeg">

Az webapp コマンドでは、zip ファイルの内容がそのまま、wwwroot 配下に配置されます (zip ファイルの内容で wwwroot を入れ替えるという方が正しいかもしれません)。

このままでも良いのですが、できれば App Service のルートディレクトリに WordPress を配置したいので、ファイルを移動します
(http://example-wordpress.azurewebsites.net/ **WordPress/** となってしまうので、フォルダ階層を一つ減らす)。

```cmd:
move wordpress\* .\
move wordpress\wp-admin .\
move wordpress\wp-content .\
move wordpress\wp-includes .\
rmdir /q /s wordpress
```
<img width="800" alt="screenshot_02-10.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/4ffd10d9-478b-f7d8-507a-1e16c988ed9e.jpeg">

これで WordPress の配置が出来ました。実際に動作しているか確認してみましょう。
App Service のページ、右側に URL という項目があります。ここから URL をコピーして、ブラウザで開きます。
<img width="800" alt="screenshot_02-11.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/bd63f8ac-d3f4-bb9e-4f21-bd1e84d760ca.jpeg">

WordPress の初期設定ページが表示されれば成功です。
<img width="800" alt="screenshot_02-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/4ab55d78-c080-9a45-43fb-c39eb640e9e3.png)




# MySQL In App を作る

WordPress を動かすためには MySQL (Maria DB) や PostgreSQL 必要ですが、App Service (Windows環境) では、[MySQL In App](https://github.com/projectkudu/kudu/wiki/MySQL-in-app) という、App Service インスタンス内で、MySQL を稼働させるオプションが準備されています。
この MySQL はあくまでもテストや検証で使用することを目的としており、本番運用に耐えうるものではないと[明言されています](https://azure.microsoft.com/ja-jp/blog/mysql-in-app-preview-app-service/)。 
※本番運用を検討されている場合、今回の構成では不十分ですので、 [Azure Database for MySQL](https://azure.microsoft.com/ja-jp/services/mysql/) や [Azure Database for PostgreSQL](https://azure.microsoft.com/ja-jp/services/postgresql/) などのご利用をご検討ください
```
MySQL in-app is not recommended for production applications. Please also keep in mind the following tips and limitations when using this feature:
```
しかし、アクセス数の少ない WordPress をちょっと動かす程度であれば十分ですので、試してみましょう。

App Service より [MySQL In App] を見ると、[オフ] になっているので、[オン] にして 保存します。
<img width="800" alt="screenshot_03-01.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/fd5a3fd8-ecce-d4ac-ea59-946b2a172848.jpeg">


[MySQL 低速クエリログ] や [MySQL 一般ログ] を有効にしておくと、開発中の問題発生時の解決の助けになるかもしれませんが、ここでは必須ではありません。
<img width="800" alt="screenshot_03-02.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/bd952e4f-529c-5319-24dc-3a7a63099a16.jpeg">
MySQL In App を管理する際、MySQL Command-Line Client などを使用して操作することはできません。組み込みの phpMyAdmin を使用して管理する必要があります。
ページ上部の [管理] をクリックします。
<img width="800" alt="screenshot_03-03.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/190c7b4b-5090-cb40-0536-2c56dd9b5c1b.jpeg">

ログインページが出てきた場合、Kudu の Process Explorer でプロセスの状況を見ていると分かりますが、MySQL プロセスが起動していません。
<img width="800" alt="screenshot_03-04.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/40515cca-aa79-f33a-98ee-9c94d6690439.jpeg">

作成した App Service のページへ、ブラウザでアクセスすると MySQL プロセスも起動します。
<img width="800" alt="screenshot_03-05.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/371eec2e-3a50-f979-8d72-6542bacc6c2a.jpeg">

この状態で、[管理] へアクセスすると、ログインページが表示されず、そのまま管理画面へジャンプします。

これで、MySQL の準備が整いました。


# WordPress の config 
WordPress に対して、MySQL In App へ接続するような設定を入れる必要があります。
MySQL In App に接続するユーザー名やパスワードはどうすれば良いのでしょう？

実は、MySQL In App への接続設定は環境変数にセットされており、毎回その設定を読み取
ってセットすることが推奨されています(ユーザー名は変わらないが、ポート番号などは毎回変わるため)。そのため、wp-config.php を編集する必要があります。
*MySQL in app - Enable/disable feature*
https://github.com/projectkudu/kudu/wiki/MySQL-in-app#enabledisable-feature

まずは、wp-config-sample.php をコピーして、wp-config.php を作成します。
<img width="800" alt="screenshot_04-01_.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/074fa0fc-1acc-8a18-f1db-f839ff8ce864.jpeg">

高度なツールには ファイルの編集機能も付いています。wp-config.php の左側にある、ペンのアイコンをクリックして編集しましょう。
wp-config.php のコードに含まれる、データベース名の指定を環境変数から取得した値をセットするように変更しています。

```php:wp-config.php(変更前)
// ** MySQL 設定 - この情報はホスティング先から入手してください。 ** //
/** WordPress のためのデータベース名 */
define( 'DB_NAME', 'database_name_here' );

/** MySQL データベースのユーザー名 */
define( 'DB_USER', 'username_here' );

/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', 'password_here' );

/** MySQL のホスト名 */
define( 'DB_HOST', 'localhost' );

```

```php:wp-config.php(変更後)
// Azure MySQL In App configuration
$servername = "";
$username = "";
$password = "";
$dbname = "";

// Parsing connnection string
foreach ($_SERVER as $key => $value) {
    if (strpos($key, "MYSQLCONNSTR_") !== 0) {
        continue;
    }
    
    $servername = preg_replace("/^.*Data Source=(.+?);.*$/", "\\1", $value);
    $dbname = preg_replace("/^.*Database=(.+?);.*$/", "\\1", $value);
    $username = preg_replace("/^.*User Id=(.+?);.*$/", "\\1", $value);
    $password = preg_replace("/^.*Password=(.+?)$/", "\\1", $value);
}

/** WordPress のためのデータベース名 */
define( 'DB_NAME', $dbname );

/** MySQL データベースのユーザー名 */
define( 'DB_USER', $username );

/** MySQL データベースのパスワード */
define( 'DB_PASSWORD', $password );

/** MySQL のホスト名 */
define( 'DB_HOST', $servername );
```

ついでなので、認証用のユニークキーも取得して、書き換えておきましょう。
https://api.wordpress.org/secret-key/1.1/salt/


# WordPress の最終設定
WordPress から MySQL  への接続設定を記載したら、もう一度、App Service の URL をブラウザで表示します。
すると、前回までの DB への接続定義などを求められる初期設定ではなく、サイトのタイトルやユーザー名を入力する項目が表示されます。
<img width="800" alt="screenshot_04-04.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/7b1fa8d9-800d-eea4-7853-7cd6d6de6cd2.jpeg">

内容は [5分間インストール](https://wpdocs.osdn.jp/WordPress_%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB#5.E5.88.86.E9.96.93.E3.82.A4.E3.83.B3.E3.82.B9.E3.83.88.E3.83.BC.E3.83.AB
) と同じで、ユーザー名やパスワード、メールアドレスを入力して、[WordPress をインストール] をクリックしたら終了です。


# 出来上がり
これで WordPress が使えるようになりました！
<img width="800" alt="screenshot_04-05.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/e007ec1f-542c-5909-f556-85daeb2dfe61.jpeg">
<img width="800" alt="screenshot_04-06.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349915/f7c4ce60-ec8b-e56d-9be0-8491f0e980c4.jpeg">

App Service 上に WordPress を導入してみた感想はいかがでしたでしょうか。
思ったより簡単でしたか？

Azure App Service は PaaS 環境のため、レンタルサーバーなどとは少し勝手はちがいますが、Azure CLI や Azure DevOps などの CI ツールと組み合わせてを使うことで多くのことができるようになります。
このドキュメントが皆様のお役に立てれば幸いです。