Wordpress用CentOS7.7+Nginx+PHP-FPM+MariaDBの構築

##WordPress用のWebサーバーを構築してみる

まっさらなVPSからNginxとPHP-FPMとMariaDBを使ったWordPress用のWebサーバーを作ってみました。

今使っているConoHaVPSでは、Nginx+MariaDBのイメージがあるのではじめから作成することができますが、基本を習得するためにベーシックなサーバー構築にチャレンジしました。

###ConoHaVPSのスペック

|項目|スペック|
|:---|-----:|
|メモリ|512MB|
|CPU|1コア|
|SSD|20GB|
|初期費用|無料|
|料金|630円/月|

ApacheだとWordPressを動かすには厳しいスペックですが、Nginxだと大丈夫。

##前提

- サーバー構築の初心者向けです。
- sshでリモートログインできること。
- Linuxの簡単なコマンドは分かること

##導入するアプリ
|アプリ|バージョン|
|---|---|
|OS|CentOS Linux release 7.7.1908 (Core)|
|Nginx|nginx/1.16.1|
|PHP-FPM|php7.3-fpm|
|Database|MariaDB 10.4.10|

#OSの確認とアップデート

```
# less /etc/redhat-release
```

```/etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
```

パッケージをアップデート

```
# yum -y update
```

##Nginxのインストールと設定

yumでinstall

```
# yum -y install nginx
```

バージョン確認

```
# nginx -v
nginx version: nginx/1.16.1
```

###Ningxの設定

後ほどSSL対応にしますが、まずは非SSL（80番ポート）で見られるWebサーバーを公開する必要があります。

他のサイトも追加していけるようにバーチャルホスト毎にコンフィグファイルを分けた方がいいです。
/etc/nginx/conf.d/以下のファイルは.confをつければ自動的にNginxのコンフィグファイルとして読み込まれます。

ファイルを新規作成して、下記のコンフィグを追加します。

```/etc/nginx/conf.d/hostname.com.conf
server {

        listen 80;
        server_name hostname.com;
        root /var/www/hostname.com/htdocs/;

        location / {
                index index.php index.html;
        }
}
```

listen: 80番ポート（HTTP）でのアクセスを受け入れる設定
server_name: サイトアクセスするドメインをいれる。
root: ドキュメントルールの指定で、ディレクトリは後ほど作成
index: index.phpとindex.htmlをindexファイルとして認識

###ルートディレクトリ作成

ログファイルとhtmlのドキュメントルートを作成します。

```
# mkdir -p /var/www/hostname.com/{htdocs|log/nginx}
/var/www/hostname.com/
　└htdocs/
　└log/
　　└nginx

#cd /var/www/hostname.com/
```

所有者を変更。
SFTPでアクセスするためのユーザーを指定するといいでしょう。

```
# chown username.username -R htdocs log
```

ログファイルの書き込みを許可する

```
# chmod -R 757 log/
```

###Nginxを起動とテスト

NginxのOS起動時自動起動設定とスタート

```
# systemctl enable nginx && systemctl start nginx
```

Firewallのhttpポートを公開する

```
# firewall-cmd --add-service=http --zone=public --permanent && firewall-cmd --reload
successと出たらOK
```

####Nginxの動作テスト

簡単なHTMLファイルがあるのでコピー。

```
# cp /usr/share/nginx/html/index.html /var/www/hostname.com/htdocs/
```

ブラウザで、`hostname.com`など設定したドメインでアクセスして、
Welcome to nginx on Red Hat Enterprise Linux!
と表示されたらOK
![FireShot Capture 078 - Test Page for the Nginx HTTP Server on Red Hat Enterprise Linux - eigo.press.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434973/31414c1e-8841-0556-a971-ae26d1faf90e.png)

# PHPのインストールと設定

## PHPのインストール

CentOS7にはphp7のリポジトリが標準で入っていないので、php7のリポジトリをインストールする。

```
# yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

###yumユーティリティのインストール

```
# yum install yum-utils
# yum-config-manager --enable remi
```

###ここではPHP7.3で必要なパッケージをインストールする

php73: PHP 7.3の基本パッケージ
php73-php-fpm: FastCGIのパッケージ
php73-php-mbstring: マルチバイト文字を取り扱うパッケージ
php73-php-pdo: データ取扱用パッケージ
php73-php-mysqlnd: MySQLに接続するために必要なパッケージ

```
# yum install php73 php73-php-fpm php73-php-mbstring php73-php-pdo php73-php-mysqlnd
```

PHP-FPM（FastCGI）の設定を変更。nginxで動かす設定に変更する。

```/etc/opt/remi/php73/php-fpm.d/www.conf
;user = apache を変更
user = nginx

;group = apache を変更
group = nginx

;listen = 127.0.0.1:9000
listen = /var/run/php73-php-fpm/www.sock

;listen.owner = nobody
listen.owner = nginx
;listen.group = nobody
listen.group = nginx
```

お決まりのコンフィグテスト

```
# /opt/remi/php73/root/usr/sbin/php-fpm -t
```

### PHP-FPMのためのUNIXソケットディレクトリを作成する
PHP-FPMの実行ユーザーがnginxのため、root所有の`/var/run/`ディレクトリにはソケットができない。

```
# mkdir /var/run/php73-php-fpm && chown nginx:nginx /var/run/php73-php-fpm
```

ソケットの設定ファイルを作成

```
# vi /etc/tmpfiles.d/php73-php-fpm
```

```
d /var/run/php73-php-fpm 0755 nginx nginx
```

PHP-FPMの再起動

```
# systemctl start php73-php-fpm
```

#nginx+PHP-FPMの連携
いよいよ、nginxにアクセスがあった.phpファイルの処理をPHP-FPMに渡す連携を設定します。別ポートを作成して渡す方法もありますが、同一サーバーのため今回はUNIXソケット方式で行います。

```/etc/nginx/conf.d/hostname.com.conf
location / {の下に追加
        location ~ .\.php$ {
                root /var/www/eigo.press/htdocs/;
                fastcgi_pass unix:/var/run/php73-php-fpm/www.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
```

nginx 再起動

```
# systemctl restart nginx
```

##テスト用のphpを作成

```
# rm -rf /var/www/eigo.press/htdocs/index.html
# echo "<?php phpinfo();" >> /var/www/eigo.press/htdocs/index.php
```

`hostname.com`にアクセスして、正常に表示されればOK。


---

#Let’s Encryptによる無料HTTPS化

##Let’s Encrypt certbotのインストール の設定
Let's EncryptのSSL証明書取得や自動更新をしてくれる`certbot`をインストールします。

```
# yum install certbot python2-certbot-nginx
```

Webroot方式（nginxのwebサーバーにアクセスして認証を取る方法）により証明書を取得します。

```
# certbot certonly --webroot -w /var/www/hostname.com/htdocs/ -d hostname.com --agree-tos -m [メアド@hostname.com]

Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Nginx Web Server plugin (nginx)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 1 #Nginxサーバーを利用
Plugins selected: Authenticator nginx, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): hosting@hostname.com #メールアドレス
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A #規約に同意しますか=>同意(A)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing 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: N #メルマガを受け取るか=>いいえ(N)
Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): eigo.press
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for eigo.press
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/eigo.press/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/eigo.press/privkey.pem
   Your cert will expire on 2020-02-08. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

```

###自動更新設定
crontabを使う人もいますが、certbot-renewというデーモンを使えば、証明書が切れる前に自動的に更新してくれます。

```
# systemctl enable --now certbot-renew.timer
```

##NginxのSSL設定

###DH 鍵交換用の鍵を作っておきます

```
# mkdir /etc/nginx/ssl
# cd /etc/nginx/ssl
# openssl dhparam 2048 -out dhparam.pem
```

#Nginxの設定変更
Nginxのconfigファイルを下記に書き換えます。

```/etc/nginx/conf.d/hostname.com.conf
server {
        listen 80;
        server_name hostname;
        rewrite ^ https://$server_name$request_uri? permanent; #HTTPでアクセスした場合は強制的にHTTPSにリダイレクト
}

server {

        listen 443 ssl;
        server_name hostname.com;
        access_log /var/www/hostname/log/nginx/ssl_access_log;
        error_log /var/www/hostname.com/log/nginx/ssl_error_log;
        root /var/www/hostname.com/htdocs/;

        #SSL関連の設定
        ssl_certificate /etc/letsencrypt/live/hostname.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/hostname.com/privkey.pem;
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_session_tickets on;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;

        #indexファイルの指定
        location / {
                index index.php index.html;
        }

        #PHPファイルの取扱設定
        location ~ .\.php$ {
                root /var/www/hostname.com/htdocs/;
                fastcgi_pass unix:/run/php73-php-fpm/www.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
}
```

#ファイヤーウォールのSSL（443）ポートを公開

```
# firewall-cmd --add-service=https --zone=public --permanent && firewall-cmd --reload
successと出たらOK
```

#MariaDBのインストール

古いのでインストール済みパッケージを削除

```
# rpm -qa | grep -i mariadb
```

yumリポジトリをインストール

```
# curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash
# yum install MariaDB-server MariaDB-client
```

MariaDBの起動とシステム起動時の自動起動設定

```
# systemctl enable mariadb && systemctl start mariadb
```

MariaDBの初期設定。rootパスワードやセキュリティ設定の初期設定を行う。

```
# mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user. If you've just installed MariaDB, and
haven't set the root password yet, you should just press enter here.

Enter current password for root (enter for none): 
OK, successfully used password, moving on...

Setting the root password or using the unix_socket ensures that nobody
can log into the MariaDB root user without the proper authorisation.

You already have your root account protected, so you can safely answer 'n'.

Switch to unix_socket authentication [Y/n] n #とりあえずNoでOK
 ... skipping.

You already have your root account protected, so you can safely answer 'n'.

Change the root password? [Y/n] Y #MariaDBのrootパスワードは不明なので変更
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y #匿名ユーザーの削除
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y #リモートでのrootログインを不可
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y #テストデータベースの削除
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y #権限のテーブルをリロード
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
```

##ユーザーとデータベースの作成

wordpress用にユーザーとデーターベースを作成する。

```
# mysql -u root -p
> create database [DB名];
> grant all on [DB名].* to [USER名]@localhost identified by ‘パスワード’;
> flush privileges;
> exit;
```

#FTPの設定

wordpressのプラグイン更新用にFTPを導入。
Nginxでは、ApacheのsuEXECの用にディレクトリの所有者に切り替えて実行というのができないため、wordpressのプラグイン更新などは都度FTPでアクセスする必要があります。サーバー内でアクセスができる様にFTPを設定します。

通常のFTP（25番ポート）でアクセス可能ですが、firewallは空けてないので、外部からはアクセス不可。

```
# yum -y install vsftpd
# systemctl enable vsftpd && systemctl start vsftpd
```

#WordpressのためのNginx設定
Wordpressを動かすためのNginxのconfig変更です。

location / の部分と

##nginxの設定変更
```/etc/nginx/conf.d/hostname.com.conf
        #下記を書き換え
        location / {
                index index.php index.html;
                try_files $uri $uri/ /index.php?$args;
        }

        #下記を追加
        location ~* /wp-config.php {
                deny all;
        }

        location ~ .*\.(js|css|png|gif|jpg|jpeg|svg|ico) {
                access_log off;
        }
```

この後はワードプレスをダウンロードしてサイトにアクセスするとwordpressをインストール可能になります。