VagrantでLAMP環境を構築〜BOXの書き出しまで

Vagrantでチームでの開発環境を整えたくて、実際に行った手順を忘備録としてまとめます。

# やりたいこと
* 仮想環境にLAMP環境を作りたい。 -> 仮想環境上で開発をしたい。
* 仮想環境を他のマシンに簡単に複製したい -> マシン毎の開発環境を統一

# 手順
* Vagrantのインストール
* BOXから仮想環境を新規に作成
* LAMP環境の構築
* 構築したLAMP環境をVagrantでBOXとしてエクスポートし、他のマシンにインポートさせる。

# 導入環境
* Mac
* VirtualBox（インストール済み）
* インストールするOSはcentos7.5
* phpは7.29
* MySQLは5.7
* SSL接続での接続も出来るようにする（サーバー証明書は自己署名）

＊補足
以下の文章中に「centos」と「GuestOS」と呼び方が混在していますが、どちらも同じ仮想環境のことを指しています。

# Vagrantのインストール
[公式サイト](https://www.vagrantup.com/)からインストーラーをダウンロードしてインストールしましょう。
コマンドラインでインストールが無事に済んだか確認します。バージョンが表示されればOKです

```
$ vagrant -v

Vagrant 2.1.2
```

# BOXから仮想環境を新規に作成
VagrantはOSをBOXファイルという形式で配布されており、そのファイルから希望のOSをインストールします。

[配布先] [Vagrant Cloud](https://app.vagrantup.com/boxes/search)

今回はcentos7.5を選びたいので「centos」で検索して一番上に表示されたBOXファイルにします。
以下からコマンドラインでの作業になります。

## BOXファイルをVagrantに追加する
`vagrant box add [name]`でBOXファイルをVagrantに追加します。

```
$ vagrant box add centos/7
```

BOXファイルのダウンロードが始まるので、完了したら確認してみましょう。
`vagrant box list`で追加済みのBOXの名前が表示されます。

```
$ vagrant box list

centos/7 (virtualbox, 1804.02)
```

## Vagrantfileの作成（初期化）
Vagrantfileを作成します。
最初に作業ディレクトリを作成して移動します。

```
$ mkdir vagrant-project
$ cd vagrant-project
```

`vagrant init "box名"`でVagrantfileを生成します。lsコマンドでファイルが出来ているか確認しましょう。

```
$ vagrant init centos/7

// Vagrantfileの確認
$ ls

Vagrantfile
```

## 仮想環境を起動・ログイン
`vagrant up`で仮想環境を起動します。初回起動時は少し時間がかかります。

```
$ vagrant up
```

起動した仮想環境へsshでログインします。

```
$ vagrant ssh

// centosに切り替わります
[vagrant@localhost ~]$ 
```

ログインするとVagrantが作成したユーザーでログインしますが、以降はルートユーザーに切り替えて作業をします。ルートユーザーのパスワードは"vagrant"を入力。

```
[vagrant@localhost ~]$ su root
password: vagrant

// ルートユーザーに変更
[root@localhost vagrant]# 
```

## centosの設定

### selinuxを無効化
SE Linuxはセキュリティ強化のための機能ですが、サービスの動作に影響が出るのでオフにします。

```
// configファイルを編集
# vi /etc/selinux/config
```

以下の点を書き換えてください。

```
SELINUX=enforcing
↓
SELINUX=disabled
```

centosの再起動後に`getenforce`コマンドを実行して`Disabled`と表示されればselinuxが無効化されています。



## apacheの有効化

### ユーザーの作成
Webサーバーを構築するに当たってwwwユーザーを作成します。

```
// ユーザー追加
# useradd -s /sbin/nologin www

// パスワードの設定
# passwd www
Changing password for user www.
New password: [パスワード入力]
Retype new password: [パスワード再入力]
passwd: all authentication tokens updated successfully.
```

作成したユーザーを確認します。

```
# cat /etc/passwd | grep www
www:x:1001:1001::/home/www:/sbin/nologin
```

idコマンドでユーザーとグループが表示されることも確認します。

```
# id www
uid=1001(www) gid=1001(www) groups=1001(www)
```

### httpdのインストール

httpdに関するパッケージは複数ありますが以下のパッケージをインストールします。

* httpd.x86_64 （httpdウェブサーバー本体)
* httpd-devel.x86_64 (httpdに関連する開発ツール、モジュールなどのパッケージ）
* httpd-manual.noarch (httpdのマニュアル）
* httpd-tools.x86_64 (httpdに関連するツール群）

```
# yum -y install httpd httpd-tools httpd-devel httpd-manual
```

パッケージのインストールが始まり、[**complete!**]と表示されればインストール完了です。
パッケージの確認をします。

```
# yum list installed | grep httpd
httpd.x86_64                     2.4.6-80.el7.centos.1          @updates        
httpd-devel.x86_64               2.4.6-80.el7.centos.1          @updates        
httpd-manual.noarch              2.4.6-80.el7.centos.1          @updates        
httpd-tools.x86_64               2.4.6-80.el7.centos.1          @updates   
```

#### httpd起動の確認

```
# systemctl status httpd

● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2018-09-04 00:33:22 UTC; 1h 2min ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 1042 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─1042 /usr/sbin/httpd -DFOREGROUND
           ├─1087 /usr/sbin/httpd -DFOREGROUND
           ├─1088 /usr/sbin/httpd -DFOREGROUND
           ├─1089 /usr/sbin/httpd -DFOREGROUND
           ├─1090 /usr/sbin/httpd -DFOREGROUND
           └─1091 /usr/sbin/httpd -DFOREGROUND

Sep 04 00:33:22 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
Sep 04 00:33:22 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
```

出力された中で、●が緑色で表示されていればhttpdサービスが正常に起動しています。

#### httpdを自動起動にする
centosが再起動した場合などにhttpdが自動的に起動するようにしておきます。

```
# systemctl enable httpd

// 以下コマンドで"enabled"になっていればOK
# systemctl list-unit-files | grep httpd
httpd.service                                 enabled 
```

### firewallの許可設定
ウェブサーバーの待ち受けポートである80番に外部から接続できるように設定を追加します。

```
# firewall-cmd --add-service=http --permanent
success

// 再読み込み
# firewall-cmd --reload
success
```

設定を確認します。

```
# firewall-cmd --list-all

// [service]項目に"http"があればOK
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: ssh dhcpv6-client http
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
```

### HostOS(Mac)からIPアドレスでアクセスする

HostOSからWebページが表示されるか確認します。
IPアドレスはVagrantfileに記述されています。
**config.vm.network "private_network"**の記述がある行のIPアドレスでアクセスしてみましょう。デフォルトのテストページが表示されればOKです。

```text:Vagrantfile
config.vm.network "private_network", ip: "xxx.xxx.xx.xx"
```

### httpdの設定

* 動作ユーザーとグループをwwwに変更
* ドキュメントルートをデフォルトから`/home/www/html`に変更
* cgi用ディレクトリを”/home/www/cgi-bin”に変更

#### httpd.confの変更

まずはhttpd.confのバックアップを取っておきます。

```
cp -p /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
```

##### 動作ユーザー・グループの変更

```text:httpd.conf
// 66~67行目
User apache
Group apache
↓
User www
Group www
```

##### ドキュメントルート・ディレクトリの変更

```text:httpd.conf
// 119行目
DocumentRoot "/var/www/html"
↓
DocumentRoot "/home/www/html"

// 124行目
<Directory "/var/www">
↓
<Directory "/home/www">

// 131行目
<Directory "/var/www/html">
↓
<Directory "/home/www/html">
```

##### スクリプトエイリアス・cgi用ディレクトリの変更
```text:httpd.conf
// 247行目
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
↓
ScriptAlias /cgi-bin/ "/home/www/cgi-bin/"

// 255行目
<Directory "/var/www/cgi-bin">
↓
<Directory "/home/www/cgi-bin">
```

#### 変更後のドキュメントルートとcgi用のディレクトリを作成しておく

```
# mkdir /home/www/html
# mkdir /home/www/cgi-bin
```

#### httpd.confファイルの確認
httpd.confに記述エラーがないか確認します。

```
# httpd -t

// Syntax OKと表示されればOK
Syntax OK
```

### 不要ファイルの移動

httpdはインストール時に、運用には不要な設定ファイルが自動的に作成されています。
/etc/httpd/conf.d/以下に含まれる autoindex.confとwelcome.confはセキュリティに問題があるためリネーム（ファイル名の変更）か削除することをオススメします。

```
# cd /etc/httpd/conf
# mv autoindex.conf autoindex.conf.org
# mv welcome.conf welcome.conf.org
```

### httpdサービスの再起動

```
# systemctl restart httpd
```

### ドキュメントルートにindex.htmlファイルを作成
ここまで問題なく進めば、Webページにアクセスすると403エラーが表示されるので**/home/www/html/**にindex.htmlファイルを作成して表示確認をします。

```
# vi /home/www/html/index.html
```

```html:index.html
<html>
  <body>
    Test Page.
  </body>
</html>
```

ファイルのアクセス権をwwwユーザーに変更します。

```
# chown www:www /home/www/html/index.html
```

これでページにアクセスすると`Test Page.`とテキスト表示されたページを確認できます。

## SSLの有効化

次にhttpsでアクセス出来るようにSSLを有効化します。

### ssl_modのインストール

```
# yum install -y mod_ssl
```

### SSLの自己証明書を作成
SSLを利用するにはSSLサーバー証明書をインストールする必要があるため、自己証明書を自分で作成してしまいます。

#### 秘密鍵(key)の生成

```
# openssl genrsa > server.key
```

#### 公開鍵(csr)の生成

```
# openssl req -new -key server.key > server.csr
```

上記コマンドを実行すると、本来は対話式で情報を入力する必要がありますが今回は全てEnterで飛ばしてしまいます。

#### サーバ証明書(crt)の作成

```
// 証明書(crt)
# openssl x509 -req -signkey server.key < server.csr > server.crt
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting Private key

// 公開鍵を削除
# rm server.csr
```

#### 秘密鍵とサーバ証明書の配置
作成した秘密鍵と証明書を/etc/httpd/conf以下に配置していきます。

```
// 秘密鍵
# mkdir /etc/httpd/conf/ssl.key
# mv server.key /etc/httpd/conf/ssl.key/

// サーバ証明書
# mkdir /etc/httpd/conf/ssl.crt
# mv server.crt /etc/httpd/conf/ssl.crt/
```

#### SSLモジュールの設定
/etc/httpd/conf.d/ssl.confの中に、配置した鍵と証明書のパスを設定します。

```
# vi /etc/httpd/conf.d/ssl.conf
```

```text:ssl.conf
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
↓下記に書き換え
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt

SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
↓下記に書き換え
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key
```

### 443ポートの解放
firewallでTCP443ポートを外部から接続できるように許可します。

```
# firewall-cmd --zone=public --add-port=443/tcp --permanent

// 再読み込み
# firewall-cmd --reload 
```

設定を確認します。

```
# firewall-cmd --list-all

// [ports]項目に"443/tcp"があればOK
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources: 
  services: ssh dhcpv6-client http
  ports: 443/tcp
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
```

## 任意のドメインでページへアクセスする
HostOSのhostsファイルを編集して、任意のドメインでアクセス出来るようにします。

```text:hosts
www.domain.com xxx.xxx.xx.xx <- GuestOSのIPアドレス
```

## PHP

### インストール
yumでインストールするので、まずはリポジトリを追加します。

```
// EPELリポジトリ
# yum install epel-release

// Remiリポジトリ
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

// phpインストール
yum install --enablerepo=remi,remi-php72 php php-devel php-mbstring php-pdo php-gd php-xml php-mcrypt
```

インストールが正常に完了したか確認します。

```
// インストールずみパッケージの確認
rpm -qa | grep php

// PHPバージョンの確認
php --version
```

### php.iniの設定

php.iniの以下の項目を設定します。

```text:php.ini
date.timezone = "Asia/Tokyo"

mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
mbstring.http_input = UTF-8
mbstring.http_output = pass
mbstring.encoding_translation = On
mbstring.detect_order = auto
mbstring.substitute_charset = none
```

### phpinfoで動作確認

ドキュメントルート`/home/www/html`に`index.php`を作成します。

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

無事phpinfoが表示されればOKです。

## MySQLのインストール
centos7ではデフォルトでMariaDBがインストールされていることがあります。
MariaDBがインストールされているか確認します。

```
# yum list installed | grep mariadb

// インストールされていれば下記のパッケージが表示されます
mariadb-libs.x86_64
```

MariaDBをアンインストールします。

```
# yum remove mariadb-libs
# rm -rf /var/lib/mysql/
```

### MySQL公式のyumリポジトリを追加
[MySQL公式サイト](https://dev.mysql.com/downloads/repo/yum/)

リポジトリURLは上記のページから、「**Red Hat Enterprise Linux 7 / Oracle Linux 7 (Architecture Independent), RPM Package**」の項目のダウンロードボタンをクリック。
![スクリーンショット 2018-09-04 10.05.56.png](https://qiita-image-store.s3.amazonaws.com/0/245899/3ef742e2-eed6-9d5e-ee0a-90f2d39ad13a.png)


「**No thanks, just start my download.**」の青字のテキストリンクURLをコピーします。
![スクリーンショット 2018-09-04 10.06.12.png](https://qiita-image-store.s3.amazonaws.com/0/245899/ae413787-3fc0-3605-93c7-e4fc1fcbace0.png)


リポジトリ追加のコマンド

```
# yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
```

ここからmysql-community-serverというパッケージとインストールするのですが、標準だとMySQLのバージョンは8.0がインストールされるようになっています。

```
# yum repolist all | grep mysql

// "mysql80-community/x86_64"が"enabled"になっている
mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community    disabled
mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community -  disabled
mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community    disabled
mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community -  disabled
mysql-connectors-community/x86_64  MySQL Connectors Community     enabled:    65
mysql-connectors-community-source  MySQL Connectors Community - S disabled
mysql-tools-community/x86_64       MySQL Tools Community          enabled:    69
mysql-tools-community-source       MySQL Tools Community - Source disabled
mysql-tools-preview/x86_64         MySQL Tools Preview            disabled
mysql-tools-preview-source         MySQL Tools Preview - Source   disabled
mysql55-community/x86_64           MySQL 5.5 Community Server     disabled
mysql55-community-source           MySQL 5.5 Community Server - S disabled
mysql56-community/x86_64           MySQL 5.6 Community Server     disabled
mysql56-community-source           MySQL 5.6 Community Server - S disabled
mysql57-community/x86_64           MySQL 5.7 Community Server     disabled
mysql57-community-source           MySQL 5.7 Community Server - S disabled
mysql80-community/x86_64           MySQL 8.0 Community Server     enabled:    33
mysql80-community-source           MySQL 8.0 Community Server - S disabled
```

これを5.7をインストールされるように変更します。

```
# yum-config-manager --disable mysql80-community
# yum-config-manager --enable mysql57-community
```

再度、`yum repolist all | grep mysql`で確認します。

```
# yum repolist all | grep mysql

// "mysql57-community/x86_64"が"enabled"になっている
mysql-cluster-7.5-community/x86_64 MySQL Cluster 7.5 Community    disabled
mysql-cluster-7.5-community-source MySQL Cluster 7.5 Community -  disabled
mysql-cluster-7.6-community/x86_64 MySQL Cluster 7.6 Community    disabled
mysql-cluster-7.6-community-source MySQL Cluster 7.6 Community -  disabled
mysql-connectors-community/x86_64  MySQL Connectors Community     enabled:    65
mysql-connectors-community-source  MySQL Connectors Community - S disabled
mysql-tools-community/x86_64       MySQL Tools Community          enabled:    69
mysql-tools-community-source       MySQL Tools Community - Source disabled
mysql-tools-preview/x86_64         MySQL Tools Preview            disabled
mysql-tools-preview-source         MySQL Tools Preview - Source   disabled
mysql55-community/x86_64           MySQL 5.5 Community Server     disabled
mysql55-community-source           MySQL 5.5 Community Server - S disabled
mysql56-community/x86_64           MySQL 5.6 Community Server     disabled
mysql56-community-source           MySQL 5.6 Community Server - S disabled
mysql57-community/x86_64           MySQL 5.7 Community Server     enabled:   287
mysql57-community-source           MySQL 5.7 Community Server - S disabled
mysql80-community/x86_64           MySQL 8.0 Community Server     disabled
mysql80-community-source           MySQL 8.0 Community Server - S disabled
```

これでmysql-community-serverのパッケージをインストールします。

```
# yum install mysql-community-server
```

インストールが正しく完了したか確認します。

```
# mysql --version
```

## HostOSとGuestOS間でのファイルの共有
実行環境はGuestOSで、ファイルの編集はHostOSで行いたいためGuestOSの`/home/www/html`ディレクトリとHostOSの作業ディレクトリを紐づけます。Vagrantfileの**config.vm.synced_folder**の項目を修正します。

```text:Vagrantfile
config.vm.synced_folder "HostOSの作業ディレクトリパス", "/home/www/html"
```

GuestOSを再起動します。

```
$ vagrant reload
```


## BOXファイルに書き出して、他マシンに同じ開発環境を構築する

これまでの設定をBOXファイルに書き出します。HostOSのVagrantfileのあるディレクトリ上で下記コマンドを実行します。

```
$ vagrant package
```

生成したBOXファイルを他マシンに複製してvagrantにBOXを追加します。

```
// BOXファイルの追加
$ vagrant box add centos/7 ./package.box

// 追加されたか確認
$ vagrant box list
```

`vagrant init centos/7`で初期化して、`vagrant up`で開発環境が立ち上がります。

これで他マシンに環境を複製することができます。
共有フォルダやIPアドレスなどの設定を引きつづ場合はVagrantfileもコピーします。

## 参考にさせていただいたページ
[CentOS 7 への Apacheインストール。最短でウェブサーバーを構築してテストページを表示する。](https://www.rem-system.com/centos-httpd-inst/)
[MySQL 5.7 を CentOS 7 に yum インストールする手順](https://weblabo.oscasierra.net/installing-mysql57-centos7-yum/)
[CentOS6／CentOS7にPHP5.6／PHP7をyumでインストール](https://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e)
[Apache httpdで作るHTTPSサーバ](https://qiita.com/jinnai73/items/638dcc1434d47b12e6ba)
[【すぐわかる】CentOSのポート開放のやり方](https://eng-entrance.com/linux-centos-port)