CentOS7にDrupal 8.2.4をゼロからセットアップする(Nginx + PHP7.1 + MariaDB)

この記事ではまっさらなCentOS 7.3(正確にはCentOS Linux release 7.3.1611 (Core))をベースに、Drupal 8.2.4を安全にセットアップする手順を紹介します。なお、サーバ自体はさくらのクラウドを使っています。

さくらのクラウド

基本的な手順

手順は次のようになります。

  1. ライブラリの更新
  2. ユーザの作成
  3. SSHログインの設定
  4. 必要なソフトウェアのインストール
  5. MariaDBのセットアップ
  6. Nginxの設定
  7. PHP7.1のインストール
  8. Nginxの設定変更
  9. Drupalのダウンロード
  10. サーバ設定の変更
  11. 管理画面の設定

1. ライブラリの更新

サーバが起動したら、まずSSHでログインします。今回のサーバのIPアドレスは 133.242.99.99 とします。最初はrootでしかログインできません。

ssh root@133.242.99.99

そして既存パッケージをアップデートします。

# yum -y update

デフォルトではCentOS 7.2ですが、Yumでアップデートすると7.3になるようです。

2. ユーザの作成

次に作業するユーザを作成し、続けてパスワードを設定します。

# adduser app
# passwd app

作業する際に便利な sudo を設定します。

# visudo

具体的には 下記の行を追加します。

app      ALL=(ALL)       ALL

後は app ユーザになって、sudo が使えれば大丈夫です。

$ sudo su - # rootアカウントになります

We trust you have received the usual lecture from the local System
  :
[sudo] password for app: 
Last login: Thu Dec 22 21:11:41 JST 2016 from h999-999-9-999.yyyyy.xxxx.jp on pts/0

3. SSHログインの設定

作成したユーザでSSHログインできるようにします。CentOSはデフォルトで公開鍵認証に対応していますので、ローカルパソコン側で公開鍵を用意しておきます。

最初に app ユーザで公開鍵、秘密鍵を作成します。

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/app/.ssh/id_rsa): 
  :
|              o+ |
+-----------------+

続いて ~/.ssh/authorized_keys に対してローカルコンピュータの公開鍵を追加します。以下のような形です。

$ cat ~/.ssh/authorized_keys 
ssh-rsa AAA...w== nakatsugawa@macpro.local

ファイルは読み込みを制限します。

$ chmod 400 ~/.ssh/authorized_keys 

これで準備完了です。作成したユーザ(今回はapp)でローカルコンピュータからSSH接続できるか確認します。

$ ssh app@133.242.99.99

ログインできたら、次はrootアカウントでのSSHログインを禁止します。rootで外部からログインできるのはセキュリティリスクになるからです。まず /etc/ssh/sshd_config をバックアップしておき、編集します。

$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org
$ sudo vi /etc/ssh/sshd_config

編集する箇所は PermitRootLogin をアンコメントし、Noを設定します。

$ sudo diff /etc/ssh/sshd_config /etc/ssh/sshd_config.org
49c49
< PermitRootLogin No # <- 新しい設定
---
> #PermitRootLogin yes  <- 元の設定

設定が終わったら、念のためSSHの設定をテストします。

$ sudo sshd -t

エラーがなかったらサービスを再起動します。

$ sudo systemctl restart sshd

再起動したら、rootユーザでSSHログインしようとしてエラーになることを確認します。

$ ssh root@133.242.99.99
root@133.242.99.99's password: 
Permission denied, please try again.

4. 必要なソフトウェアのインストール

Drupalに必要なのは主に次のソフトウェアです。

  • MySQL(CentOS 7の場合はMariaDB)
  • Nginx もしくはApache
  • PHP

これらをそれぞれインストールします。まずMariaDBをインストールします。

$ sudo yum -y install mariadb mariadb-server

インストールが終わったら起動します。

$ sudo systemctl start  mariadb
$ sudo systemctl enable mariadb

起動した確認します。

$ ps aux | grep mariadb
mysql    27222  0.7  8.0 902788 81492 ?        Sl   21:30   0:00 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariad/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock

5. MariaDBのセットアップ

MariaDBが起動したらセットアップを行いますが、mysql_secure_installation というコマンドが用意されていますのでこれを使います。このコマンドを使えば不要な設定を削除してくれます。

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

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

Set root password? [Y/n] Y
New password: 
Re-enter new password: 
Password updated successfully!
Reloading privilege tables..
 ... Success!
  : 匿名ユーザを削除します
Remove anonymous users? [Y/n] Y
 ... Success!
  : rootがリモートからログインできないようにします
Disallow root login remotely? [Y/n] Y
 ... Success!
  : テストデータベースの削除確認です
Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!
  : 権限を再読込します
Reload privilege tables now? [Y/n] Y
 ... Success!
  : 
Thanks for using MariaDB!

これで、より安全に運用できるようになりました。さらにデフォルトの文字コードなどを設定します。

$ sudo cat /etc/my.cnf.d/server.cnf
  :
[mysqld]
character-set-server=utf8 # 追加

設定を記述したらMariaDBを再起動します。

$ sudo systemctl restart mariadb

次にデータベースユーザと、データベースを作成します。

$ mysql -uroot -p
Enter password: 
  : データベースを作成します
MariaDB [(none)]> create database drupal;
Query OK, 1 row affected (0.00 sec)
  : ユーザを作成します
MariaDB [(none)]> grant all privileges on drupal.* to 'drupal'@'localhost' identified by 'xxxxxxxx';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)

ここまででデータベースの設定は完了です。

6. Nginxの設定

次はNginxの設定です。インストールするために、まずnginxのレポジトリを追加します。

$ sudo yum install http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm

レポジトリの追加後、nginxをインストールします。

$ sudo yum install nginx

インストールが終わったら一度起動してみます。

$ sudo systemctl start nginx
$ sudo systemctl enable nginx # 起動時のサービスに登録

起動した後、そのままではファイアウォールの設定により、Webブラウザからアクセスできません。そこでHTTP/HTTPSからのアクセスを許可します(via CentOS7のhttpd設定で詰まった点 - Qiita)。

$ sudo firewall-cmd --permanent --zone=public --add-service=http
success
$ sudo firewall-cmd --permanent --zone=public --add-service=https
success
$ sudo firewall-cmd --reload
success

これでWebブラウザからアクセスできるようになります。Webブラウザから http://(サーバのIPアドレス)/ にアクセスしてみましょう。次の画像のように表示されれば問題ありません。

Nginxの初期表示画面

7. PHP7.1のインストール

では最後にPHP7.1をインストールします。標準のYumリポジトリではPHP5.4までしかインストールできませんので、Remiを追加します。

$ sudo yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

これで準備は整ったので、PHP7.1系をインストールします。

$ sudo yum install --enablerepo=remi-php71 php
$ sudo yum install --enablerepo=remi-php71 php-mysqlnd # MySQLドライバのインストール
$ sudo yum install --enablerepo=remi-php71 php-php-fpm   # PHP-FPMのインストール

PHP7からApache用のモジュールなどはインストールされなくなっています。PHP-FPM(FastCGI Process Manager)を用いてApacheやNginxといったHTTPサーバと連携します。そこで、PHP-FPMの設定を行います。

$ sudo vi /etc/php-fpm.d/www.conf

設定する箇所としては次の通りです。今回はNginxとsockファイルで連携するのでそのパスと、そのファイルを読む権限を持ったユーザ/グループを指定(今回はnginx)します。また、PHP-FPM自体のユーザ/グループ(今回はapp)も指定します。

; 実行ユーザ
user = nginx
group = nginx

; sockファイルのパス
listen = /var/run/php-fpm/php-fpm.sock

; sockファイルを読み取るユーザ/グループ
listen.owner = nginx
listen.group = nginx

そしてPHP-FPMを起動します。

$ sudo systemctl start php-fpm

うまくいっていれば次のようにプロセスが確認できます。

$ ps aux | grep fpm
root     28097  0.2  0.8 161736  8640 ?        Ss   19:18   0:00 php-fpm: master process (/etc/opt/remi/php71/php-fpm.conf)
app      28098  0.0  0.3 161736  3840 ?        S    19:18   0:00 php-fpm: pool www
app      28099  0.0  0.3 161736  3840 ?        S    19:18   0:00 php-fpm: pool www

8. Nginxの設定変更

PHP-FPMに合わせてNginxの設定を変更します。ファイルは /etc/nginx/conf.d/default.conf になります。

server {
    root   /var/www/drupal;

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Very rarely should these ever be accessed outside of your lan
    location ~* \.(txt|log)$ {
        allow 192.168.0.0/16;
        deny all;
    }

    location ~ \..*/.*\.php$ {
        return 403;
    }

    location ~ ^/sites/.*/private/ {
        return 403;
    }

    # Allow "Well-Known URIs" as per RFC 5785
    location ~* ^/.well-known/ {
        allow all;
    }

    # Block access to "hidden" files and directories whose names begin with a
    # period. This includes directories used by version control systems such
    # as Subversion or Git to store control files.
    location ~ (^|/)\. {
        return 403;
    }

    location / {
        # try_files $uri @rewrite; # For Drupal <= 6
        try_files $uri /index.php?$query_string; # For Drupal >= 7
    }

    location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;
    }

    # Don't allow direct access to PHP files in the vendor directory.
    location ~ /vendor/.*\.php$ {
        deny all;
        return 404;
    }

    # In Drupal 8, we must also match new paths where the '.php' appears in
    # the middle, such as update.php/selection. The rule we use is strict,
    # and only allows this pattern with the update.php front controller.
    # This allows legacy path aliases in the form of
    # blog/index.php/legacy-path to continue to route to Drupal nodes. If
    # you do not have any paths like that, then you might prefer to use a
    # laxer rule, such as:
    #   location ~ \.php(/|$) {
    # The laxer rule will continue to work if Drupal uses this new URL
    # pattern with front controllers other than update.php in a future
    # release.
    location ~ '\.php$|^/update.php' {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        # Security note: If you're running a version of PHP older than the
        # latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
        # See http://serverfault.com/q/627903/94922 for details.
        include fastcgi_params;
        # Block httpoxy attacks. See https://httpoxy.org/.
        fastcgi_param HTTP_PROXY "";
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_intercept_errors on;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
    }

    # Fighting with Styles? This little gem is amazing.
    # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
    location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
        try_files $uri @rewrite;
    }

    # Handle private files through Drupal. Private file's path can come
    # with a language prefix.
    location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
        try_files $uri /index.php?$query_string;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

これで準備は完了です。

9. Drupalのダウンロード

ではついにDrupalをダウンロードします。今回は Nginx のデフォルトルートである /var/www/drupal にセットアップします。バージョンは執筆時点での最新版である8.2.4をインストールします。

$ cd /tmp
$ curl https://ftp.drupal.org/files/projects/drupal-8.2.4.tar.gz | tar zx
$ sudo mv drupal-8.2.4 /var/www/drupal
$ sudo chown -R nginx:nginx /var/www/drupal

ここでnginxを再起動します。

$ sudo systemctl restart nginx

ここまで終わったら http://(サーバのアドレス)/ にアクセスしてみましょう。

バージョンが古いと言われたら…

Drupalにアクセスすると、次のようなエラーメッセージが出ることがあります。内容としてはPHPのバージョンが古いということです。CentOS7デフォルトのPHPは5.4系のためです。

Your PHP installation is too old. Drupal requires at least PHP 5.5.9. See the system requirements page for more information.

バージョンが古い場合のエラー

これを改善するには既存のPHPを削除し、7. PHP7.1のインストール に沿って新しいPHP(5.6以降)をインストールする必要があります。そこでまず既存のPHPを削除します。

$ sudo yum remove php
$ sudo yum remove php-mysql

10. サーバ設定の変更

問題がなければインストールウィザードが開始します。

Drupalのインストールウィザード

進めていくと、必須条件の検証のところで細かくエラーや警告が出ているので修正していきます。

インストール中のエラー

PHP拡張のインストール

PHP拡張でのエラーが出ていますので、追加で次のライブラリをインストールします。これもインストールが終わったらPHP-FPMを再起動します。

$ sudo yum install --enablerepo=remi-php71 php-gd php-xml
$ sudo systemctl restart php-fpm

PHP OPcodeのキャッシング

次にサイトパフォーマンス向上のためにキャッシングを有効にします。次のライブラリをインストールして、PHP-FPMを再起動します(via CentOS7 に 旧 APC (apcu & opcache)を導入する - Qiita)。

$ sudo yum install --enablerepo=remi-php71 php-opcache
$ sudo systemctl restart php-fpm

ここまでの手順でインストールは問題なく完了するはずです。後はパスワードやメールアドレスを設定して進めていきます。

パスワード設定など

再度セットアップを行う場合は…

Drupalインストール済み

インストール中にエラーが出た場合には次の手順で再インストールを行えます。default.settings.phpをsettings.phpにコピーします。

cp /var/www/drupal/sites/default/default.settings.php /var/www/drupal/sites/default/settings.php

次にデータベースを作成し直します。

$ mysql -uroot -p
Enter password: 
  :
> drop database drupal;
> create database drupal;

後は再度WebブラウザでDrupalにアクセスしてインストールを再開してください。

11. 管理画面の設定

次にサイトの状態を見ると、幾つかの問題点が出ているようです。それらを改善します。

サイトの状態

アップロード進捗状況

PECL uploadprogressの利用が推奨されています。これは次のコマンドでインストールできます。インストールしたらPHP-FPMを再起動します。

$ sudo yum install --enablerepo=remi-php71 php-pecl-uploadprogress
$ sudo systemctl restart php-fpm

信頼の置けるホストの設定

最後に信頼のおけるホストの設定を行います。これは /var/www/drupal/sites/default/settings.php の中に次のような記述をします。数字の部分は皆さんのドメインであったり、IPアドレスに書き換えてください。記述は正規表現で行う必要がありますが、基本的には最初に^を記述して、.(ドット)の前に \ をつけて、最後に$をつけると言う形になります。なお、settings.phpは読み込みのみ許可されていますので、一時的に書き込み権限を追加してください。

chmod 600 /var/www/drupal/sites/default/settings.php

とした上で編集します。

$settings['trusted_host_patterns'] = array(
  '^133\.242\.99\.99$',
);

編集後はファイルの権限を元に戻しておきます。

chmod 400 /var/www/drupal/sites/default/settings.php

修正後のサイトの状態

これでエラーや警告が消え、安全にDrupal 8.2.4が運用できる準備が整いました。慣れればすぐにできるようになると思いますが、この記事を参考にトライしてみてください。

Drupal - Open Source CMS | Drupal.org