複数のウェブサイトを１つのVPS上に作るための環境作り（Apache + MySQL + PHP + WordPress / Ubuntu / Linode）

### 要約

Apacheのバーチャルホストで複数の異なるドメイン（マルチドメイン）のウェブサイトを１つのサーバー上に作る手順を説明します。Apache + MySQL + PHP + Wordpress / Ubuntu 16.04 LTS / Linode VPSの組み合わせで環境を構築します。


### 背景

ドメインの登録者はサブドメイン（*.example.com）を自由に決めて使うことができます。例えば、モバイル向けのサイトm.example.comや、英語で書かれたサイトen.example.comなどです。登録したドメインは１つでもサブドメインを複数個持つことができます。

それぞれのドメインのウェブサイトを作る度にサーバーを用意していたのでは、お金と労力がかかります。また、他のドメインtest.comで実験的にウェブサイトを作りたいなら、すでに運用しているサーバーを共用したいものです。

Apacheのバーチャルホスト（Name-based Virtual Host）の機能を使えば、複数の異なるドメイン（マルチドメイン）のウェブサイトを１つのサーバー上に作ることができます。


### 目的

ドメインexample.comを例にとって、２つのウェブサイト http://example.com/ と http://staging.example.com/  を１つのサーバー上に作るためのサーバーソフトウェアの環境を作ることが今回の目的です。さらに、ユーザーが http://www.example.com/  にアクセスしたら、
 http://example.com/  が表示されるようにします。example.comとwww.example.comは異なるドメインですが、ユーザーに同じウェブサイトとして見せるのです。読者のあなたはexample.com（１つ目のドメイン）、staging.example.com（２つ目のドメイン）をあなたのドメインに置き換えて下さい。


### 概要

この記事では、私がこの目的を達成するために行った具体的な手順を書きます。大まかな流れは次の通りです。

10. ドメインはお名前.comで登録しました。
20. サーバーは、LinodeのVPSを使います。
30. サーバーのOSは、Ubuntu 16.04 LTSをインストールします。
40. ログインユーザーの作成やSSHなどの設定をして最低限の使いやすさとセキュリティを確保します。
50. HTTPサーバーソフトウェアは、Apacheをインストールします。
60. Apacheのバーチャルホストの設定をして、複数サイトを同じサーバーに共存させます。
70. DNSレコードを設定して、サイトをオープンします。お名前.comが提供しているDNSサーバーを使います。
80. WordPressのためにデータベースソフトウェアのMySQLをインストールします。
90. WordPressのためにスクリプト言語のPHPをインストールします。
100. 最後にウェブサイトパブリッシングツールのWordPressをインストールします。

この手順で、複数のWordPressサイトを作るための基本的なサーバー環境を構築します。


### 必要な知識

[「サーバーってなに？」～初心者でもよくわかる！VPSによるWebサーバー構築講座(1) - さくらのナレッジ](http://knowledge.sakura.ad.jp/beginner/2691/)に書いてあることがわかるくらいにLinuxとインターネットの知識があれば、この記事の内容も理解し、実践できると思います。さくらインターネットの解説ですがさくらのVPSに限った話ではありません。CLI操作（ターミナルの使い方）の初歩も説明されています。

Linuxを使ったことがなくて一からウェブサイトを立ち上げようとする人は稀だと思いますが、もし、あなたがそうだとしたら、まずはあなたのPCにLinuxをインストールして使い始めたらよいと思います。

ドメインって何だっけ？とドメインについてよくわかっていない人もいると思います。ドメインについて知りたい方は、日本ネットワークインフォメーションセンター（JPNIC）の解説[ドメイン名 - JPNIC](https://www.nic.ad.jp/ja/dom/index.html)を読むことをおすすめします。JPNICは日本のIPアドレスを管理している団体です。他にもインターネット全体やIPアドレスの解説があり、とても有益なウェブサイトです。


### ドメインの登録

私はドメインexample.comの登録と管理は[お名前.com](http://www.onamae.com/)を使っています。お名前.comは日本の代表的なレジストラのGMOインターネットが運営しているサービスです。レジストラは他にもありますが、ドメインの登録料金の差はあまりないように思います。お名前.comを使っていて機能やサポートに不満はありません。

どこのレジストラでも、そこのウェブサイトで希望するドメインが登録できるのか検索して確かめることができます。まだ誰も登録していないドメインなら登録して使うことができます。


### サーバー（VPS）の契約

私はサーバーは[Linode](https://www.linode.com/)のVPSを使っています。Linodeは米国のクラウドホスティングサービスです。

これから述べていくウェブサイトの構築手順はVPSがどこのホスティングサービスかは関係ありません。どこのサービスを使ってもよいと思います。国内でしたら[さくらのVPS](http://vps.sakura.ad.jp/)がOSインストールなど管理パネルが使いやすいです[^5]。[GMOクラウド](https://vps.gmocloud.com/)は使いにくかったです。料金はどこも大差ありません。

ホスティングサービスと契約すると最低１つのIPアドレスとrootパスワードが与えられます。ホスティングサービスから管理パネルの案内があり、IPアドレスの確認、サーバーの起動などは管理パネルから行えます。

[^5]: Linodeとさくらはどちらも使いやすいのですが、LinodeはアダルトコンテンツがOKで、さくらはNGです。


### Ubuntu 16.04 OSのインストール

VPSのホスティングサービスなら、どこのサービスでも管理パネルからインストールしたいOSを選んでクリックだけでインストールできるはずです。私は[Linode Manager](https://manager.linode.com/linodes)にログインして、Rebuildページに移り、

- OSは64bit Ubuntu 16.04 LTSを選択し、
- パーティションは約20GBすべての容量、
- スワップ512MB、

としてRebuildしてOSをインストールしました（下図）。

![Linode ManagerでOSをインストールする画面](https://qiita-image-store.s3.amazonaws.com/0/197109/dded2ca6-d251-ed90-6c3c-2e83357a1bbb.png)

しばらく待つとOSが起動しサーバーの状態がRunやONになります。

SSH、Apacheの設定は、OSがCentOSなどUbuntuとは違うLinuxのディストリビューションだと設定ファイルのパスなど細かい点が変わってきます。Ubuntu（またはDibian）以外のディストリビューションの補足説明は私が実際に経験していないのでできません。


### ユーザーアカウントの作成

サーバーが稼働したらターミナルでリモートログインして、作業用のユーザーアカウントを作成します。

SSHでroot@addressにリモートログインします。ここではサーバーのIPアドレスを192.155.x.xとします。あなたのIPアドレスに置き換えて下さい。

```bash:ターミナル
$ ssh root@192.155.x.x
root@192.155.x.x's password:
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.8.3-x86_64-linode76 x86_64)
```

作業用のユーザーアカウントを作成します。ウェブ開発用なのでwwwとしました。名前は何でもよいです。Apacheのユーザー名とグループ名がwww-dataなのでそれに合わせています。

```bash:ターミナル
root@ubuntu:~# adduser www
```

ここでユーザーパスワードを決めて入力します。


### SSHの設定

SSHのセキュリティを高める設定をします。`/etc/ssh/sshd_config`がSSHの設定ファイルです。`sshd_config`ファイルはオリジナルをコピーして残しておきます。

```bash:ターミナル
root@ubuntu:~# cd /etc/ssh
root@ubuntu:/etc/ssh# cp sshd_config sshd_config.old
```

nanoエディタなどで`sshd_config`を開き、次のように編集します。

```bash:ターミナル
root@ubuntu:/etc/ssh# nano sshd_config
```

```:/etc/ssh/sshd_config
# /etc/ssh/sshd_config
Port 50000
LoginGraceTime 10
PermitRootLogin no
```

`Port`と書かれた行で、ポート番号を49152から65535の任意の番号に変えます[^40]。ポート番号を変更すると、不正アクセスを減らしてサーバーの負荷を減らす利点もあります。`LoginGraceTime`でパスワード認証の入力時間を10sにします。`PermitRootLogin`をnoにして、rootログインを禁止します。

[^40]: [List of TCP and UDP port numbers - Wikipedia](https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers)に記載している空いていて自由に使えるポートの範囲です。

ログアウトして再ログインするには、ポート番号を指定します。

```bash:ターミナル
$ ssh -p 50000 www@192.155.x.x
www@192.155.x.x's password:
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.8.3-x86_64-linode76 x86_64)
www@ubuntu:~$
```

ログアウトすれば、sshdのリスタートは必要ないと思いましたが、念のため以下がリスタートのコマンドです。

```bash:ターミナル
root@ubuntu:~# systemctl restart sshd
```

デフォルトだとパスワード認証のみですが、ログインとファイルのアップロードの度にパスワードを入力するのは面倒なので、公開鍵認証ができるようにします[^50] [^60]。

[^50]: [ssh接続を鍵認証で行う - CentOS / Scientific Linuxでサーバー構築](http://www.tooyama.org/ssh-key.html)と[sshの公開鍵認証の設定でつまずいた - さかな前線](http://daily.belltail.jp/?p=112)を参考にしました。

[^60]: 公開鍵暗号方式に慣れていないとき、私は[GnuPGで遊ぶ 暗号化してみる - そんなこと覚えてない](http://blog.eiel.info/blog/2013/07/31/gpg/)を読みました。ssh-keygenとは違うgpgという暗号ソフトなのですが、この記事を読むと暗号ソフトの使い方に親しめます。

クライアントサイド（あなたが使っているコンピュータ）で、公開鍵と秘密鍵のペアをRSA暗号方式で作成します。

```bash:ターミナル
$ cd ~/.ssh
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
...
```

処理の途中で入力するpassphraseは入力しないでEnterしてもよいです。処理が終わると`~/.ssh/`以下に、公開鍵`id_rsa.pub`と秘密鍵`id_rsa`が作成されます。

ssh-agentに秘密鍵`id_rsa`を登録します。

```bash:ターミナル
$ ssh-add id_rsa
Enter passphrase for id_rsa:
Identity added: id_rsa (id_rsa)
```

作成した公開鍵`id_rsa.pub`をサーバーにアップロードします。ここでは、サーバーのユーザーアカウントwwwのホームディレクトリにアップロードしています。

```bash:ターミナル
$ scp -P 50000 id_rsa.pub www@192.155.x.x:~
```

サーバーサイドに移ります。`~/.ssh`ディレクトリがない場合は、ディレクトリを作り、ユーザーwwwのみにrwxパーミッションを与えます。

```bash:ターミナル
www@ubuntu:~$ mkdir .ssh
www@ubuntu:~$ chmod 700 .ssh
```

アップロードした公開鍵`id_rsa.pub`を`~/.ssh/authorized_keys`に追加します。ユーザーwwwのみにrwパーミッションを与えます。

```bash:ターミナル
www@ubuntu:~$ cat id_rsa.pub >> .ssh/authorized_keys
www@ubuntu:~$ chmod 600 .ssh/authorized_keys
```

sshサービスリスタートします。

```bash:ターミナル
root@ubuntu:~# systemctl restart ssh
```

これで、公開鍵認証でログインできるようになりました。今後はログインにパスワードを入力する必要がありません。

```bash:ターミナル
$ ssh -p 50000 -i ~/.ssh/id_rsa www@192.155.x.x
```

sshは公開鍵認証に登録した秘密鍵を使うので、秘密鍵を登録してあれば、秘密鍵を`-i`オプションで指定しなくてもOKです。

```bash:ターミナル
$ ssh -p 50000 www@192.155.x.x
```

ここまでで、OSをインストールして、最低限のセキュリティの設定をしました。


### Apache HTTPサーバーソフトウェアのインストール

Apacheをインストールして、VPSの処理能力に合った設定をします[^70]。

[^70]: Apache、MySQL、PHPのインストールの方法は[Install LAMP on Ubuntu 16.04 - Linode](https://www.linode.com/docs/websites/lamp/install-lamp-on-ubuntu-16-04)に習っています。

Apacheをインストールする前にapt-getのアップデートをします。

```bash:ターミナル
root@ubuntu:~# apt-get update
root@ubuntu:~# apt-get upgrade
```

Apacheをインストールします。

```bash:ターミナル
root@ubuntu:~# apt-get install apache2
```

http://192.155.x.x/ にブラウザでアクセスして、デフォルトページが表示されればインストール成功です。

VPSの処理能力に合わせて設定を変更します。

Apacheのメインの設定ファイルである`/etc/apache2/apache2.conf`のバックアップをとってから編集します。

```bash:ターミナル
root@ubuntu:~# cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.old
root@ubuntu:~# nano /etc/apache2/apache2.conf
```

```:/etc/apache2/apache2.conf
KeepAlive Off
```

[Apache 2.4のドキュメント](http://httpd.apache.org/docs/2.4/mod/core.html#keepalive)によると、`KeepAlive`はHTTPの持続的な接続を可能にする機能です。`KeepAlive`をOnにしておけば、特に画像が多いサイトではブラウザ表示が速くなります。欠点はメモリを消費するので、Linodeのガイドではこの機能をOffにしています。`KeepAlive`をOn/Offどちらを選ぶかはあなたが要求するウェブサイトの機能によって決まります[^80]。

[^80]: [Apache optimization: KeepAlive On or Off? - Abdussamad.com](https://abdussamad.com/archives/169-Apache-optimization:-KeepAlive-On-or-Off.html)より

Apacheのデフォルトのmulti-processing module (MPM)はeventモジュールですが、PHPはデフォルトでpreforkモジュールを使っているので、MPMをeventからpreforkに変更します。

まず、preforkモジュールの設定ファイル`/etc/apache2/mods-available/mpm_prefork.conf`を編集して、VPSの処理能力に合わせます。バックアップを取ってから次のように編集します。

```:/etc/apache2/mods-available/mpm_prefork.conf
<IfModule mpm_prefork_module>
  StartServers 4
  MinSpareServers 20
  MaxSpareServers 40
  MaxRequestWorkers 200
  MaxConnectionsPerChild 4500
</IfModule>
```

これらの値は、2GB RAM / 1CPU COREの月10米ドルのVPS用のもので、Linodeが推奨している値です[^90]。

[^90]: MPM、`mpm_prefork.conf`の設定について、[Tuning Your Apache Server - Linode](https://www.linode.com/docs/websites/apache-tips-and-tricks/tuning-your-apache-server)に説明があります。また、`KeepAlive`の説明の際にもリンクしたApacheの公式ドキュメント[Documentation: Apache HTTP Server](https://httpd.apache.org/docs/)で調べることができます。

そして、ApacheのMPMをeventモジュールを無効にして、preforkモジュールを有効にします。

```bash:ターミナル
root@ubuntu:~# a2dismod mpm_event
Module mpm_event disabled.

root@ubuntu:~# a2enmod mpm_prefork
Considering conflict mpm_event for mpm_prefork:
Considering conflict mpm_worker for mpm_prefork:
Enabling module mpm_prefork.

root@ubuntu:~# systemctl restart apache2
```


### Apacheのバーチャルホストの設定

１つのIPアドレスで複数のウェブサイトを作るためのバーチャルホストの設定をします。


#### ApacheのconfファイルとDocumentRootディレクティブ

Apacheはクライアントからリクエストがあると、`DocumentRoot`ディレクティブで定義しているディレクトリ下の`index.html`ファイルをクライアントに返します。`DocumentRoot`は、`/etc/apache2/sites-available/000-default.conf`ファイルのバーチャルホスト内で定義されていて、`000-default.conf`ファイルの`DocumentRoot`の値は`/var/www/html`です。

```:/etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
  DocumentRoot /var/www/html
</VirtualHost>
```

つまり、Apacheのデフォルトの設定だと、ウェブウェイトの来訪者はサーバーの'/var/www/html/index.html'を読んでいます。

そこで、`000-default.conf`をもとにconfファイルを作成し、example.com、www.example.com、staging.example.comのために`DocumentRoot`やその他のディレクティブを定義して、私が目的とするバーチャルホストの設定をします。


#### 要求するバーチャルホストの確認

ここでもう一度、要求を書きます。

| サーバーのIPアドレス | ウェブサイトのアドレス |
| --- | --- |
| 192.155.x.x | http://example.com/ (= http://www.example.com/) |
| 192.155.x.x | http://staging.example.com/ |

上表のように、サーバーのIPアドレスは同一で、ウェブサイトのアドレスが異なる２つのサイトを１つのサーバーに共存させたいのです。

この要求を実現するためには、次のようなバーチャルホストの設定をします。

| IPアドレス:ポート番号 | ServerName | ServerAlias | DocumentRoot |
| --- | --- | --- | --- |
| *:80 | example.com | www.example.com | /var/www/html/example.com/pub |
| *:80 | staging.example.com |   | /var/www/html/staging.example.com/pub |

サーバーのIPアドレスが１つの場合は192.155.x.xと明記しても*としても同じです。HTTPのポート番号は通常80番です。`ServerName`ディレクティブはドメイン名を指定します。`ServerAlias`は`ServerName`の別名です。example.comはwww.example.comを別名としたいので、`ServerAlias`に指定します。example.comとstaging.example.comの`DocumentRoot`を別のパスに指定します。`DocumentRoot`をどこに置くかは、ユーザーのホームディレクトリ下`/home/www/`としてもよいです。私はApacheのデフォルト`/var/www/html`下に作ることにしました。

決めたバーチャルホストの設定をconfファイルに入力して、Apacheをリロードすれば複数のウェブサイトがオープンします（あと、後述するDNSレコードの設定があります）。


#### DocumentRoot下のファイルとディレクトリのパーミッション

バーチャルホストの設定を決めたので、その通りにconfファイルを編集するのですが、その前に`/var/www/html'下のすべてのファイルとディレクトリのパーミッションをどうすればよいか決めて変更する必要があります[^100]。

[^100]: [Webサーバーのパーミッションの設定〜ユーザー権限の考え方 - IT工房](http://itstudio.co/2015/08/20/4616/)がわかりやすくて勉強になります。具体的にどう設定するかは、[web開発のためのapacheやコンテンツディレクトリのパーミッション関連まとめ - バカンス駆動開発](http://egapool.hatenablog.com/entry/2013/11/29/184300)を参考にしました。

Apacheのデフォルトの`DocumentRoot`である`/var/www/html`のパーミッションは、

```bash:ターミナル
root@ubuntu:/# ls -la /var/www
drwxr-xr-x 1 root root 4096 Nov 18 04:29 .
drwxr-xr-x 1 root root 4096 Nov 18 07:03 html
```

となっています。所有者はrootでrwxパーミッションが与えられていて、その他ユーザーにはr-xのパーミッションが与えられています。

また、Apacheのユーザーと所属グループはwww-dataです。Apacheのユーザーとグループは、`apache2.conf`ファイルと`envvars`ファイルで定義されています。

```:/etc/apache2/apache2.conf
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
```

```:/etc/apache2/envvars
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
```

`/var/www/html`はパーミッションがその他（www-data含めその他すべてのユーザー）にr-xが与えられているので、Apacheはhtmlファイルを読んでクライアントの要求に返答することができます。ですから、Apacheをインストールすれば、何も設定しなくても、 http://192.155.x.x/ にアクセスするとウェブページが表示されます。

パーミッションを変更する理由はhtmlなどのファイルを便利に編集するためです。`DocumentRoot`のディレクトリとファイルのオーナーがrootでは、suでrootにならないとファイルの編集ができません。そこで、ウェブ開発用ユーザーwww（私やあなた）でファイルを編集でき、かつApache（ユーザーwww-data）もファイルを読めるようにパーミッションの変更をします。

ウェブ開発用ユーザーwwwをグループwww-data（Apacheのグループ）に追加します。

```bash:ターミナル
root@ubuntu:/# gpasswd -a www www-data
Adding user www to group www-data
```

再ログインすると、設定が反映されます。

```bash:ターミナル
www@ubuntu:~$ groups
www www-data
```

`DocumentRoot`下のすべてのファイルとディレクトリの所有者と所有グループをwww-data（Apache）にします。

```bash:ターミナル
root@ubuntu:/# chown -R www-data:www-data /var/www/html
```

chownの`-R`オプションはRecursive、指定ディレクトリ下のすべてのディレクトリとファイルに対して再帰的にコマンドを実行するオプションです。

`DocumentRoot`下のディレクトリのパーミッションを770、ファイルのパーミッションを660にして、その他のユーザーがアクセス出来ないようにします。

```bash:ターミナル
root@ubuntu:/# find /var/www/html -type d -exec chmod 770 {} \;
root@ubuntu:/# find /var/www/html -type f -exec chmod 660 {} \;
```

ここまでで、パーミッションはこのように変わっています。

```bash:ターミナル
root@ubuntu:/# ls -la /var/www/html

# パーミッション変更前
drwxr-xr-x 1 root root 4096 Nov 18 07:03 html

# 変更後
drwxrwx--- 1 www-data www-data 4096 Nov 18 07:03 html
```

今後、`DocumentRoot /var/www/html`下に作成されるファイルの所有グループをwww-dataに固定します。ディレクトリにSGID（Set Group ID）を設定した場合は、その下に作成したファイル・ディレクトリが、SGIDが設定されているディレクトリの所有グループになることを利用します[^110]。

[^110]: [SGID（Set Group ID） - 特殊なアクセス権](http://kazmax.zpp.jp/linux_beginner/setgroupid.html)で勉強しました。

```bash:ターミナル
root@ubuntu:/# chmod -R 2770 /var/www/html
```

グループのパーミッションがrwxからrwsに変わっています。

```bash:ターミナル
root@ubuntu:/# ls -la /var/www/html
drwxrws--- 1 www-data www-data 4096 Nov 18 07:03 html
```

試しにディレクトリを作ってみます。

```bash:ターミナル
www@ubuntu:~$ mkdir /var/www/html/test
www@ubuntu:~$ ls -la /var/www/html/test
# htmlディレクトリ
drwxrws--- 2 www-data www-data 4096 Nov 18 07:03 html
# 新規作成ディレクトリ
drwxrwsr-x 1 www www-data 4096 Nov 28 03:26 test
```

新しく作られるディレクトリの所有者は作成者であるユーザーwwwで、その他ユーザーがパーミッションr-xを持ちます。グループがwww-dataなので、Apacheにもパーミッションrwxが与えられているので、所有者がユーザーwwwでも問題ありません。

しかし、その他ユーザーにパーミッションr-xが与えられていることは、先ほど、その他ユーザーにパーミッションを与えない設定をしたことからすると意に反しています。

[How to set default file permissions for all folders/files in a directory? - Unix & Linux Stack Exchange](http://unix.stackexchange.com/questions/1314/how-to-set-default-file-permissions-for-all-folders-files-in-a-directory)を読むと、ACLをインストールして使えば新規作成するディレクトリのパーミッションを755、ファイルのパーミッションを644から変更できるらしいです。

ただ、これは保留にします。SGID設定後に作られる`DocumentRoot`下のすべてのディレクトリ・ファイルの所有者はwww（ウェブ開発ユーザー）またはwww-data（Apache）で、所有グループはwww-dataであることは固定です。前述したfindとchmodによるパーミッション変更はコマンド一つでいつでもできます。その他ユーザーにパーミッションr-xが与えられていることはとりあえず置いておいて、Apacheのバーチャルホストの設定を先に進めます。


#### バーチャルホストの設定

`DocumentRoot`下のパーミッションがクリアになったので、バーチャルホストの設定をします[^120]。

[^120]: 詳しくは、[Apache バーチャルホスト説明書 - Apache HTTP サーバ バージョン 2.4](http://httpd.apache.org/docs/current/ja/vhosts/)に解説があります。

`/etc/apache2/sites-available/000-default.conf`ファイルをコピーして、`example.com.conf`ファイルを作ります。エディタで`example.com.conf`を開き、次のように編集します。

```bash:ターミナル
root@ubuntu:/# cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf
root@ubuntu:/# nano /etc/apache2/sites-available/example.com.conf
```

```:/etc/apache2/sites-available/example.com.conf
NameVirtualHost *:80

<Directory /var/www/html/example.com/pub>
  Require all granted
</Directory>
<VirtualHost *:80>
  ServerName example.com
  ServerAlias www.example.com
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html/example.com/pub
  ErrorLog /var/www/html/logs/error-example.com.log
  CustomLog /var/www/html/logs/access-example.com.log combined
</VirtualHost>

<Directory /var/www/html/staging.example.com/pub>
  Require all granted
</Directory>
<VirtualHost *:80>
  ServerName staging.webfub.tech
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html/staging.example.com/pub
  ErrorLog /var/www/html/logs/error-staging.example.com.log
  CustomLog /var/www/html/logs/access-staging.example.com.log combined
</VirtualHost>
```

`NameVirtualHost *:80`は、クライアントが任意のIPアドレスにポート80でHTTP接続したときに、このバーチャルホストの設定が有効だという意味です。サーバーのIPアドレスは192.155.x.xの1つだけなので、`NameVirtualHost 192.155.x.x:80`としても同じことです。`NameVirtualHost`と`VirtualHost`の後に続く値は同じでなければいけません。

`ServerName`て定義した値がウェブサイトのURLの http://ServerName/ になります。`ServerAlias`は`ServerName`の別名で、クライアントが http://ServerAlias/ にアクセスすると、Apacheはhttp://ServerName/ にアクセスがあったときと同じ動作をします。`ServerName`で定義するホスト名は１つのみです。`ServerAlias`はホスト名を複数定義でき、ワイルドカード（*.example.com）を使うこともできます。

私は、 http://example.com/ と http://www.example.com/ は同じウェブサイトでメインサイトとしたいので、１つ目のバーチャルホストは`ServerName example.com`で、`ServerAlias www.example.com`としています。サブサイトは http://staging.example.com で別名はいらないので、２つ目のバーチャルホストは`ServerName staging.example.com`で`ServerAlias`はありません。

１つ目と２つ目のバーチャルホストは異なる`DocumentRoot`を定義します。それぞれ、`/var/www/html/example.com/pub`と`/var/www/html/staging.example.com/pub`としています。

定義したディレクトリはウェブ開発用ユーザーwwwで作ります。（rootではなくユーザーwwwです）。`ErrorLog`と`CustomLog`で定義したログファイルを保存するディレクトリも作成します。

```bash:ターミナル
www@ubuntu:/var/www/html$ mkdir -p example.com/pub
www@ubuntu:/var/www/html$ mkdir -p staging.example.com/pub
www@ubuntu:/var/www/html$ mkdir logs
```

ディレクトリを作成したら、設定ファイルを有効にして、Apacheのサービスをリロードします。

```bash:ターミナル
root@ubuntu:/# a2ensite example.com.conf
root@ubuntu:/# a2dissite 000-default.conf
root@ubuntu:/# systemctl reload apache2
```

これでバーチャルホストの設定は終わりです。


### DNSレコードの設定

DNSサーバーにDNSレコードを次のように設定します[^125]。DNSレコードの設定はApacheの設定の前でも構いません。

[^125]: DNSについて説明しているページのリンクを貼ろうと思ったのですが、特におすすめしたいものが思い出せません。確か、ずいぶん前に[ネットワークはなぜつながるのか（戸根勤 著 2007年）](http://amzn.to/2fGNelR)を読んだと思います。

私はドメインを登録したお名前.comが提供しているDNSサーバーを使っています。お名前.comなら、[ドメインNavi - お名前.com](https://www.onamae.com/navi/domain.html)にログインして、`ドメイン設定 > ネームサーバーの設定 > DNS関連機能の設定`とたどります。

| ホスト名 | TYPE | TTL | VALUE | 状態 |
| --- | --- | --- | --- | --- |
| example.com | A | 3600 | 192.155.x.x | 有効 |
| www.example.com | A | 3600 | 192.155.x.x | 有効 |
| staging.example.com | A | 3600 | 192.155.x.x | 有効 |

３つのドメインをすべて同じIPアドレスに紐付けます。お名前.comでは、このようなDNSレコードを設定する場合は、ホスト名はドメイン、TYPEはA、TTL（Time To Live パケットの有効期間）は3600秒、VALUEはIPアドレスを入力します[^130]。

[^130]: [お名前.comヘルプセンター](http://www.onamae.com/help/)で調べることができます。

DNSレコードの設定が反映されるまで数時間かかります。休憩タイムです。


### バーチャルホストとDNSの動作確認

DNSレコードが反映されたら、２つのバーチャルホストの`DocumentRoot`にそれぞれ`index.html`ファイルを置いて、ウェブサイトがパブリックになっているか確かめます。

ローカルで簡単な`index.html`ファイルを作って、サーバーにアップロードします。

２つのバーチャルホストが区別できるように`<p>`などの内容を一部変えます。`~/example.com/index.html`と`~/staging.example.com/index.html`を作ります。

```html:~/example.com/index.html
<! for example.com -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>example.com</title>
</head>
<body>
  <p>for example.com</p>
</body>
</html>
```

```html:~/staging.example.com/index.html
<! for staging.example.com -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>staging.example.com</title>
</head>
<body>
  <p>for staging.example.com</p>
</body>
</html>
```

scpコマンドで`index.html`をサーバーのDocumentRootに指定したディレクトリにアップロードします。scpはポート番号を指定するには`-P`オプションを使います。大文字のPでなければいけません。アップロードするパスは`user@address:path`という表記で指定します。

```bash:ターミナル
$ scp -P 50000 ~/example.com/index.html www@192.155.x.x:/var/www/html/example.com/pub
$ scp -P 50000 ~/staging.example.com/index.html www@192.155.x.x:/var/www/html/staging.example.com/pub
```

ブラウザで、http://example.com/（またはhttp://www.example.com/）とhttp://staging.example.com/にそれぞれアクセスすると、それぞれ別の`index.html`が表示されればOKです。

後はウェブサイトをデザインしてコンテンツを用意すればウェブサイトの完成です。私はデザインとコンテンツ作成にはWordPressを使いたいので、さらにMySQL、PHP、WordPressをインストールします。


### MySQLのインストール

apt-getでMySQLをインストールします。パスワードの設定を求められるので、任意のパスワードを入力します。入力したパスワードがMySQLのrootパスワードになります。

```bash:ターミナル
root@ubuntu:~# apt-get install mysql-server
```


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

apt-getでPHPとPHPの拡張モジュールをインストールします。

```bash:ターミナル
root@ubuntu:~# apt-get install php7.0 php-pear libapache2-mod-php7.0 php7.0-mysql
```

拡張モジュールは他にもcURL、JSON、CGIをサポートするための拡張モジュールがありますが、私は今のところは上記のモジュールだけをインストールしました。これでWordPressの動作に問題は出ていません。

PHPを設定します。`php.ini`のバックアップをとり、エディタで編集します。

```bash:ターミナル
root@ubuntu:~# cp /etc/php/7.0/apache2/php.ini /etc/php/7.0/apache2/php.ini.old
root@ubuntu:~# nano /etc/php/7.0/apache2/php.ini
```

```:/etc/php/7.0/apache2/php.ini
max_input_time = 30
error_reporting = E_COMPILE_ERROR | E_RECOVERABLE_ERROR | E_ERROR | E_CORE_ERROR
error_log = /var/log/php/error.log
```

`max_input_time`はスクリプトがPOSTなどの入力をパースする最大時間（秒）です。[Linodeのガイド](https://www.linode.com/docs/websites/lamp/install-lamp-on-ubuntu-16-04)では30秒が指定されています。`error_reporting`はエラーログに出力する項目で、`error_log`は出力ファイルパスです[^160]。

[^160]: 他にも`php.ini`の設定について[PHP: 実行時設定 - Manual](http://php.net/manual/ja/info.configuration.php)に説明があります。

`error_log`で指定したエラーログの出力ディレクトリを作り、ディレクトリの所有者をwww-data（Apache）に変更します。

```bash:ターミナル
root@ubuntu:~# mkdir /var/log/php
root@ubuntu:~# chown www-data:www-data /var/log/php
```


### MySQLとPHPの動作テスト

MySQLとPHPが正しく動作するかを、MySQLデータベースにPHPがアクセスできるかどうかでテストします。

データベースを１つ作成します。

MySQLにroot（UbuntuのrootではなくMySQLのrootです）でログインします。インストール時に設定したパスワードを使います。

```bash:ターミナル
root@ubuntu:~# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.16-0ubuntu0.16.04.1 (Ubuntu)
```

`webdata`という名前のデータベースを作り、ユーザー（ユーザー名`you`、パスワード`your-password`）にデータベース`webdata`を使用する権利を与えます。`you`と`your-password`は任意の値に置き換えます（`user1`と`e2;3d#Sa`など）。`quit`で終了します。

```mysql:MySQLコンソール
mysql> CREATE DATABASE webdata;
Query OK, 1 row affected (0.00 sec)
mysql> GRANT ALL ON webdata.* TO 'you' IDENTIFIED BY 'your-password';
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> quit
Bye
```

テスト用のPHPスクリプト`~/test.php`をローカルで作り、Apacheの`DocumentRoot`にアップロードします。

```php:test.php
<html>
  <head>
    <title>PHP Test</title>
  </head>
  <body>
    <?php
    echo '<p>Hello World</p>';

    $servername = "localhost";
    $username = "you";
    $password = "your-password";

    // Create MySQL connection
    $conn = mysqli_connect($servername, $username, $password);

    // Check connection - if it fails, output will include the error message
    if (!$conn) {
      die('<p>Connection failed: <p>' . mysqli_connect_error());
    }
    echo '<p>Connected successfully</p>';
    ?>
  </body>
</html>
```

`$username`と`$password`をそれぞれデータベースを作成した時に入力した値に置き換えて下さい。このスクリプトはPHPがMySQLデータベースサーバーへのアクセスに成功したらConnected succesfullyとブラウザに表示し、アクセスに失敗したらCoonection failedと表示します。

```bash:ターミナル
user@client ~ % scp -P 50000 ~/test.php www@192.155.x.x:/var/www/html/example.com/pub
```

今、`DocumentRoot`が`/var/www/html/example.com/www`だとして、scpで`test.php`をローカルマシンからサーバーにアップロードします。

http://example.com/test.phpにブラウザでアクセスしてConnected succesfullyと表示されたらOKです。NGだった場合は、まずユーザー名、パスワードが正しく入力されているか確かめます。Apacheサービスをリスタートしてもよいと思います。


### WordPressのインストール

これまでにApache、MySQL、PHPがインストールしてバーチャルホストやVPSの処理能力に応じた設定など様々な設定をしてきました。これでWordPressの[インストールの前に](http://wpdocs.osdn.jp/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%AE%E5%89%8D%E3%81%AB)のシステム要件を満たすので、WordPressをインストールして使うことができます[^170]。

[^170]: インストールの方法は[WordPress のインストール - WordPress Codex 日本語版](https://wpdocs.osdn.jp/WordPress_%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)に習いました。

#### latest.tar.gzのダウンロードと解凍

WordPress http://wordpress.org/latest.tar.gz をwgetでダウンロードしてtarで解凍します。ローカルではなくwordoress.orgサーバーから私のウェブサーバーにダウンロードします。

```bash:ターミナル
www@ubuntu:~$ wget http://wordpress.org/latest.tar.gz
www@ubuntu:~$ tar -xzvf latest.tar.gz
```

解凍すると`wordpress`ディレクトリができます。中には、`wp-settings.php`などPHPスクリプトが入っています。

```
wordpress/
wordpress/wp-settings.php
wordpress/wp-cron.php
wordpress/wp-comments-post.php
wordpress/wp-activate.php
wordpress/wp-admin/
wordpress/wp-admin/link-parse-opml.php
...
```

ダウンロードしたファイルを見ると、改めてWordPressはPHPスクリプトの集合で構成されたシステムなのだとわかります。WordPressというバイナリのソフトウェアがあるわけではなく、PHPで書かれたシステムなのです。ユーザーがブラウザでウェブサイトにアクセスすると、HTTPサーバーであるApacheがPHPを呼び出し、PHPがWordPressのPHPスクリプトを実行します。WordPress自体にサーバー上のファイルをリードしたりライトしたりするパーミッションがあるのではなく、Apache（www-dataユーザー）にパーミッションがあります。


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

WordPressはMySQLデータベースを１つ使用するので、データベースとそのユーザーを作ります。MySQLとPHPの動作テストのために作ったデータベースとユーザーをWordPress専用にしてもOKです。

MySQLのrootでMySQLにログインします。

```bash:ターミナル
www@ubuntu:~$ mysql -u root -p
Enter password:
```

データベース名wp_webfuntech、データベースのユーザーはユーザー名wwwとします。このMySQLのユーザーwwwとUbuntuのユーザーwwwは同じ名前ですが関係ありません。ユーザーwwwのパスワードを設定します。最後に、一応`flush`コマンドで権限を消します。

```mysql:MySQLコンソール
mysql> create database wp_webfuntech;
mysql> grant all privileges on wp_webfuntech.* to 'www'@'localhost'
mysql> flush privileges;
mysql> exit
```

一度MySQLからログアウトした後に、ユーザーwwwでログインします。ユーザーwwwの正しいパスワードを入力するとログインできます。

```bash:ターミナル
www@ubuntu:~$ mysql -u www -p
Enter password:
```

MySQLのデータベースの一覧を得るには、`show`コマンドを使います。

```mysql:MySQLコンソール
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| webdata |
| wp_webfuntech |
+--------------------+
7 rows in set (0.00 sec)

mysql> exit
Bye
```

MySQLの新規ユーザーとデータベースができています。


#### wp-config.phpの設定

解凍した`wordpress/wp-config-sample.php`をコピーして、`wp-config.php`を作成します。`wp-config.php`はWordPressのインストールスクリプト`install.php`が読み込む設定ファイルです。`wp-config.php`の内容は、MySQLデータベース名、ユーザー名、パスワード、認証キーなどです。これらを入力して保存します。

```bash:ターミナル
www@ubuntu:~$ cp wordpress/wp-config-sample.php wordpress/wp-config.php
www@ubuntu:~$ nano wordpress/wp-config.php
```

エディタで`wp-config.php`を次のように編集します。

```:wp-config.php
define('DB_NAME', 'wp_webfuntech');

/** MySQL database username */
define('DB_USER', 'www');

/** MySQL database password */
define('DB_PASSWORD', 'password for www');

/** MySQL hostname */
define('DB_HOST', 'localhost');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define('AUTH_KEY', '*');
define('SECURE_AUTH_KEY', '*');
define('LOGGED_IN_KEY', '*');
define('NONCE_KEY', '*');
define('AUTH_SALT', '*');
define('SECURE_AUTH_SALT', '*');
define('LOGGED_IN_SALT', '*');
define('NONCE_SALT', '*');
```

ファイルの上の方の行にあるDB_NAMEはデータベース名で、その他のデータベースの情報を適当に入力します。ファイルの下の方の行にあるAUTH_KEYなどAuthentication Unique Keys（認証キー）は https://api.wordpress.org/secret-key/1.1/salt/ が出力する64桁のランダムな文字列を入力します。

私は、サーバーからwgetで https://api.wordpress.org/secret-key/1.1/salt/ （認証キー）をダウンロードして`index.html`として保存し、nanoエディタで`wp-config.php`を開き、`Ctrl + R`で`index.html`のテキスト（認証キー）を挿入しました。

```bash:ターミナル
# 認証キーをダウンロードしてindex.htmlに保存する
www@ubuntu:~$ wget https://api.wordpress.org/secret-key/1.1/salt/
2016-12-06 05:43:08 (81.3 MB/s) - 'index.html' saved [768]

# catでindex.htmlを見てみると
www@ubuntu:~$ cat index.html
define('AUTH_KEY',         'X@+rNHM:?kxg{6irA#ru2@P]bK;@gNz&UbK|2s)S`&i*Rj|2!_&~2fH|woxH3_aT');
define('SECURE_AUTH_KEY',  'ly&0/Gbs_R! a/)>ynRPr_&&(boR4YM/S*t-8YF*|yyj*U.1z|u6R9c3>=+#E7bB');
define('LOGGED_IN_KEY',    ',FowD`:>t6@x)%khp*P2Ewxhj((j3MMb]P,(!6=|O)CHP31ZrPag#unR1x}M#x+w');
define('NONCE_KEY',        'Ad2P-L?GLsXqPlO>M-M0)x|G~L<ZoCy<>7@68Mk#x_O4{^I h;h;jzEH1mAW~0ho');
define('AUTH_SALT',        '4}v9/aMfSo;NM8S/SNH7fLwo_XY~]=?EY5_LS,eWxXmeEgvp|+BGg4e/-[6U*pMB');
define('SECURE_AUTH_SALT', 'P(L/6Zc$*l*pRp.P2O^{Tc]cc7sH@9{-0l|S`o=KMrSOL+NvN(+(}{se1PD$%UTu');
define('LOGGED_IN_SALT',   'v*OpM,4qQ#CPQ5cPeWtV/uC&vV,S+LAm!hL4Ar9H]o$Amgwk9w/ygWG=,F{M4`#*');
define('NONCE_SALT',       'VG;}CsJTj>OlUzOzOa;C;XEla{bxV:</vQfs:GC=Ke6+jui:SD1C3uhbzUR0O$>N');

# nanoエディタでwp-config.phpを編集する
www@ubuntu:~$ nano wprdpress/wp-config.php

# この後、Ctrl+Rでindex.htmlをテキスト挿入する
```

#### wordpressディレクトリのコピー

`wp-config.php`を作成したら、`~/wordpress/`ディレクトリの中身だけを`DocumentRoot`にコピーします。そして、ファイルとディレクトリのパーミッションをもう一度変更します。

```bash:ターミナル
www@ubuntu:~$ cp -r wordpress/* /var/www/html/example.com/pub/
www@ubuntu:~$ su

root@ubuntu:/# chown -R www-data:www-data /var/www/html/
root@ubuntu:/# find /var/www/html -type d -exec chmod 770 {} \;
root@ubuntu:/# find /var/www/html -type f -exec chmod 660 {} \;
```

chownとchmodでパーミッションを変更しないと、www-data（Apache）にライトの権限がないため、WordPressのインストールはできてもテーマのインストールや編集ができません。この再度パーミッションを設定しないといけない点は前述したとおりUbuntuを改良する余地があります。


#### インストールスクリプトinstall.phpの実行

http://example.com/wp-admin/install.php にブラウザでアクセスします。サイト名、ユーザー名、ログインパスワード、メールアドレスを入力してセットアップが終わるとWordPressのインストールが完了します。http://ServerName/wp-admin/ にアクセスして管理パネルにログインできるようになります。

長い文章を読んで下さってありがとうございます。お疲れ様でした。


### 公式ドキュメントのリンク

- [Getting Started with Linode](https://www.linode.com/docs/getting-started)
- [Apache HTTP サーバ バージョン 2.4 ドキュメント](http://httpd.apache.org/docs/2.4/ja/)
- [MySQL 5.6 リファレンスマニュアル](http://dev.mysql.com/doc/refman/5.6/ja/)
- [PHP マニュアル](http://php.net/manual/ja/index.php)
- [WordPress Codex 日本語版](http://wpdocs.osdn.jp/Main_Pagewordpress)