CentOS7にPHP5.6,MySQL5.7,Nginx1.8の環境構築

## はじめに
MySQLのgeometryカラムを使ってみたかったので、VagrantでCentOS7,PHP5.6,MySQL5.7,Nginx1.8の環境構築してみました。
fuelphpで開発するのでNginxの設定箇所にfuelphp用の設定もありますがコメントアウトしてます。
当手順ではfuelphpのインストールは含んでいません。

## ホスト側構成
- OSX 10.5.1
- Vagrant 1.8.1
- VertualBox 5.0.12

## VM側構成
- CentOS 7.0.1406
- PHP 5.6.17
- MySQL 5.7.10
- Nginx 1.8.0


## 元となるCentOS7のBOX準備  
[vagrantbox.ex](http://www.vagrantbox.es/)にCentOS7.0 x86_64 minimal (VirtualBoxGuestAddtions 4.3.14)があったので、
そちらをベースに構築します。

- boxの追加  
`vagrant box add centos7 https://f0fff3908f081cb6461b407be80daf97f07ac418.googledrive.com/host/0BwtuV7VyVTSkUG1PM3pCeDJ4dVE/centos7.box`
- vagrant初期化  
`vagrant init centos7`
- 生成されたVagrantfileの修正  

```
# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure(2) do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://atlas.hashicorp.com/search.
  config.vm.box = "centos7"

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: "192.168.33.10" # ⇦ HOSTからVMにアクセス可能にするためコメント外す。他のVagrantがあるならip変える。

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  # config.vm.network "public_network"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
  # such as FTP and Heroku are also available. See the documentation at
  # https://docs.vagrantup.com/v2/push/atlas.html for more information.
  # config.push.define "atlas" do |push|
  #   push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
  # end

  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   sudo apt-get update
  #   sudo apt-get install -y apache2
  # SHELL

  # vm側の時刻をhostに合わせる
  # VM立ち上げっぱなしにしてPCスリープしたあとに見るとズレくる？
  # CentOS7からはChronyがntpの代わりになったようなのでそっちに変更。
  # config.vm.provider :virtualbox do |vb|
  #  vb.customize ["setextradata", :id, "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled", 1]
  # end
end
```

- vagrant起動  
`vagrant up`
- vmに接続  
`vagrant ssh`  

## VM側作業 環境設定  
vm側作業はすべてrootユーザーで実施を想定。  
`su - root`

- バージョン確認
`cat /etc/redhat-release`
CentOS7.0より最新を使いたい場合 -> `yum -y upgrade`
package updateの場合 -> `yum -y update`
*upgrade,updateしなくても可

- selinux無効
`setenforce 0`

- selinux永続無効
`sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux` 
`sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config`  
*1番目だけだとサーバー再起動時に戻ってしまっていた。2番目だけでも平気？

- selinux確認
`getenforce`
`Permissive`が表示されればOK

- 時刻を日本時間に設定
~~`\cp -f /usr/share/zoneinfo/Japan /etc/localtime`~~
`timedatectl set-timezone Asia/Tokyo`

- 時刻同期
`yum -y install chrony`
`vim /etc/chrony.conf`

```  
+ server ntp.nict.jp iburst
+ server ntp1.jst.mfeed.ad.jp iburst
+ server ntp2.jst.mfeed.ad.jp iburst
+ server ntp3.jst.mfeed.ad.jp iburst
- #server 0.centos.pool.ntp.org iburst
- #server 1.centos.pool.ntp.org iburst
- #server 2.centos.pool.ntp.org iburst
- #server 3.centos.pool.ntp.org iburst
```

## VM側設定 MySQL5.7インストール
- mariadbと競合しないように削除
`yum -y remove mariadb-libs`
`rm -rf /var/lib/mysql/`

- MySQLインストール
`yum -y install http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm`
`yum -y install mysql-community-server`

## PHP5.6インストール  
- epelインストール  
`rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/7/x86_64/e/epel-release-7-5.noarch.rpm`
- remiインストール  
`rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm`
- PHPインストール(インストールモジュールは任意で)  
`yum -y install --enablerepo=remi --enablerepo=remi-php56 php php-devel php-gd php-mbstring php-mcrypt php-memcache php-mysql php-mysqlnd php-pdo php-gd php-fpm php-cli php-xml phpMyAdmin`

## Nginxインストール
`rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm`
`yum -y install nginx`

## サービス起動
- 一旦、MySQL、firewall、chronyのサービス起動  
`systemctl start mysqld.service && systemctl start firewalld.service && systemctl start chronyd.service`

## 各種サービスの自動起動設定  
- Nginx,php-fpm,MySQL,firewallの自動起動を設定  
`systemctl enable nginx.service && systemctl enable php-fpm.service && systemctl enable mysqld.service && systemctl enable firewalld.service && systemctl enable chronyd`

## MySQL設定
- my.cnfの修正(文字コードなど)  
`vi /etc/my.cnf`  

```
[mysqld]
+ character-set-server = utf8 		# 文字コード
+ validate_password = OFF 			# パスワードを複雑化していないと受け付けない設定を無効
+ default_password_lifetime = 0 	# パスワード有効期限を無効。デフォルトだと365日で切れてログインできなくなる
+ log_timestamps=system 			# log出力タイムスタンプをJST。デフォルトだとUTC
# my.cnfの設定はもっとやることあると思うがとりあえず。
```

- cnf修正したのでMySQLを再起動
`systemctl restart mysqld.service`  

- root初期パスワード確認
`grep -e 'A temporary password is generated for root@localhost' /var/log/mysqld.log`

- rootパスワードなどを変更
`mysql_secure_installation`

```
2016-01-07T00:28:18.308696Z 1 [Note] A temporary password is generated for root@localhost: L!omqpK#k4bq
[root@localhost ~]# mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root:[grepで確認したパスワードを入力] 

The existing password for the user account root has expired. Please set a new password.

New password: [vagrant としました]

Re-enter new password: [vagrant]
The 'validate_password' plugin is installed on the server.
The subsequent steps will run with the existing configuration
of the plugin.
Using existing password for root.

Estimated strength of the password: 0 
Change the password for root ? ((Press y|Y for Yes, any other key for No) : No # 英数記号など含んだパスワードで設定するか？って聞いてくるけど設定しない。

 ... skipping.
By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) : y # anonymous ser削除する
Success.


Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.

By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.


Remove test database and access to it? (Press y|Y for Yes, any other key for No) : y # test dbを削除する
 - Dropping test database...
Success.

 - Removing privileges on test database...
Success.

Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y # 再起動する
Success.

All done! 
```

## PHP設定
- php.iniの修正
timezone,session.save_pathを修正(CentOS7では/tmpにファイル置いてもシステムで消されるため)
`sed -i 's/;date.timezone =$/date.timezone = "Asia\/Tokyo"/g' /etc/php.ini`
`sed -i 's/;session.save_path = "\/tmp"$/session.save_path = "\/var\/lib\/php\/session"/g' /etc/php.ini`

- session.save_pathのグループ変更
`chown :vagrant /var/lib/php/session`

- php-fpm.cnfの修正
user,groupをvagrantに修正
`sed -i "s/user = apache$/user = vagrant/g" /etc/php-fpm.d/www.conf`
`sed -i "s/group = apache$/group = vagrant/g" /etc/php-fpm.d/www.conf` 

## Nginx設定
- ドキュメントルートディレクトリ作成
`rm -rf /var/www && mkdir -p /var/www/public`

- 確認用phpファイル作成
`echo '<?php phpinfo();' > /var/www/public/index.php`

- user,group変更
`chown -R vagrant:vagrant /var/www`

- conf作成
`vi /etc/nginx/conf.d/dev.conf`

```
# app
server {
    listen       80;
    server_name  192.168.33.10;
    charset utf-8;

    # file_upload_size.default 1mb.
    client_max_body_size  32M;

    # access_logはformatは指定可能だが、levelは指定不可
    # "main"と記載しているのは、nginx.confにmainという名前でformatを設定していてそれを使っている
    access_log  /var/log/nginx/access.log main;

    # error_logはformatは指定不可だが、levelは指定可能
    # logレベルはdebug,info,notice,warn,error,critから選ぶ
    error_log  /var/log/nginx/error.log debug;

    location / {
        root   /var/www/public;
        index  index.php;

        # ===fuelphp使うなら必要===
        # rewrite setting
        # try_files $uri $uri/ /index.php$is_args$args;
        # ===/ fuelphp使うなら必要===
    }

    location ~ \.php$ {
        root           /var/www/public;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        # fastcgi_param  FUEL_ENV "production";# ===fuelphp使うなら必要===
        include        fastcgi_params;
    }
}

# phpmyadmin
server {
    listen       8080;
    server_name  192.168.33.10;

    charset utf-8;
    access_log  /var/log/nginx/phpmyadmin.access.log  main;
    error_log  /var/log/nginx/phpmyadmin.error.log  error;

    location / {
        root   /usr/share/phpMyAdmin;
        index  index.php;
    }

    location ~ \.php$ {
        root           /usr/share/phpMyAdmin;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}
```

- /etc/nginx/nginx.confの修正
`sed -i "s/user  nginx;$/user  vagrant;/g" /etc/nginx/nginx.conf` 

- /etc/nginx/conf.d/default.confを使わないのでリネーム
`mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bk` 

- php-fpm,nginx起動
php-fpm,Nginxの設定ファイルを更新したので再起動
`systemctl start nginx.service && systemctl start php-fpm.service`

## firewall設定
- 完全無効
`systemctl stop firewalld`
`systemctl disable firewalld`
*開発環境なので上記のみで可。勉強がてら上記ではなく、下記設定にしてみました。

- http,https,8080ポートを永続許可
`firewall-cmd --add-service=http --permanent && firewall-cmd --add-service=https --permanent && firewall-cmd --add-port=8080/tcp --permanent`

- firewall再起動
`firewall-cmd --reload`

- 設定内容確認
`firewall-cmd --list-services`
`firewall-cmd --list-ports`

## アクセス確認
- PHP
[http://192.168.33.10](http://192.168.33.10)
phpinfoが出る事

- phpMyAdmin
[http://192.168.33.10:8080](http://192.168.33.10:8080)
id:root
pw:vagrant
でログイン出来る事

## ハマったところ
どうも繋がらないと思ったら、selinuxが有効だった。。。
どうも繋がらないと思ったら、firewallが有効だった。。。

（´-`）.｡oO（今年はAnsible,Dockerを覚えるぞ）