concrete5 (version 8)を CentOS8の環境に構築する①

# 概要

concrete5とは、オープンソースで現在でも開発が進められているCMS製品です。
githubでのcontributorたちの活動状況はこんな感じです。
<img width="732" alt="スクリーンショット 2020-03-04 19.58.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/33cbd2a0-ede9-4ff7-57ee-61b5011329fc.png">

2019年まではかなり活発で、2020年はまだそこまででも無いですが、
安定してそれなりの頻度で開発されていることは分かります。

とあることからconcrete5について知る機会があり、せっかくなので自分で触ってみようと思ったので、
まずはその環境を用意するところからやることにしました。

やるからには最新バージョンで取り揃えたいので、まずはその環境構築から始めます。

# 環境情報

今回の環境構築にあたって必要となる主な製品とバージョンです。

- Vagrant 2.2.7
- VirtualBox 6.1
- CentOS 8.1
- Nginx 1.17.8
- PHP 7.4.3
- MySQL 8.0.17


# まずはCentOS 8.1の環境を立ち上げるところから

Vagrantのカレントディレクトリ配下は以下のファイルを用意。

```shell-session
.
├── Vagrantfile
└── provision.sh
```

各ファイルはこんな感じです。
Vagrantfileの`config.vm.box_url`がややこしいことになっているのは、VagrantのCentOS8のイメージがちょっとアレなんで、それを解消するために設定しています。
詳しくは以下を参考にして下さい。
[VagrantでCentOS8を起動すると「Error: Unknown repo: 'C*-base'」のエラーが出る](https://qiita.com/You_name_is_YU/items/a7e2ca82ba48faee8e97)

```config:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "centos/8"
  config.vm.box_url = "http://cloud.centos.org/centos/8/x86_64/images/CentOS-8-Vagrant-8.1.1911-20200113.3.x86_64.vagrant-virtualbox.box"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
  end
  config.vm.provision :shell, :path => "./provision.sh", :privileged => true
end
```

```shell:provision.sh
#!/bin/sh

systemctl stop firewalld
systemctl disable firewalld

timedatectl set-timezone Asia/Tokyo
localectl set-locale LANG=ja_JP.UTF-8
source /etc/locale.conf

# langpacks-jaは以下のエラーが出るため必要となるパッケージ
# default: Failed to set locale, defaulting to C
dnf install -y langpacks-ja
dnf install -y vim
dnf -y update
```

各ファイルの定義が完了したら、Vagrantを起動してCentOS8に接続します。

```shell-session
vagrant up

vagrant ssh

# 面倒なので root で作業します
sudo su -

cat /etc/redhat-release
CentOS Linux release 8.1.1911 (Core) 
```

とりあえず、CentOS8.1の環境にアクセスできるところまで確認できました。

# Nginx 1.17の構築

```shell-session
# Nginx公式のMainlineを利用するためリポジトリを定義（AppStreamを利用しない）
cat << EOF > /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
EOF

# CentOS8のAppStreamを無効にして公式のNginxリポジトリからインストール
dnf --disablerepo=AppStream -y install nginx

nginx -v
nginx version: nginx/1.17.8

systemctl enable nginx
systemctl start nginx
```

ここまでできたら以下のURLにアクセスする。

http://192.168.33.10/
Welcome to nginx!のページが表示されたらOK

# PHP-FPM 7.4の構
築

```shell
dnf module reset php
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm
dnf module install -y php:remi-7.4

which php
/usr/bin/php

php -v
PHP 7.4.3 (cli) (built: Feb 18 2020 11:53:05) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

php-fpm -v
PHP 7.4.3 (fpm-fcgi) (built: Feb 18 2020 11:53:05)
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
```

PHP7.4のインストールはこれで完了
あとは、Nginxとの繋ぎ込みの部分を設定。

```shell-session
cp -p /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.org
vim /etc/nginx/conf.d/default.conf
```

一応concrete5の環境構築をすることが目的なので、ドキュメントルートを`/var/www/concrete5`としている。

```config:default.conf
server {
  listen 80;
  server_name localhost;

  # ドキュメントルートの設定
  root /var/www/concrete5;
  index index.php index.html index.htm;

  location / {
    # 指定された順序でfileやdirの存在を確認し、最初に見つかったものを返却する。
    # いずれも無かった場合は、最後に指定されたパスに遷移する。
    try_files $uri $uri/ /index.php$is_args$args;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    # 1台のサーバーでnginx+php-fpmを動作させる場合、Unixソケットの方が高速に動作するため、
    # 以下の設定をする。
    fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_index  index.php;
    include        fastcgi_params;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO $fastcgi_path_info;
  }

  access_log /var/log/nginx/access.log;
  error_log  /var/log/nginx/error.log;
}
```

NginxとPHP-FPMを同一サーバーで動作させる場合、UNIXソケットで通信を行う。
UNIXソケットを利用する場合、php-fpmのwww.confの設定でnginxを利用するための設定をする必要がある。

```shell
cp -p /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.org
vim /etc/php-fpm.d/www.conf
```

```config:www.conf
;user = apache
;group = apache
user = root
group = root

;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

# UNIXドメインソケットを利用するため、その設定に合わせてlistenを修正
;listen = /run/php-fpm/www.sock
listen = /var/run/php-fpm/php-fpm.sock
```

設定が終わったら、php-fpmを自動起動にして、サービスを開始。
nginxも設定に変更があるためサービスを再起動しておく。

```shell-session
systemctl enable php-fpm
systemctl start php-fpm
systemctl stop nginx
systemctl start nginx
```

これでNginxとPHP-FPMの繋ぎ込みが完了したので、お決まりのphpinfoを表示できるか確認してみる。

```shell-session
vim /var/www/concrete5/index.php
```

```php:index.php
<?php
phpinfo();
```

ここまでの設定が完了したら以下のURLにアクセスしてPHPINFOが表示されることを確認する。
http://192.168.33.10

# MySQL 8.0.17の構築

MySQL 8.0.17はCentOS8 のAppStreamから簡単にインストールできる。
PHPからPDOを使ってMySQLに接続するため、MySQLサーバー製品以外に、php-mysqlndも合わせてインストールしておく。

```shell
dnf info mysql
Last metadata expiration check: 0:23:55 ago on 2020年03月04日 07時26分51秒.
Available Packages
Name         : mysql
Version      : 8.0.17
Release      : 3.module_el8.0.0+181+899d6349
Architecture : x86_64
Size         : 11 M
Source       : mysql-8.0.17-3.module_el8.0.0+181+899d6349.src.rpm
Repository   : AppStream
Summary      : MySQL client programs and shared libraries
URL          : http://www.mysql.com
License      : GPLv2 with exceptions and LGPLv2 and BSD
Description  : MySQL is a multi-user, multi-threaded SQL database server. MySQL is a
             : client/server implementation consisting of a server daemon (mysqld)
             : and many different client programs and libraries. The base package
             : contains the standard MySQL client programs and generic MySQL files.


dnf install @mysql:8.0
dnf install php-mysqlnd
mysql --version
mysql  Ver 8.0.17 for Linux on x86_64 (Source distribution)
```

インストールが完了したので、サービスを自動起動にして起動しておく。

```shell-session
systemctl enable mysqld
systemctl start mysqld
```

MySQLデータベースの初期設定を行う。（rootのパスワードとかとか）

```shell-session
mysql_secure_installation

Press y|Y for Yes, any other key for No: y
- VALIDATE PASSWORDを変更 -> y

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 0
- とりあえず開発なのでLOWで設定 -> 0

New password:（rootのパスワードを入力） -> mysqluser000
Re-enter new password:（rootのパスワードを再入力） mysqluser000

Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
- 設定したパスワードで続行 -> y

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
- 匿名ユーザーは不要 -> y

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
- rootでリモートログインはしない -> y

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y
- テスト用のデータベースは不要 -> y

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
- ここまでの設定を反映 -> y

```

concrete5では、MySQLデータベースの構築で以下を注意する必要があるらしい。

- 接続照合順序＝utf8_general_ci
- 文字コード＝utf8

参考：https://concrete5-japan.org/help/5-6/install/gettingready/

なので、そのあたりの設定をしていく。

```shell
vim /etc/my.cnf.d/charset.cnf
```
※utf8mb4は照合順序 utf8_general_ci を利用する場合、指定することができないので注意。

```config:charset.cnf
[mysqld]
character-set-server            = utf8
collation-server                = utf8_general_ci

[client]
loose-default-character-set     = utf8
```

設定を変更したので、MySQLのサービスを一度再起動。

```shell
systemctl stop mysqld
systemctl start mysqld
```

ここからはインストールしたMySQLにデータベースとユーザーとテーブルを作成します。
concrete5の環境構築として必須の作業ではありませんが、
Nginx 1.17.8 + PHP-FPM 7.4 + MySQL 8.0.17の環境がここまでの手順で
正常に構築できていることを確認するために行います。


```shell-session
mysql -u root -p
```

```shell-session
mysql> create database sample;
Query OK, 1 row affected (0.00 sec)

mysql> create user 'mysqluser'@'localhost' identified by 'MySQL00#$%';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on *.* to 'mysqluser'@'localhost' with grant option;
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit

mysql -u mysqluser -p

mysql> connect sample
Connection id:    15
Current database: sample

mysql> create table sample(id int, name varchar(10));
Query OK, 0 rows affected (0.02 sec)

mysql> insert into sample values(1, 'test01');
Query OK, 1 row affected (0.01 sec)

mysql> quit
```

データベース・ユーザー・テーブル・テーブルの初期データ登録まで完了したので、
PHPからMySQLデータベースに接続して、正常にデータが表示できるところまで確認します。

まずは、php.iniで扱う文字コードなどの設定を行います。
php.iniについてもいくつか設定の注意点があるようなので、公式からの指摘をちゃんと守って設定します。
参考：https://concrete5-japan.org/help/5-6/install/gettingready/

```shell
cp -p /etc/php.ini /etc/php.ini.org
vim /etc/php.ini
```

Vagrantで仮想環境なので、あんまりメモリ多くしてません。。。

```ini:php.ini
; デフォルト文字コード
default_charset = UTF-8
;HTTPのレスポンスにPHPのバージョン情報を出力するX-Powered-Byヘッダを含めない
expose_php = Off

;メモリ使用量の上限
memory_limit = 256M
;POSTリクエストのデータの最大サイズ
post_max_size = 128M
;ファイルをアップロードする際のアップロードファイルの最大サイズ
upload_max_filesize = 100M

; エラーログ
error_log = /var/log/php_error.log
; エラーを出力
error_reporting = E_ALL
; エラー表示
display_errors = On
display_startup_errors = On

[Date]
date.timezone = Asia/Tokyo

[mbstring]
;　mbstringのデフォルトの言語
mbstring.language = Japanese
;　HTTP入力文字のエンコーディングを内部文字のエンコーディングに自動変換しない
mbstring.encoding_translation = Off
;　文字コードを自動検出する際の優先順位
mbstring.detect_order = UTF-8,SJIS,EUC-JP,JIS,ASCII
; タイムゾーンを日本標準時間
date.timezone = Asia/Tokyo
; HTTPのレスポンスによりPHPのバージョン情報を非表示
expose_php = Off
```

phpinfoを表示するようにしていたindex.phpの内容を書き換えて、
MySQLデータベースに作成したテーブルのデータを取得して画面に表示することができるか確認する。

```shell-session
vim /var/www/concrete5/index.php
```

```php:index.php
<?php

$dsn = 'mysql:host=localhost;dbname=sample';
$user = 'mysqluser';
$password = 'MySQL00#$%';

try {
  $dbh = new PDO($dsn, $user, $password);

  $sql = "select * from sample";

  foreach ($dbh->query($sql, PDO::FETCH_ASSOC) as $row) {
    var_dump($row);
  }
} catch (PDOException $e) {
  var_dump($e);
}
```

以下のURLにアクセスして動作確認をする。
http://192.168.33.10

こんな内容が画面上に表示されていれば、正常に Nginx+PHP-FPM+MySQLの環境が構築できている。

```
array(2) { ["id"]=> string(1) "1" ["name"]=> string(6) "test01" }
```

とりあえず、concrete5の環境を構築するにあたり、事前に準備しておくひつようがありそうな部分まではできたと思います。