ConoHaへWordPressをOPCache&APCu&SSLで移行と新規セットアップ

# ゴール
* Nginx + php + php-fpmの環境にする
* phpは7.2を使用する
* OpCacheとAPCuも有効化する。
* Let's Encryptで常時SSL化
* AWSからConoHaへ移行する
* データベースサーバをMySQLからMariaDBへ移行
* WebサーバをApacheからNginxへ変更

# 最初にすること
__旧サーバのWordPressを最新版にアップデートしておくこと__

# 作業
## ConoHaコントロールパネル
サーバを1台用意します。稼働中のサーバでも問題ないと思いますが、今回は、1Gプランを契約しました。

## SSHログイン
rootユーザーを無効化しサービスの設定を適用

```conf:/etc/ssh/sshd_config
PermitRootLogin no
```

```console
systemctl reload sshd.service
```

## ユーザー作成

```console
useradd hogehoge
passwd hogehoge
usermod -aG wheel hogehoge
```

* ユーザー作成後、別ターミナルで、rootログインができないことを確認
* 作成したユーザーでログインしてsudosできることを確認 (システムパッケージのアップデートあたりを実行すると良いかも)
* 以降は、一般ユーザーで作業を想定

## システムパッケージのアップデート
```console
sudo yum -y update
```
## Firewallの設定

```console
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload
```

## 各種リポジトリの追加
```console
sudo yum install epel-release
sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
sudo rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

リポジトリが初期のyumとかぶるのは避けたいので、enableを0に設定する。

```conf:/etc/yum.repos.d/epel.repo
[epel]
name=Extra Packages for Enterprise Linux 7 - $basearch
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch
failovermethod=priority
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7

[epel-debuginfo]
name=Extra Packages for Enterprise Linux 7 - $basearch - Debug
#baseurl=http://download.fedoraproject.org/pub/epel/7/$basearch/debug
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$b$
failovermethod=priority
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1

[epel-source]
name=Extra Packages for Enterprise Linux 7 - $basearch - Source
#baseurl=http://download.fedoraproject.org/pub/epel/7/SRPMS
mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$$
failovermethod=priority
enable=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
gpgcheck=1
```

MariaDBのリポジトリを追加

```conf:/etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
enable=0
```

## パッケージインストール
必要なパッケージのインストール

> httpdもインストールされますが今回は不使用です。

```console
sudo yum install -y --enablerepo=epel,remi,remi-php72,mariadb nginx php-fpm mariadb mariadb-server mariadb-client php php-mbstring php-mysql php-gd php-opcache php-pecl-apcu
```

## バージョンの確認
__この項目はスキップしても問題ありません__
2017/12/12現在

```console
nginx -v
```

> nginx version: nginx/1.12.2

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

> MariaDB-compat-10.2.11-1.el7.centos.x86_64
> MariaDB-common-10.2.11-1.el7.centos.x86_64
> MariaDB-server-10.2.11-1.el7.centos.x86_64
> MariaDB-client-10.2.11-1.el7.centos.x86_64

```console
php -v
```

> PHP 7.2.0 (cli) (built: Nov 28 2017 20:22:21) ( NTS )
> Copyright (c) 1997-2017 The PHP Group
> Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
>     with Zend OPcache v7.2.0, Copyright (c) 1999-2017, by Zend Technologies
> 
> __ここでのポイントはwith Zend OPcache v7.1.12が入っていること__


```console
php-fpm -v
```

> PHP 7.2.0 (fpm-fcgi) (built: Nov 28 2017 20:24:40)
> Copyright (c) 1997-2017 The PHP Group
> Zend Engine v3.2.0, Copyright (c) 1998-2017 Zend Technologies
>    with Zend OPcache v7.2.0, Copyright (c) 1999-2017, by Zend Technologies
>
> __ここでのポイントはwith Zend OPcache v7.1.12が入っていること__

## OPCacheの設定
だいたい以下のようなら設定にしておきましょう
__コメントは残したほうが無難(なぜか有効化されない場合がある？)__

```conf:/etc/php.d/10-opcache.ini
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1
```

## PHPの設定
独自テーマのインストールも考えて、php.iniのファイルアップロードサイズを変更しておきます。
Nginxは、このあと100MBで設定しますが、余裕を持って今回は、200MBで設定しておきます。

```conf:/etc/php.ini
upload_max_filesize = 200M
```

## php-fpmの設定

初期状態では、実行ユーザーがapacheになるため、nginxに変更

```conf:/etc/php-fpm.d/www.conf
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache Choosed to be able to access some dir as httpd
user = nginx
; RPM: Keep a group allowed to write in log dir.
group = nginx

```

## WordPressの設置
今回は、/user/share/nginx/www.example.comに設置することを想定しています。
WordPressは[こちら](https://ja.wordpress.org/download/)からダウンロードURLを取得してください。
2017/12/12現在は、4.9.1が最新版でした。
__まずはSSL化の前にhttpで設定します__

```console
cd /usr/share/nginx/
sudo wget https://ja.wordpress.org/wordpress-4.9.1-ja.zip
sudo unzip wordpress-4.9.1-ja.zip
sudo mv wordpress www.example.com
sudo rm wordpress-4.9.1-ja.zip
```

```conf:/etc/nginx/conf.d/www.example.com.conf
server {
  listen 80;
  server_name www.example.com;

  root /usr/share/nginx/www.example.com;

  client_max_body_size 100m;

  location / {
    index  index.html index.htm index.php;
    try_files $uri $uri/ /index.php?q=$uri&$args;
  }

  location ~* /wp-config.php {
    deny all;
  }

  location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    include fastcgi_params;
  }
}

```

## NginxのConfigテスト
```console
sudo nginx -t
```

> nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
> nginx: configuration file /etc/nginx/nginx.conf test is successful

## wp-contentフォルダの移行
旧サーバからwp-contentフォルダをSFTPか何かで、新サーバへ移動させます。
wp-contentを上書き。

## WordPressのオーナーとパーミッションの変更
自動更新できるようにパーミッションを設定します。

```console
sudo chown -R nginx:nginx /usr/share/nginx/www.example.com/
sudo find /usr/share/nginx/www.example.com -type d -exec chmod 705 {} \;
sudo find /usr/share/nginx/www.example.com -type f -exec chmod 604 {} \;
```

## FS_METHODを設定
WordPressの更新やプラグインのインストールをFTPやSFTP経由でなく直接更新できるようにします。
詳細は、[WordPress FTPなしでプラグインダウンロードできる設定](https://qiita.com/mzdakr/items/41d64e5d79557b8de6ef)の記事を参考にしてください。
__今回は、移行のため、前回の設定ファイルをそのまま流用するため、設定は省きます__

wp-config.phpのパーミッションを変更しておきます。

```console
sudo chmod 600 /usr/share/nginx/www.example.com/wp-config.php
```

## 各種デーモンの起動

```console
sudo systemctl enable nginx.service
sudo systemctl enable php-fpm.service
sudo systemctl enable mariadb.service
sudo systemctl start nginx.service
sudo systemctl start php-fpm.service
sudo systemctl start mariadb.service
```

# MariaDBの初期設定

ウィザードに従って入力していきます。

```console
sudo mysql_secure_installation
```

|表示|説明|
|:---:|:---:|
|Enter current password for root (enter for none):|MariaDBの現在のrootユーザパスワード入力(初期設定時は何も設定されていない)|
|Set root password? [Y/n]|rootユーザのパスワードを設定するかどうか|
|Remove anonymous users? [Y/n]|初期設定で作成されている「anonymous」ユーザを削除するか|
|Disallow root login remotely? [Y/n]|MariaDBの「root」ユーザのリモートログインを禁止するか|
|Remove test database and access to it? [Y/n]|初期設定で作成されている「test」データベースを削除するか|
|Reload privilege tables now? [Y/n]|今設定したユーザ設定をすぐに反映させるか|

## WordPressで使用するユーザーの作成

```console
mysql -u root -p
```

```sql:sql
create database データベース名 character set utf8;
create user 'ユーザー名'@'localhost' identified by 'パスワード';
grant all privileges on データベース名.* to 'ユーザー名'@'localhost';
exit;
```

# 移行の作業
## 旧MySQLからsqldump
データを取り出し、取り出したデータをSFTPか何かで、新サーバへ移動させます。

```console
mysqldump -u root -p 移行前のデータベース名 > ダンプファイル名
```

## 新MariaDBへデータの復元

```console
mysql -u ユーザ名 -p 移行先のデータベース名 < ダンプファイル名
```

# SSL化

## Certbotのインストール

```console
sudo yum -y install --enablerepo=epel certbot
```

## Diffie-Hellman パラメータを生成
```console
sudo mkdir /etc/ssl/private/
sudo openssl dhparam -out /etc/ssl/private/dhparam.pem 2048
```

## SSL証明書取得

```console
sudo certbot certonly --webroot -w /usr/share/nginx/www.example.com -d www.example.com
```

## SSL証明書の自動更新

```console
sudo crontab -e
```

```shell:crontab
0 0 * * * /bin/certbot renew && /bin/systemctl reload nginx.service
```

## NginxのSSL設定

```conf:/etc/nginx/conf.d/www.example.com.conf
server {
    listen 80;
    server_name www.example.com;
    return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name www.example.com;

  root /usr/share/nginx/www.example.com;

  client_max_body_size 100m;

  ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;

  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets on;

  ssl_dhparam /etc/ssl/private/dhparam.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK";
  ssl_prefer_server_ciphers on;

  add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';

  location / {
    index  index.html index.htm index.php;
    try_files $uri $uri/ /index.php?q=$uri&$args;
  }

  location ~* /wp-config.php {
    deny all;
  }

  location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_script_name;
    include fastcgi_params;
  }
}

```