LAMPサーバーでWordPressブログを開設する

LAMPサーバーとは、オープンソースソフトウェアだけで作り上げるサーバーです。可能な限りコストを下げることができます。
**L**inuxで**A**pacheと**M**ariaDB(MySQL)と**P**HP(Perl/Python)でサーバーを構築しようという構想です。

[AWS公式ドキュメント](https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/tutorials-al2023.html)を参考に、ドメインやSSL/TLS証明書に関するあれこれを加えて、最終的にWordPressでブログを開設するまでをまとめてみました。

なお、データベースのMariaDBは最新版を使わず10.5を利用します。これは、そのバージョンがAmazonLinuxでの正式サポート（執筆時点）だからです。
ただ、MariaDB 10.5のサポート自体は2025年6月24日までということですので、それまでにはAmazonLinuxも何かしてくれるかもしれません。



- 前提
・ Amazon EC2サービス利用
・ **Amazon Linux 2023 AMI**
・ Apache 2.4
・ MariaDB **10.5**
・ お名前.comでドメイン取得済み
・ Let's Encrypt でSSL/TLS証明書を発行してもらう
・ WordPress でブログを開設

<br>

# 1,システムを最新にする
```Console
$ sudo dnf update -y
```

# 2,ApacheとPHP等をインストールする
ここではApacheに加え、wgetとPHP関連を一緒にインストールします。
ここでインストールする一覧です。
| パッケージ | 説明 |
|:-:|:-|
| httpd | Apache HTTPサーバー。ウェブサーバーソフトウェア |
| wget | ファイルをダウンロードするためのコマンドラインツール |
| php-fpm | FastCGI Process Manager。PHPの高速CGIプロセスマネージャー |
| php-mysqli | PHPからMySQLデータベースに接続するための拡張モジュール |
| php-json | PHPでJSONデータを処理するための拡張モジュール |
| php | PHPスクリプト言語のメインパッケージ |
| php-devel | PHPの開発用ヘッダファイルとライブラリ |


```Console
$ sudo dnf install -y httpd wget php-fpm php-mysqli php-json php php-devel
```

# 3,Apache ウェブサーバーを起動
Apacheを起動するだけではなく、ブート時に自動起動してくれるようにしましょう。
```shell-session
//起動
$ sudo systemctl start httpd

//起動を確認
$ sudo systemctl status httpd

//自動起動するように設定
$ sudo systemctl enable httpd

//自動起動が設定されてるか確認
$ sudo systemctl is-enabled httpd
```

# 4,ディレクトリの所有権とアクセス許可を設定
Amazon Linux Apache ドキュメントルートは `/var/www/html` であり、デフォルトでは root によって所有されます。
apacheに所有権とアクセス許可を与えます。
```Console
//ユーザー(今回はec2-user) を apache グループに追加します。
$ sudo usermod -a -G apache ec2-user

//ここで、いったんログアウトします。
$ exit

//再度ログインし、ユーザーが所属しているグループにapacheが含まれているかを確認します。
$ groups

// /var/www とそのコンテンツのファイル所有権を apache ユーザーに付与します。
$ sudo chown -R apache /var/www

// /var/www とそのコンテンツのグループ所有権を apache グループに付与します。
$ sudo chgrp -R apache /var/www

//グループに対し/var/www とサブディレクトリへのディレクトリ許可を変更します。
$ sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \;

//グループに対し/var/www とサブディレクトリへのファイル許可を再帰的に変更します。
$ find /var/www -type f -exec sudo chmod 0664 {} \;
```
> これで、ec2-user (および apache グループの将来のメンバー) は、Apache ドキュメントルートでファイルを追加、削除、編集できるようになります。したがって、静的ウェブサイトや PHP アプリケーションなどのコンテンツを追加できます。


# 5,LAMPサーバーをテスト
試しに`/var/www/html` ディレクトリに PHP ファイルを作成してブラウザで開いてみましょう。
```Console
//Apache ドキュメントルートで PHP ファイルを作成します。
$ echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php
```
これはechoで`"\<?php phpinfo(); ?>"`という内容のテキストを`/var/www/html/phpinfo.php`というファイル名で書き出しています。
アクセス許可がちゃんとできていないと、ここでエラーが起きます。

次は、ブラウザからアクセスしてみましょう。サーバーのIPアドレスなどでアクセスできます。
```url:ブラウザ
http://(サーバーのIPなど)/phpinfo.php
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555422/4cea7881-ad49-0d74-b0c1-ce62ab74e652.png)
かっこいいです。

ですが、この情報をネットに公開しておくのも良くないので、このページは削除します。
```Console
$ rm /var/www/html/phpinfo.php
```

# 6,お名前.comのDDNSを自動更新
これはオプションです。
AWSのElastic IPサービスを利用すれば必要ないものと思います。
しかしながら、絶対無駄な出費はしたくない！　という方にはお勧めしておきます。
[こちらの別記事](https://qiita.com/NZTD/items/4ffb6f71fb96ac75a743)にて解説しています。

https://qiita.com/NZTD/items/4ffb6f71fb96ac75a743


# 7,Let's Encrypt でSSL/TLS証明書の取得と自動更新
Let's Encrypt はhttps等のセキュアな通信に必要な証明書を無料で発行してくれます。
無料である分、社会的な信用度は低くなりますが、暗号自体の堅牢度は変わりません。
今回はLet's Encrypt にて証明書を発行してもらい、それをApacheに登録、尚且つ自動で継続的に更新し続けてくれるようにします。

### ポート80の仮想ホストを設定
最初に、`/etc/httpd/conf/httpd.conf` に以下の内容を追記します。
ポート80の仮想ホストを設定しています。
これをしないと、証明書発行のやり取りができないようです。
```Console
$ sudo nano /etc/httpd/conf/httpd.conf
```
書き加えるのは以下になります。末尾で大丈夫です。
`ドメイン名`を書き換えてください。例：www.example.com
```conf:/etc/httpd/conf/httpd.conf
<VirtualHost *:80>
    ServerName ドメイン名
    DocumentRoot /var/www/html

    <Directory /var/www/html>
        AllowOverride All
    </Directory>

</VirtualHost>
```
設定を反映させるため、Apacheを再起動します。
```Console
$ sudo systemctl restart httpd
```
### 便利なプラグインを付けてcerbotをインストール
**cerbot**は”Let's Encrypt”に証明書を発行してもらうツールです。
そして、Apacheとそのツールとの連携をささっとやってくれるプラグインが**python3-certbot-apache**です。
```Console
//インストール
$ sudo dnf install -y certbot python3-certbot-apache
```


### Let’s EncryptからSSL/TLS証明書を取得し、Apacheに設定
`ドメイン名`を書き換えるのを忘れないでください。
例：www.example.com
私はお名前.comで取得しました。

そうしましたら、次に証明書を取得して、Apacheに設定します。
```Console
//Apacheを停止する
$ sudo systemctl stop httpd

//SSL/TLS証明書を取得・設定
$ sudo certbot --apache -d ドメイン名
```
:::note
自分の環境では以下のようなエラーが出たのですが、Apacheがちゃんと止まってなかったようです。
Error while running apachectl configtest.

AH00526: Syntax error on line 101 of /etc/httpd/conf.d/ssl.conf:
SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty
:::
<br>

実行すると、Eメールアドレスを聞かれるので、入力しましょう。
```
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): 
```
利用規約への同意を求められます。**Y**で。
```
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: 
```
あなたのメールを共有して色々な情報のメールを送っても良いですか？　**N**で
```
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: 
```
エラーが無ければ無事に発行され、Apacheに設定されてるかと思います。

:::note
「Unable to find a virtual host listening on port 80 which is currently needed for Certbot to prove to the CA that you control your domain. Please add a virtual host for port 80.」という赤字の表示が出たら、上記の「ポート80の仮想ホスト」が設定できていないのだと思います。
私はこれで苦労しました。
:::

# 8,セキュリティの強度を調べてみる
これは必須ではありませんが、自分のサイトが安全かどうかを調べることは時に重要ではないかと思います。
[Qualys SSL Labs](https://www.ssllabs.com/ssltest/analyze.html)のサイトにて今回作ったサーバーの完全修飾ドメイン名（www.example.comなど）を入力すると、1，2分で評価（A～F）が出ます。
AWSで提供しているAmazon Linux 2023で進めているのでしたら、きっとAランクなのではないでしょうか。
もしAでないようでしたら、[AWSの公式ドキュメント](https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/SSL-on-amazon-linux-2023.html#ssl_test_2023)が強化する方法の参考になるかもしれません。

# 9, systemd timer を使って証明書更新の定期実行を設定
定期実行にはcrontabを頭に浮かべる方が多いかと思います。
しかしながら、Amazon Linux 2023 ではデフォルトで提供されておらず、代わりに[**systemd timer**への移行がお勧め](https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/cron.html)とのことです。
全てには理由があるのであろうと考え、素直に従います。~~でもすこしめんどうだよ~~

### 設定ファイルの作成
`/etc/systemd/system`に`certbot.service`を作成します。
```console
$ sudo nano /etc/systemd/system/certbot.service
```
以下の内容を貼り付けてください。
```:certbot.service
[Unit]
Description=certbotでSSL/TLS証明書を更新

[Service]
Type=oneshot
User=root
ExecStart=certbot renew --pre-hook "service httpd stop" --post-hook "service httpd start"

[Install]
WantedBy=multi-user.target
```
これは、certbotで更新を行う前にApacheを停止し、更新が終わったらApacheを起動させるものです。

続けて、`/etc/systemd/system`に`certbot.timer`を作成します。
```console
$ sudo nano /etc/systemd/system/certbot.timer
```
以下の内容を貼り付けてください。
```:certbot.timer
[Unit]
Description=certbotを定期実行します

[Timer]
OnCalendar=*-1,3,5,7,9,11-1 1:00:00
Persistent=true

[Install]
WantedBy=timers.target
```
これはcertbot.serviceを毎年1,3,5,7,9,11月の1日 AM1時に実行するという内容です。
Let's Encrypt の証明書は有効期限が3か月であるため、2か月毎に更新すれば安心というわけです。

### 設定ファイルの有効化
```console
//サービスの起動
$ sudo systemctl start certbot.timer

//サービス自動起動を有効に
$ sudo systemctl enable certbot.timer
```
これで、2か月ごとにSSL/TLS証明書が自動的に更新されます。

# 10,MariaDBをインストールする
MariaDBはMySQLから派生した、次世代を期待されるリレーショナルデータベースです。
執筆時点でのAmazonLinux2023はバージョン10.5が正式サポート対象です。

```Console
//インストール
$ sudo dnf install -y mariadb105-server

//MariaDB サーバーを起動
$ sudo systemctl start mariadb

//自動起動するように設定
$ sudo systemctl enable mariadb
```
### データベースサーバーをセキュリティで保護する
```Console
//mysql_secure_installation を実行
$ sudo mysql_secure_installation
```
プロンプトが表示されます。質問に答えていきましょう。

```
Enter current password for root (enter for none): 
```
ルートアカウントのパスワードを求められます。
現在はデフォルト状態なのでパスワードは未設定です。そのままEnterを押してください。

```
Switch to unix_socket authentication [Y/n] 
```
認証方法をunix_socketに切り替えるかどうか聞かれます。
unix_socketを使うと、OSのユーザー名とMariaDBのユーザー名が一緒なら、ログイン時にパスワード入力不要の認証が可能になります（要追加設定）。
私はrootじゃない通常ユーザーでログインしたく、出来ればunix_socket認証できるようにしたいので**Y**にします。

```
Change the root password? [Y/n] 
```
次に、rootパスワードを変更するか聞かれます。現在はデフォルトのパスワード無しになっています。
MariaDB側の文面には「You already have your root account protected, so you can safely answer 'n'.」と書いてくれていますが、AWSの公式ドキュメントには「**Y**で」と書かれています。
セキュリティを考えれば当然パスワードは設定すべきです。
**Y**で。
```
New password: 
Re-enter new password: 
```
同じパスワードを2回入力します。
8文字以上で記号なども含めたやつが良いです。
忘れないようにしてください。

```
Remove anonymous users? [Y/n] 
```
匿名ユーザーは削除します。**Y**で。

```
Disallow root login remotely? [Y/n] 
```
リモートルートログインは無効にします。**Y**で。

```
Remove test database and access to it? [Y/n] 
```
インストール時に自動的に用意されたTest用データベースを消すか聞かれます。どんな感じか見てみたい人は消さなくても良いと思いますが、正式運用時にはちゃんと消しておきましょう。
今回は**Y**で。

```
Reload privilege tables now? [Y/n] 
```
権限テーブルを再ロードし、変更を保存します。**Y**で。

### MariaDBユーザーを追加する
MariaDB にログインします。
```shell-session
//mysql -u root -p でもOK
$ mariadb -u root -p
```
先ほど設定したパスワードを入力してください。

ログインしましたら、以下のコマンドを実行していってください。
ユーザー名には各自のOSログイン時のユーザー名を入れてください。
今回は`ec2-user`です。
`IDENTIFIED VIA unix_socket`によって認証をunix_socketに設定しています。
```sql:MariaDB
`対象ユーザーをunix_socket認証で登録する`
CREATE USER 'ec2-user'@'localhost' IDENTIFIED VIA unix_socket;

`既に登録済みのユーザーでしたら更新します`
ALTER USER 'ec2-user'@'localhost' IDENTIFIED VIA unix_socket;

`今回は全てのデータベースに対しフル権限（GRANT OPTION）を与えます`
GRANT ALL PRIVILEGES ON *.* TO 'ec2-user'@'localhost' WITH GRANT OPTION;

`最後に設定を反映させる`
FLUSH PRIVILEGES;
```
正しく設定されているかを確認できます。
```sql:MariaDB
SELECT user, host, plugin FROM mysql.user;
```
終わったらログアウトしましょう
```sql:MariaDB
exit
```
これで、次回からはパスワード要らずで簡単にログインできるようになります。
```shell-session
//$ mysql も可
$ mariadb
```

# 11. phpMyAdminをインストール
phpMyAdminは、MySQLおよびMariaDBのデータベース管理をウェブブラウザ上で行うためのオープンソースツールです。使いやすいインターフェースを提供し、SQLの知識があまりなくてもデータベースの操作が可能です。[GPT先生の解説はこちら](https://chatgpt.com/share/60c5ebf2-4189-4d8f-8d46-21c28eba5ae6)

1, 必要な依存関係をインストールします。
```console
$ sudo dnf install php-mbstring php-xml -y
```
2, Apache を再起動します。
```console
$ sudo systemctl restart httpd
```
3, php-fpmも再起動します。
```console
$ sudo systemctl restart php-fpm
```
4, Apache ドキュメント ルート(`/var/www/html`)に移動します。
```console
$ cd /var/www/html
```
5, 最新の phpMyAdmin をダウンロードします。
```console
$ wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.tar.gz
```
6, `phpMyAdmin`フォルダーを作成し、次のコマンドを使用してその中にパッケージを抽出します。
```console
$ mkdir phpMyAdmin && tar -xvzf phpMyAdmin-latest-all-languages.tar.gz -C phpMyAdmin --strip-components 1
```
7, 要らなくなった`phpMyAdmin-latest-all-languages.tar.gz`ファイルを削除します。
```console
$ rm phpMyAdmin-latest-all-languages.tar.gz
```
8, WebブラウザでphpMyAdminインストール用のURLを開きます。
```:ブラウザ
http://(サーバーのIPまたはドメイン)/phpMyAdmin
```
ログインページが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555422/cb5336f1-4496-d065-a8f1-d1a8a0ee7af9.png)
9, ユーザー名には`root`、パスワードにはMariaDBの`root`ユーザーのパスワードを入れてログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555422/69a37516-cbe1-3bd2-a20e-5ded633cbcc3.png)

phpMyAdmin のインストールは以上です。
必要があれが各自構成してください。


# 12,日本語版 WordPressをインストール
1, パッケージをダウンロードしておく
```console
//カレントディレクトリをホームに戻しておく
```console
$ cd ~

//最新の日本語版 WordPress インストールパッケージをダウンロード
$ wget https://ja.wordpress.org/latest-ja.zip

//インストールパッケージを解凍
$ unzip latest-ja.zip

//データベースとWEBのサーバーをちゃんと起動しておく
$ sudo systemctl start mariadb httpd
```

2, WordPress用のデータベースを作成
MariaDBにログインしてから作業してください。
```sql:MariaDB
CREATE DATABASE `wordpress-db`;
```

3, MariaDBにWordPress用ユーザーを追加する
こちらは強力なパスワードを設定してください。
```sql:MariaDB
CREATE USER 'wordpress-user'@'localhost' IDENTIFIED BY 'パスワード';
```


4, WordPress ユーザーにデータベースの権限を付与
```sql:MariaDB
GRANT ALL PRIVILEGES ON `wordpress-db`.* TO "wordpress-user"@"localhost";
```

5, 変更を有効に
```sql:MariaDB
FLUSH PRIVILEGES;
```

6, WordPressの設定ファイルを作成
`wp-config-sample.php`を `wp-config.php`という名前でコピーします。
```console
$ cp wordpress/wp-config-sample.php wordpress/wp-config.php
```

7, `wp-config.php`を編集
```console
$ nano wordpress/wp-config.php
```
`DB_NAME` `DB_USER` `DB_PASSWORD`を定義する行を探して、値を修正する。
パスワードは`wordpress-user`用のものです。
```php:wp-config.php
define('DB_NAME', 'wordpress-db');
define('DB_USER', 'wordpress-user');
define('DB_PASSWORD', 'パスワード');
```
`Authentication Unique Keys and Salts` というセクションを見つけます。ここの`KEY`や`SALT`値は、 WordPress ユーザーが使っているブラウザの `Cookie` に暗号化レイヤーを提供します。基本的に、ここで長くてランダムな値を指定すると、サイトのセキュリティが向上します。https://api.wordpress.org/secret-key/1.1/salt/ にアクセスすると、自動でランダムに生成されるキーセット値を一度に取得できます。それをコピーして下記のところと置き換えてください。
```php:wp-config.php
define( 'AUTH_KEY',         'put your unique phrase here' );
define( 'SECURE_AUTH_KEY',  'put your unique phrase here' );
define( 'LOGGED_IN_KEY',    'put your unique phrase here' );
define( 'NONCE_KEY',        'put your unique phrase here' );
define( 'AUTH_SALT',        'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT',   'put your unique phrase here' );
define( 'NONCE_SALT',       'put your unique phrase here' );
```

書き換えたら、ファイルを保存してエディタを終了してください。

8, Apache ドキュメントルートの下に WordPress ファイルをインストールします。
ブログをドキュメントルートに設置するか、サブディレクトリに設置するかで、ブログのアドレスが変わります。

ドキュメントルートに設置する場合は
```console
$ cp -r wordpress/* /var/www/html/
```
サブディレクトリ（例：blog）に設置する場合は
```console
$ mkdir /var/www/html/blog
$ cp -r wordpress/* /var/www/html/blog/
```
:::note warn
**重要**
**セキュリティ上の理由から、次の手順にすぐに進まない場合は、Apache ウェブサーバー (httpd) を直ちに停止してください。** インストールを Apache ドキュメントルートの下に移動すると、 WordPress インストールスクリプトは保護されず、Apache ウェブサーバーが実行されていれば攻撃者がブログにアクセスできる可能性があります。**Apache ウェブサーバーを停止するには、$ `sudo systemctl stop httpd` コマンドを入力します。** 次の手順に移動する場合、Apache ウェブサーバーを停止する必要はありません。
:::

9, Apacheの`.htaccess`ファイルを上書きできるようにします。
`.htaccess`ファイルを上書きすることはAmazon Linux ではデフォルトで有効になっていません。
`/etc/httpd/conf/httpd.conf`ファイルをエディターで開き、
必ず`<Directory "/var/www/html">`セクション内の
`AllowOverride None`を**ALL**にします。
```console
$ sudo nano /etc/httpd/conf/httpd.conf
```
```conf:/etc/httpd/conf/httpd.conf
<Directory "/var/www/html">
    (中略)
    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride All

    (中略)
</Directory>
```
:::note warn
このファイルには複数の AllowOverride 行がありますが、必ず `<Directory "/var/www/html">` セクション内のみを変更してください。
:::

編集が終わりましたら、保存してエディタを終了してください。

10, （オプション）PHPグラフィック描画ライブラリをインストールします。
PHP-GDはWebページを描画する際に便利なツールです。このライブラリを使用すると、動的な画像の生成や、画像のサイズ変更、切り抜き、フィルタ適用、テキストの描画などが可能です。
```console
$ sudo dnf -y install php-gd
```

11, WordPressインストールスクリプトを実行します。
これでやっとWordPress をインストールする準備ができました。
ApacheとMariaDBの両サービスがブート時に起動するようになっているようにしてください。
また、両サービスを実行中にしてください。
```console
//ブート時に起動設定
$ sudo systemctl enable httpd && sudo systemctl enable mariadb

//実行中へ
$ sudo systemctl start mariadb httpd
```
ウェブブラウザで、 WordPress ブログの URL (インスタンスのパブリック DNS アドレス、またはそのアドレスの後に blogフォルダ) を入力して開きます。
```:ブラウザ
http://(ブログアドレス)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555422/a74b4509-945a-da32-5496-fb7b20c5cee6.png)

WordPress インストールに必要な情報を入力します。
後から変更可能と書いてあります。
| 設定 | 説明 |
|:-:|:-:|
| サイトのタイトル | ブログのタイトル |
| ユーザー名 | ログインするユーザー名を決めてください |
| パスワード | ログインするパスワードを決めてください |
| メールアドレス | e-mailアドレス |
| 検索エンジンでの表示 | 検索エンジンをブロックするならチェック |

**WordPress をインストール** でインストールを完了します。
<br>


これにてブログ開設完了です！！
おつかれさまでした！