CentOS7.3に「みんなでつくろう自転車安全マップ」を設置する

# 今回の動機
[みんなでつくろう自転車安全マップ](https://bicyclesafetymap.jp/)がオープンソース化されたので、自分たちで使ってみようと思い設置してみました。
[GitHubのリポジトリはこちら](https://github.com/bicyclesafetymap/bsmap)

# 構築環境
|Software|Version|
|:---:|:---:|
|CentOS|7.3|
|nginx|1.10.2|
|PHP|5.6.31|
|php-fpm|5.6.31|
|MariaDB|10.2.8|

今回の構築環境は、nginx+php5.6+php-fpm+MariaDBという環境です。
みんなでつくろう自転車安全マップは、FuelPHP1.7で開発されています。
エディターは、nanoを使用しているので、viやvimの方は適時読み替えてください。

## クラウドについて
設置したサーバは、さくらのクラウドを使用しました。
ConoHaのクラウドでも同様に設置が可能でした。

## PHP7について
当初、PHP7で構築していましたが、FuelPHP1.7ではPHP7に対応していませんでした。
PHP7に対応させるためにはFWのバージョンアップが必要なようでした。
oilコマンドでエラーが発生しました。
その為、今回は、PHP5.6.31をすることにしました。

## 常時SSLについて
常時SSLにしなければ、スマートフォンで位置情報の取得が出来ません。
今回の記事では、SSLの設定について詳細に触れていません。
必要であれば以下の記事を参考にして設定や設定変更をお願いいたします。
なお、nginxのみ設定方法と設定ファイルを記事に記載しています。

||参考URL|
|:---:|:---:|
|Apache|[CentOS7でLet's Encryptを使う](http://qiita.com/yasushi00/items/40bdaf8f05017e212325)|
|nginx|[How to Install Let’s Encrypt on Nginx](https://www.upcloud.com/support/install-lets-encrypt-nginx/)|

## FuelPHPの環境について
今回は、**development**で設定しています。
必要に応じて、環境を読み替えて設定してください。

# 環境構築開始
## epelリポジトリの追加
```shell-session:shell
$ sudo yum install epel-release
```
epelリポジトリを指定しないと使用できないように、
[epel][epel-debuginfo][epel-source]の「enabled=1」を「enabled=0」に変更します。

```shell-session:shell
$ sudo nano /etc/yum.repos.d/epel.repo
```

## remiリポジトリの追加
remiリポジトリは、初期設定でリポジトリを指定しないと使用できないようになっています。

```shell-session:shell
$ sudo rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
$ sudo rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

## MariaDB10.2のリポジトリの追加

```shell-session:shell
$ sudo nano /etc/yum.repos.d/MariaDB.repo
```

```repo:/etc/yum.repos.d/MariaDB.repo
 [mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.2/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
```

## Gitのインストール
```shell-session:shell
$ sudo yum install git
```

## nginxのインストール
```shell-session:shell
$ sudo yum install --enablerepo=epel nginx
```

## php56とphp-fpmとその他のインストール
**Apacheの場合は、php-fpmが不要です。**

```shell-session:shell
$ sudo yum install --enablerepo=epel,remi,remi-php56 php php-mbstring php-fpm php-mysql
```
> 同時にApacheもインストールされます。
> この記事には、Apacheの設定も記載していますが今回は、使用していません。

## MariaDBのインストール
```shell-session:shell
$ sudo yum install MariaDB-server MariaDB-client
```

## php-fpmの設定
**Apacheの場合は、この手順は不要です。**
オリジナルを保存し、24行目付近のuserとgroupがapacheになっているものをnginxに変更します。

```shell-session:shell
$ sudo cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.orig
$ sudo nano /etc/php-fpm.d/www.conf
```

## php.iniの設定変更
各ControllerやViewでショートオープンタグが使用されているため設定変更します。

```shell-session:shell
$ sudo nano /etc/php.ini
```

```ini:/etc/php.ini
short_open_tag = On
```

## MariaDBの設定変更
STRICT_TRANS_TABLESがONになっているため、usersのdeleted_atカラムをmigrationした時にエラーが発生しました。
そのため、STRICT_TRANS_TABLESをOFFにしておおよそMySQL5.5レベルのsql_modeに変更します。

```shell-session:shell
$ sudo cp /etc/my.cnf.d/server.cnf /etc/my.cnf.d/server.cnf.orig
$ sudo nano /etc/my.cnf.d/server.cnf
```
[mysqld]グループに以下を記述します。

```conf:/etc/my.cnf.d/server.cnf
sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
```

## 各サービスの自動起動と起動
```shell-session:shell
$ sudo systemctl enable php-fpm.service
$ sudo systemctl enable nginx.service
$ sudo systemctl enable mariadb.service
$ sudo systemctl start php-fpm.service
$ sudo systemctl start nginx.service
$ sudo systemctl start mariadb.service
```

## MariaDBの初期設定
```shell-session:shell
$ sudo mysql_secure_installation
```
以下のような質問がされますので、必要に応じて設定してください。
基本的には、Yで問題はないと思います。

|表示|説明|
|:---:|:---:|
|Enter current password for root (enter for none):|MariaDBの現在のrootユーザパスワード入力(初期設定時は何も設定されていない)|
|Set root password? [Y/n]|rootユーザのパスワードを設定するかどうか|
|Remove anonymous users? [Y/n]|初期設定で作成されている「anonymous」ユーザを削除するか|
|Disallow root login remotely? [Y/n]|MariaDBの「root」ユーザのリモートログインを禁止するか|
|Remove test database and access to it? [Y/n]|初期設定で作成されている「test」データベースを削除するか|
|Reload privilege tables now? [Y/n]|今設定したユーザ設定をすぐに反映させるか|

## ユーザーとデータベースの作成
```shell-session:shell
$ mysql -u root -p
```

今回は、User: bsmap_adminとPassword: passwordでユーザーを作成します。
もちろん、構築時は、変更してください。

```sql:sql
MariaDB [(none)]> create database bsmap;
MariaDB [(none)]> grant all on bsmap.* to 'bsmap_admin'@'localhost' identified by 'password';
MariaDB [(none)]> exit;
```

## GitHubからソースコードをダウンロード
chownのuserは、作業ユーザーを指定してください。
**今回は、nginxを対象にしているため、nginxのディレクトリを使用します。**

```shell-session:shell
$ cd /usr/share/nginx
$ sudo git clone https://github.com/bicyclesafetymap/bsmap.git
$ sudo chown -R user:user bsmap
```

## ディレクトリの作成

logディレクトリを作成します。

```shell-session:shell
$ mkdir /usr/share/nginx/bsmap/fuel/app/logs
```

uploadディレクトリの作成とパーミッション変更をします。

```shell-session:shell
$ mkdir /usr/share/nginx/bsmap/htdocs/upload
$ chmod 777 /usr/share/nginx/bsmap/htdocs/upload
```

## 必要なコンポーネントのインストール
```shell-session:shell
$ cd /usr/share/nginx/bsmap
$ php composer.phar install
```

## bsmapのデータベース接続設定

2つのファイルを書き換えます。

1つ目のファイルは、以下のファイル

```shell-session:shell
$ nano /usr/share/nginx/bsmap/fuel/app/config/db.php
```

```PHP:/usr/share/nginx/bsmap/fuel/app/config/db.php
return array(
	'development' => array(
	    'type'           => 'mysqli',
	    'connection'     => array(
	        'hostname'       => 'localhost',
	        'port'           => '3306',
	        'database'       => 'bsmap',
	        'username'       => 'bsmap_admin',
	        'password'       => 'password',
	        'persistent'     => false,
	        'compress'       => false,
	    ),
	    'identifier'     => '`',
	    'table_prefix'   => '',
	    'charset'        => 'utf8',
	    'enable_cache'   => true,
	    'profiling'      => false,
	    'readonly'       => false,
	),
);
```

2つ目のファイルは、以下のファイル

```shell-session:shell
$ nano /usr/share/nginx/bsmap/fuel/app/config/development/db.php
```

```PHP:/usr/share/nginx/bsmap/fuel/app/config/development/db.php
return array(
        'default' => array(
                'connection'  => array(
                        'dsn'        => 'mysql:host=localhost;dbname=bsmap',
                        'username'   => 'bsmap_admin',
                        'password'   => 'password',
                ),
        ),
);
```

## bsmap用GoogleMapsAPIkeyの修正
以下のファイルのGoogleMapsAPIKeyをKey取得後編集してください

- fuel/app/views/admin/point/_form.php
- fuel/app/views/map/streetview.php
- fuel/app/views/map/detail.php
- fuel/app/views/map/index.php
- fuel/app/views/report/confirm.php
- fuel/app/views/report/latlong.php

## データベースのmigration
```shell-session:shell
$ FUEL_ENV=development php oil r migrate
```

## nginxの設定
```shell-session:shell
$ sudo nano /etc/nginx/conf.d/bsmap.example.com.conf
```

```conf:/etc/nginx/conf.d/bsmap.example.com.conf
server {
  listen 80;
  server_name bsmap.example.com;
  root /usr/share/nginx/bsmap/htdocs;
  index index.php;

  charset utf-8;

  location / {
    if (-f $request_filename) {
      expires 30d;
      break;
    }
    if (!-e $request_filename) {
      rewrite ^(.*)$ /index.php?q=$1 last;
    }
  }


  location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param FUEL_ENV development;
    include fastcgi_params;
  }
}
```

設定ファイルの再読込

```shell-session:shell
$ sudo systemctl reload nginx.service
```

## firewalldのhttpとhttpsポート開放
ここで一度アクセスしてテストするためにポートを開放します。
この後、常時SSL化もするため同時にhttpsポートも開放します。

```shell-session:shell
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent
$ sudo firewall-cmd --reload
```

## Let’s Encryptを使った常時SSL
```shell-session:shell
$ sudo yum install certbot
$ sudo certbot certonly --webroot -w /usr/share/nginx/bsmap/htdocs -d bsmap.example.com
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
```

上記のコマンドが全て成功した後に設定ファイルを以下の通りに変更

```shell-session:shell
$ sudo nano /etc/nginx/conf.d/bsmap.example.com.conf
```

httpでアクセスが来たときには、httpsへリダイレクトする設定も入れています。

```conf:/etc/nginx/conf.d/bsmap.example.com.conf
server {
    listen 80;
    server_name bsmap.example.com;
    return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name bsmap.example.com;
  root /usr/share/nginx/bsmap/htdocs;
  index index.php;

  charset utf-8;

  ssl_certificate /etc/letsencrypt/live/bsmap.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/bsmap.example.com/privkey.pem;
  ssl_trusted_certificate /etc/letsencrypt/live/bsmap.example.com/fullchain.pem;

  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_session_tickets on;

  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK";
  ssl_prefer_server_ciphers on;

  add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains;';

  location / {
    if (-f $request_filename) {
      expires 30d;
      break;
    }
    if (!-e $request_filename) {
      rewrite ^(.*)$ /index.php?q=$1 last;
    }
  }

  location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param FUEL_ENV development;
    include fastcgi_params;
  }
}
```

設定ファイルの再読込

```shell-session:shell
$ sudo systemctl reload nginx.service
```

## Apacheの設定
**今回の記事は、nginxが対象となっているため、ソースコードは、nginxのディレクトリに配置しています。**
**ApacheでのSSLについてはテストをしていません。常時SSL化する場合は、冒頭の記事を参考に設定してください。**

```shell-session:shell
$ sudo nano /etc/httpd/conf.d/bsmap.example.com.conf
```

```conf:/etc/httpd/conf.d/bsmap.example.com.conf
<VirtualHost *:80>

  DocumentRoot /usr/share/nginx/bsmap/htdocs
  ServerName bsmap.example.com
  <Directory "/usr/share/nginx/bsmap/htdocs">
    Options FollowSymlinks Includes
    AllowOverride All
    Require all granted
  </Directory>

  SetEnv FUEL_ENV development

</VirtualHost>
```

設定ファイルの再読込

```shell-session:shell
$ sudo systemctl reload httpd.service
```


# 実際の運用に際して
実際の運用には、「このプロジェクトについて」「運営」「利用規約」の各ページの内容が、本家の公開ページのままになっているので、編集する必要があります。

# 参考
以下のページを参考にさせていただきました。
[MariaDB Foundation](https://downloads.mariadb.org/mariadb/repositories/#mirror=yamagata-university&distro=CentOS&distro_release=centos7-amd64--centos7&version=10.2)
[CentOS7 + php7 + nginx + php-fpm環境にwordpressインストール](http://www.server-memo.net/memo/wordpress/nginx-install.html)
[CentOSでFuelPHPをnginxで動かしてみたときのメモ](http://qiita.com/ryurock/items/f5e25699961824376454)
[How to Install Let’s Encrypt on Nginx](https://www.upcloud.com/support/install-lets-encrypt-nginx/)
[Let's Encrypt 総合ポータル](https://letsencrypt.jp/usage/)