FreeBSD で Nginx1.14 & PHP7.12 & MySQL8.0 環境を構築！

FreeBSD 11.2にNginx & PHP(php-fpm) & MySQLを構築します。
これでFreeBSD上でPHPのウェブアプリケーションが作り放題になります。


# 環境
| ソフトウェア | バージョン |
|---|---|---|
| FreeBSD   | 11.2 |
| Nginx     | 1.14.1 |
| PHP       | 7.2.12 |
| MySQL     | 8.0.12 |

作業に関してはOSを素でインストールした直後からの手順です。
全部rootで作業しています。


# pkgを最初に実行したとき
こんなこと聞かれるのでyを押して進みましょう

```
# pkg -y
The package management tool is not yet installed on your system.
Do you want to fetch and install it now? [y/N]: y
```


# pkgのリポジトリをlatestにしてから必要なpkgをインストール
pkgのデフォルトのリポジトリのquarterlyは更新頻度が遅いためlatestにします
リポジトリの変更は/etc/pkg/FreeBSD.confを書き換えてもいいですが、
/usr/local/etc/pkg/repos/FreeBSD.confを作って値を上書きしてみます

```
# mkdir -p /usr/local/etc/pkg/repos/
# echo 'FreeBSD: { url: "pkg+http://pkg.FreeBSD.org/${ABI}/latest" }' > /usr/local/etc/pkg/repos/FreeBSD.conf
# pkg update
# pkg install -y php72 mysql80-server nginx php72-mysqli vim-console
```
php-fpmはphp72に含まれています
nginxのmainline版(現在は1.15)を使いたい場合はnginx-develを指定すればインストールできます
vim-consoleは日本語ファイルを作成するために使います
（vimだとX11系pkgなどが色々インストールされて時間かかるため）
インストールされたパッケージは↓だけ

```
# pkg info
icu-63.1,1                     International Components for Unicode (from IBM)
libargon2-20171227_1           Memory hard password hashing program and library
libedit-3.1.20170329_2,1       Command line editor library
libevent-2.1.8_2               API for executing callback functions on events or timeouts
liblz4-1.8.3,1                 LZ4 compression library, lossless and very fast
libxml2-2.9.7                  XML parser library for GNOME
mysql80-client-8.0.12_1        Multithreaded SQL database (client)
mysql80-server-8.0.12_1        Multithreaded SQL database (server)
nginx-1.14.1_5,2               Robust and small WWW server
pcre-8.42                      Perl Compatible Regular Expressions library
perl5-5.26.2_2                 Practical Extraction and Report Language
php72-7.2.12                   PHP Scripting Language
php72-mysqli-7.2.12            The mysqli shared extension for php
pkg-1.10.5_5                   Package manager
protobuf-3.5.2_1,1             Data interchange format library
re2-20180901                   Fast C++ regex library
vim-console-8.1.0502           Improved version of the vi editor (console only)
```


# MySQLの起動＆設定
```
# sysrc mysql_enable="YES"
# /usr/local/etc/rc.d/mysql-server start
# mysqladmin password 'tekito-pass' -u root
```
FreeBSDのMySQL8.0.12では5.7の時と違いデフォルトはパスワード無しのようです
ちなみにMySQLの設定ファイルは/usr/local/etc/mysql/my.cnfにあるので必要に応じて変更しましょう


# Webアプリケーション用DB＆ユーザ＆テーブル作成
```
# mysql -u root -p'tekito-pass'
mysql> CREATE DATABASE webapp;
mysql> CREATE USER 'webapp_user'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'webappass';
mysql> GRANT ALL ON webapp.* TO 'webapp_user'@'127.0.0.1' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
```
MySQL8からユーザの作成がGRANTだけで出来なかったので注意
https://www7390uo.sakura.ne.jp/wordpress/archives/456
認証プラグインをmysql_native_password（今まで通り）にしないと認証に失敗するので注意
https://yoku0825.blogspot.com/2018/01/mysql-804.html
PHP extensionのmysql_xdevapiだとcaching_sha2_password対応しているがpkgにないので今まで通りで
http://php.net/manual/ja/book.mysql-xdevapi.php

テーブル作成

```
# mysql -h 127.0.0.1 -u webapp_user -p'webappass' webapp
mysql> CREATE TABLE IF NOT EXISTS `access` (
        `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 
        `ip` INTEGER UNSIGNED NOT NULL DEFAULT 0,
        `time` DATETIME       NOT NULL DEFAULT '1000-01-01 00:00:00',
        PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1;
```





# PHP(PHP-FPM)の設定
```
# cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini
# sysrc php_fpm_enable="YES"
# /usr/local/etc/rc.d/php-fpm start
```
php-fpmの設定ファイルは/usr/local/etc/php-fpm.confにあるので必要に応じて変更しましょう
includeされている/usr/local/etc/php-fpm.d/www.confをみると127.0.0.1:9000で起動するようです


# Nginxの設定
/usr/local/etc/nginx/nginx.confを下記の内容にします（ほぼデフォルトのまま必要なところのみ変更＆有効）

```
user  nobody;
worker_processes  auto;
error_log  /var/log/nginx/error.log;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile   on;
    tcp_nopush on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        charset utf-8;
        root   /usr/local/www/nginx;
        location / {
            index  index.html index.htm index.php;
        }
        location ~ \.php$ {
            include /usr/local/etc/nginx/fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_pass   127.0.0.1:9000;
        }
    }
}
```
Nginxの起動

```
# sysrc nginx_enable="YES"
# /usr/local/etc/rc.d/nginx start
```

# Webアプリケーション開発
ここまででWebアプリケーションを開発できる環境が整いました
簡単なプログラムを書いて動きを確かめてみましょう
/usr/local/www/nginx/index.php を下記の内容で作成します

```
<?php
header("Content-type: text/plain");

$host = "127.0.0.1";
$user = "webapp_user";
$pass = "webappass";
$dbname = "webapp";
$charset = "utf8mb4";

# エラー処理は省略
$mysqli = mysqli_init();
$mysqli->real_connect($host, $user, $pass, $dbname);
$mysqli->set_charset($charset);
$mysqli->autocommit(TRUE);

# アクセスしてきたクライアントのIPアドレスをINSERT
$sql = sprintf('INSERT INTO `access` SET `ip` = %d, `time` = NOW()', ip2long($_SERVER["REMOTE_ADDR"]));
$mysqli->query($sql);

# アクセス履歴を最新順に表示(最大10件)
$sql = "SELECT * FROM `access` ORDER BY `time` DESC, `id` DESC LIMIT 10";
$res = $mysqli->query($sql);
while ($row = $res->fetch_assoc()) {
	printf("%s:  %s  %s\n", $row["id"], long2ip($row["ip"]), $row["time"]);
}
$res->free_result();
$mysqli->close();
```
Webブラウザから下記にアクセスして動きを確認してみましょう！
http://サーバのIPアドレス/index.php