CentOS7.4上でLaravelプロジェクトを動かすための環境を作る

# はじめに
![image.png](https://qiita-image-store.s3.amazonaws.com/0/165355/603085ba-32ef-2d09-76a9-426e9f1943ba.png)
いきなり本番環境を構築するのは怖すぎるので仮想マシン上で設定したときの備忘録。
過去に[**こんなの**](https://qiita.com/tosite0345/items/1e5bbeb33508abb1eaae)執筆してたけど今見たら足りてない部分ががが。

# 環境 (2017-11-07時点)

|サービス名|バージョン|
|:--:|----|
|**CentOS**|CentOS Linux release 7.4.1708 (Core)|
|**Apache**|Apache/2.4.6|
|**PHP**|PHP 7.1.11 (cli)|
|**MySQL**|Ver 14.14 Distrib 5.7.20|
|**phpMyAdmin**|4.7.5|
|**supervisor**|3.1.4|
|**git**|1.8.3.1|
|**composer**|1.5.2|


# 注意事項
+ Laravelプロジェクト設置場所を``[project]``と表記することにする。
+ ここでは``/var/www/html``配下に``[project]``ディレクトリを作成したと仮定。


# VM環境準備
## BOXファイルを取ってくる
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/dba6565d-033e-67b9-164a-e8c4c470466a.png" height=80px>

### うまくいった方法
こちらはvagrantが提供しているBOXファイルをダウンロードして使う方法。

```bash:console
vagrant box add centos/7 https://atlas.hashicorp.com/centos/boxes/7
mkdir centos7 # make vagrant directory
vagrant init centos/7
vagrant up
vagrant ssh
```

#### "rsync" could not be found on your PATH（Windowsのみ？）

vagrantは自動でディレクトリマウント方法``(rsync)``を指定しようとするが、``rsync``が入っていない場合エラーを投げる。
いつまでも起動できない。
そこで、

```bash:Vagrantfile
Vagrant.configure("2") do |config|
    ########
    # 省略
    ########

    config.vm.box = "centos/7"

    # コメントアウトを外す
    config.vm.network "private_network", ip: "192.168.33.10"

    # 新しく追加する
    config.vm.synced_folder".", "/vagrant", disabled:true

    ########
    # 省略
    ########
end
```

これでおｋ（[**参考**](https://qiita.com/MuuKojima/items/a298a7dc76784052da1d) ）。


### うまく行かなかった方法

素のCentOS isoイメージでBOX化しようとした。
かなりハマったので今回はパス。

```bash:console
# vagrant box add [any_box_name] [repo]
# repo_name = centos7_x64
# repo      = https://github.com/holms/vagrant-centos7-box/releases/download/7.1.1503.001/CentOS-7.1.1503-x86_64-netboot.box
# mkdir centos7 # make vagrant directory
# vagrant init centos7_x64
# vagrant up
# vagrant ssh
```

ネットワークインターフェースでエラーが頻発したので却下。

>
```bash:エラー内容
Job for network.service failed. See 'systemctl status network.service' and 'journalctl -xn' for details.
# とか
Unit network.service entered failed state.
# とか
```



## GUI環境の準備（不要ならスキップ）
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/190ef136-f800-0a22-614e-e6b1186e35df.png" height=150px>

たまにはGUIで起動したいときあるやん？
なければ読み飛ばし推奨。

```bash:console
sudo yum groupinstall -y "GNOME Desktop"
startx
```
[**参考**](http://blog.amedama.jp/entry/2015/09/01/232339)



# CentOS サービス準備

## Apache (httpd) サービスインストール + Firewallを無効化
![image.png](https://qiita-image-store.s3.amazonaws.com/0/165355/0b45d1c3-09fc-ad50-06c8-e95462a4dfdf.png)

言わずと知れた``Apache``。
本当は``nginX``入れようと思ってたんだけど、テストでインストールした際の感想

+ 慣れていないだけだが構築が割と面倒くさい
+ PHPを利用できるようにするだけでもかなり手間
+ 設定変更してない[**標準環境だとPOSTができない**](https://qiita.com/toris-birds/items/1e99e2be0e337253fe83)って何事？
+ そもそも社内サービスだからそんなにアクセス数ない → nginXのメリットェ
+ トラブったときのメンテナンスに手を取られそう

という理由から、今回はApacheを選定。

```bash:console
yum -y install httpd
systemctl start httpd
systemctl stop firewalld
# 確認したかったら以下のコマンドで
systemctl status httpd
systemctl status firewalld
```

### 起動時に自動でサービス開始／停止ができるようにする

```bash:console
systemctl is-enabled firewalld
# enable
systemctl disable firewalld
# 確認作業
systemctl is-enabled firewalld
# disable

systemctl is-enabled httpd
# disable
systemctl enable httpd
# 確認作業
systemctl is-enabled firewalld
# enable
```


## PHP (+etc) サービス準備
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/32ee2001-50eb-4649-222a-8d6a12aa109b.png" height=100px>

PHPとか諸々周辺パッケージをまとめてインストール。

```bash:console
# remiリポジトリ追加
yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
yum install -y --enablerepo=remi-php71 php php-cli php-common php-devel php-fpm php-gd php-mbstring php-mysqlnd php-pdo php-pear php-pecl-apcu php-soap php-xml php-xmlrpc
# インストール確認
php -v
```

## MySQLサービス準備
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/aa88edae-ecea-2d2e-da81-c677d519a200.png" height=120px>

### インストールまで

```bash:console
# 最初にMariaDBが入っている場合、アンインストールする
yum list installed | grep mariadb
yum remove mariadb-libs
rm -rf /var/lib/mysql/
# 改めてMySQLのインストールを行う
sudo yum -y localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
yum info mysql-community-server
yum -y install mysql-community-server
# サービス起動
systemctl status mysqld
systemctl start mysqld

### 初期パスワードを取得する
cat /var/log/mysqld.log | grep root
2016-03-15T02:44:33.949457Z 1 [Note] A temporary password is generated for root@localhost: '初期パスワード'
```

```bash:MySQL環境のセットアップ
### 初期セットアップ
mysql_secure_installation

# Securing the MySQL server deployment.
Enter password for user root: 'さっきの初期パスワードを入力'
# The existing password for the user account root has expired. Please set a new password.

New password:
Re-enter new password:
# 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: 100

Change the password for root ? ((Press y|Y for Yes, any other key for No) : y
# Rootユーザーのパスワードを変更しますか？ - はい
New password:
Re-enter new password:

# Estimated strength of the password: 100

Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
# 提供されたパスワードの利用を続けますか？ - はい

# 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
# 匿名ユーザーを削除しますか？　- はい

# 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) : n
# リモートからのRootユーザーログインを拒否しますか？ - いいえ

#  ... skipping.
# 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
# テスト用データベースを削除しますか？ - はい

#  - 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!

mysql -u root -p
```


### プロジェクト用のMySQLユーザーの作成・権限付与

```mysql:console
/* ユーザーを作成して権限を与える */
create user (ユーザー) identified by '(password)';
grant (権限) on (レベル) to (ユーザー);

/*
実例：
sampleユーザーにSELECT, INSERT, UPDATE, DELETEを与える。
adminユーザーにすべての権限を与える。
*/ 
create user sample identified by 'sample';
create user admin  identified by 'admin';
grant select,insert,update,delete on *.* to sample;
grant all on *.* to admin;
```
[**参考**](http://vdeep.net/centos7-mysql)

セキュリティ的にパスワードは大文字 + 数字 + 記号を織り交ぜないとエラーになるっぽい。

## データベースディレクトリの場所を変更する [2017-12-05追記]
MySQL標準だと``/var/lib/mysql``配下にDBを作成するようになっている。
バックアップ的な意味でも別のパーティションに保存するようにしておいたほうがいいため、設定の変更を行う。

[**この前書いた記事**](https://qiita.com/tosite0345/items/8a8355525bc58d051f4a)を参考に設定する。

## phpMyAdmin準備
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/ba49424b-e8e9-e1ff-0743-682c31f1d424.png" height=150px>

### 事前準備

```bash:console
rpm --import https://rpms.remirepo.net/RPM-GPG-KEY-remi
yum install -y yum-utils https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum-config-manager --enable remi-php71
yum install -y php php-mbstring php-intl
yum install -y php-mysqlnd
```

### remi.repoファイル編集
``/etc/yum.repos.d/remi.repo``最終行に以下を追加。

```ini:/etc/yum.repos.d/remi.repo
; 新しく追加
includepkgs=phpMyAdmin php-phpmyadmin-sql-parser php-google-recaptcha
```

```bash:console
yum-config-manager --enable remi
yum install -y phpMyAdmin
```

### シンボリックリンクの作成
```
cd /var/www/html
ln -s /usr/share/phpMyAdmin
```

### アクセス権の修正
これを行わないと画面が真っ白になったり、``You don’t have permission to access /phpMyAdmin/ on this server.``とか怒られたりします。
どうも標準だと``local``以外のアクセスを拒否してるみたい。
ただ、これだと**危険が危ない状態**になりかねないので、一通りセットアップが終わったら``local``からしか接続できないようにしたり、アクセスできるユーザーを絞ったり、そもそもシンボリックリンクを削除してアクセス不可にするなどの対応を検討したりしたほうがいいかも。

```bash:/etc/httpd/conf.d/phpMyAdmin.conf
########
# 省略
########

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin

########
# 省略
########

<Directory /usr/share/phpMyAdmin/>
   AddDefaultCharset UTF-8
   <IfModule mod_authz_core.c>
     # Apache 2.4
     # Require local      # コメントアウト
     Require all granted  # 追加
   </IfModule>
    ########
    # 省略
    ########
```

この辺りを[**参考**](https://qiita.com/100/items/8e9d9540845cc23e6111)にさせていただきました。
``systemctl restart httpd``しておく。

### phpMyAdmin 環境保管領域が完全に設定されていないためうんたらかんたら
この辺りを[**参考**](https://www.dbonline.jp/phpmyadmin/install/index3.html)にsqlファイルのインポートを行った。

## アクセス許可するIPを制限する [2017-12-05追記]
いくら社内システムとは言えこのままだとどのIPからでもアクセスできてしまうため、非常にまずい。
自分自身のIP以外からは接続できないように設定を変更していく。

先程いじった``etc/httpd/conf.d/phpMyAdmin.conf``の中身を更にいじる。

```bash:/etc/httpd/conf.d/phpMyAdmin.conf
########
# 省略
########

Alias /phpMyAdmin /usr/share/phpMyAdmin
Alias /phpmyadmin /usr/share/phpMyAdmin

########
# 省略
########

<Directory /usr/share/phpMyAdmin/>
   AddDefaultCharset UTF-8
   AllowOverride All
   <IfModule mod_authz_core.c>
     # Apache 2.4
     Require all denied     # 追加
     Require local          # コメントアウトを外す
     # Require all granted  # コメントアウト

     #########################
     # 参考：Apache 2.2系以前
     #########################
     # Order Deny, All
     # Deny from All
     # Allow from localhost

   </IfModule>
    ########
    # 省略
    ########
```

どうやら``Apache 2.4``系からアクセス制限の書き方が変わった模様。
[**こちら**](https://ex1.m-yabe.com/archives/2154)の記事を参考にさせていただきました。感謝。

## gitコマンドのインストール
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/2fc0d3d7-3505-0fac-1ec3-73e73b7a485e.png" height=80px>

だがしかしこのコマンドを叩くだけだとバージョンが1.8.1になってしまう模様。
とりあえず運用はできているので...とは思うが、どうにも気持ち悪い...。

```bash:console
yum install -y git
```

## Windowsファイルサーバーをマウントする（不要ならスキップ）
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/0864c3f2-96c3-4216-8feb-9a5372071d68.png" height=170px>

色々と使う予定があったので。


```bash:console
mkdir /mnt/server
mount -t cifs -o username=(username),password=(password) //(file_server_ip)/(directory) /mnt/server

# cifsなんてないとかなんとか言われたら
yum install -y cifs-utils
```

### ついでに自動化

``fstab``ファイルに追記することで起動時に自動でマウントしに行くようになる。
しかしながら``nofail``オプションを付けておかないと（少なくともvagrant上では）タイムアウトの連続で起動できなくなった。
恐らく実機であれば回避方法はあるのだろうが、念のためオプションは付けておく。

```ini:/etc/fstab
//(file_server_ip)/(directory)       /mnt/server   cifs    username=(username),password=(password),uid=apache,gid=apache        0       0       nofail
# ここでnofailを記述しておかないと起動できないループに陥る可能性がある
# 2017-12-05追記：UIDでLinux側の実行ユーザーを指定する
```

起動確認も行う。

```bash:console
mount -a
```

## Supervisorサービスを入れる
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/f33c4980-2d93-ac61-c575-7d19da13cbcc.png" height=200px>

``supervisor``でジョブ監視したり、Laravelキューワーカーとして利用したり。
サービス自体は先に入れておいて構わないが、実際に動作させる場合は先に**プロジェクト配置**をしておいた方がいいと思う。

```bash:console
yum install -y supervisor
```

とりあえず生きている設定だけ。

<details><summary>**設定ファイル（展開）**</summary><div>

```ini:/etc/supervisord.conf
; Sample supervisor config file.

[unix_http_server]
file=/var/run/supervisor/supervisor.sock   ; (the path to the socket file)
;chmod=0700                 ; sockef file mode (default 0700)
;chown=nobody:nogroup       ; socket file uid:gid owner
;username=user              ; (default is no username (open server))
;password=123               ; (default is no password (open server))

[inet_http_server]
;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
port=0.0.0.0:9001           ; これに書き換えると全てのクライアントからwebアクセスが可能になる
username=user               ; (default is no username (open server))
password=password           ; (default is no password (open server))

[supervisord]
logfile=/var/log/supervisor/supervisord.log  ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB            ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10               ; (num of main logfile rotation backups;default 10)
;loglevel=info                   ; (log level;default info; others: debug,warn,trace)
loglevel=debug                   ; (log level;default info; others: debug,warn,trace)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false                   ; (start in foreground if true;default false)
minfds=1024                      ; (min. avail startup file descriptors;default 1024)
minprocs=200                     ; (min. avail process descriptors;default 200)
;umask=022                       ; (process file creation umask;default 022)
;user=chrism                     ; (default is current user, required if root)
;identifier=supervisor           ; (supervisord identifier, default is 'supervisor')
;directory=/tmp                  ; (default is not to cd during start)
;nocleanup=true                  ; (don't clean up tempfiles at start;default false)
;childlogdir=/tmp                ; ('AUTO' child log dir, default $TEMP)
;environment=KEY=value           ; (key value pairs to add to environment)
;strip_ansi=false                ; (strip ansi escape codes in logs; def. false)

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor/supervisor.sock ; use a unix:// URL  for a unix socket
;serverurl=http://127.0.0.1:9001  ; use an http:// url to specify an inet socket
serverrrurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
;username=chris                   ; should be same as http_username if set
;password=123                     ; should be same as http_password if set
;prompt=mysupervisor              ; cmd line prompt (default "supervisor")
;history_file=~/.sc_history       ; use readline history if available

; The below sample program section shows all possible program subsection values,
; create one or more 'real' program: sections to be able to control them under
; supervisor.

;[program:theprogramname]
;command=/bin/cat              ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=999                  ; the relative start priority (default 999)
;autostart=true                ; start at supervisord start (default: true)
;autorestart=true              ; retstart at unexpected quit (default: true)
;startsecs=10                  ; number of secs prog must stay running (def. 1)
;startretries=3                ; max # of serial start failures (default 3)
;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A=1,B=2           ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)

; The below sample eventlistener section shows all possible
; eventlistener subsection values, create one or more 'real'
; eventlistener: sections to be able to handle event notifications
; sent by supervisor.

;[eventlistener:theeventlistenername]
;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
;events=EVENT                  ; event notif. types to subscribe to (req'd)
;buffer_size=10                ; event buffer queue size (default 10)
;directory=/tmp                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=-1                   ; the relative start priority (default -1)
;autostart=true                ; start at supervisord start (default: true)
;autorestart=unexpected        ; restart at unexpected quit (default: unexpected)
;startsecs=10                  ; number of secs prog must stay running (def. 1)
;startretries=3                ; max # of serial start failures (default 3)
;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups        ; # of stderr logfile backups (default 10)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A=1,B=2           ; process environment additions
;serverurl=AUTO                ; override serverurl computation (childutils)

; The below sample group section shows all possible group values,
; create one or more 'real' group: sections to create "heterogeneous"
; process groups.

;[group:thegroupname]
;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions
;priority=999                  ; the relative start priority (default 999)

; The [include] section can just contain the "files" setting.  This
; setting can list multiple files (separated by whitespace or
; newlines).  It can also contain wildcards.  The filenames are
; interpreted as relative to this file.  Included files *cannot*
; include files themselves.

[include]
files = supervisord.d/*.ini
```
</div>


laravel.iniは新規に作成する。

```ini:/etc/supervisor.d/laravel.ini
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
; artisanファイルの場所を環境に応じて書き換える
command=php /[product]/artisan queue:work --sleep=3 --daemon
autostart=true
autorestart=true
user=root
numprocs=1
redirect_stderr=true
stdout_logfile=/[product]/storage/laravel_worker.log
stderr_logfile=/[product]/storage/laravel_error.log
```

公式ドキュメント辺りを[**参考**](https://readouble.com/laravel/5.1/ja/queues.html)に。


```bash:console
systemctl start supervisord
# 実行確認
supervisorctl status
# laravel-worker:laravel-worker_00   RUNNING   pid 4574, uptime 0:09:19
```

当初、``/etc/supervisor.d/laravel.ini``内部の``command=php /[project]/artisan queue:work --sleep=3 --tries=2 --daemon``を公式通り``command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3 --daemon``にしていて、エラーログも何も出ないのにジョブがプッシュされなくて軽く詰みかけた。
``artisan``の場所を環境に応じて書き換えること、``sqs``を外すことで解決。

## Supervisorで割り当てたジョブの挙動がおかしなことになった話 [2017-12-05追記]
[**こちら**](https://qiita.com/tosite0345/items/734782c6a985402b49d9)を参考にコンフィグファイルの修正を行った。

## SSHサービスを入れる
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/81270302-ea3c-41ed-122c-0d1a2f509092.png" height=120px>

入ってない場合は入れる。

```bash:console
yum list installed | grep ssh
yum install -y openssh-server
```

最初から入ってたのでやってない。
[**この辺**](https://qiita.com/sango/items/816136188387221f05b3)を参考にどうぞ。

### WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
クライアントからサーバー側に``ssh (user_name)@(host_name)``でつなぐ際にエラーが出た場合。

```bash:console(client)
ssh-keygen -R (host_name)
# 改めてssh接続
ssh (user_name)@(host_name)
# The authenticity of host '(host_name)' can't be established.
# ECDSA key fingerprint is SHA256:(sha256_key).
Are you sure you want to continue connecting (yes/no)? yes
# Warning: Permanently added '(host_name)' (ECDSA) to the list of known hosts.
(user_name)@(host_name) password:
```

[**参考**](https://qiita.com/tanishilove/items/d8f867134528c13b9c2c)

## リモートデスクトップ接続許可 [2017-12-05追記]
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/31106abd-1bef-33cc-71c1-a97501642a92.png" height=150px>

[**こちら**](https://qiita.com/SkyLaptor/items/56c9b5f5784f19cac225)を参考に設定。
なお、予め``GNOME DESKTOP``がインストールされている前提とする。
``firewall``を有効化している場合は``ポート番号3389``を許可しておくこと。

```bash:console
yum install epel-release
yum install tigervnc-server
yum install xrdp

# インストール確認
prm -qa | grep xrdp
prm -qa | grep tiger
```

```ini:/etc/xrdp/xrdb.ini

;;;;;;;;;
; 省略
;;;;;;;;;

; max_bpp=32 ; コメントアウト
; 色の深さが24ビット以下でないと接続できないため、32→24に変更する
max_bpp=24

;;;;;;;;;
; 省略
;;;;;;;;;
```

```bash:console
# サービス起動と自動起動化
systemctl start xrdp
systemctl enable xrdp
```

あとは通常通り、Windowsのリモートデスクトップ接続あたりから接続テストを行う。

# プロジェクト配置
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/225a216e-cc13-4a27-ff45-d3c377fce8a7.png" height=120px>


## プロジェクトをcloneしてくる

```bash:console
cd /var/www/html
git clone 'your repository'
```

このままだと設定ファイルなんかが原因でエラーを吐くことがあるので、``.env``ファイル、``config/``ディレクトリ内など、必要に応じて書き換える。
書き換えただけだとキャッシュやら何やらが残っていてうまく行かない場合があるので、続けて下記の対応を行う。

## composerをインストールしてアップデートする
``env``ファイルを更新するためには、``php artisan config:cache``コマンド叩くと一発なのだけど、
> ``bootstrap/../vendor/autoload.php. Failed to open stream: No such file or directory. The "vendor" folder does not exist.``

的なメッセージが出ることがある。


```bash:console
# [project]配下で作業する
cd /[project]

# Composerインストール
yum install -y composer

# 依存関係の注入
composer install

# 改めてLaravelのconfigファイルをキャッシュ化
composer dump-autoload
php artisan config:cache
```


## ドキュメントルートの設定を行う
Laravelは一度``/[project]/public/index.php``にアクセスさせて、そこで全てのアクセスを捌いている模様。
なのでデフォルトのドキュメントルートを変更して、``public``へとルーティングするように設定を変える。

```ini:/etc/httpd/conf/httpd.conf
########
# 省略
########

# ドキュメントルートを書き換える
DocumentRoot "/[project]/public"

# ルートディレクトリも変更する
<Directory "/[project]/public">
    # Allへ書き換え
    AllowOverride All
    # Allow open access:
    Require all granted
</Directory>

########
# 省略
########
```

``systemctl restart httpd``するのも忘れずに。

## マイグレーションとかその他諸々
[**DBを複数に分けて**](https://qiita.com/tosite0345/items/ff6103174254456aeeff)いたりする場合は``phpMyAdmin``からDB作成しておく。
その後、``php artisan migrate``でテーブルを作成。

## Laravelログ出力ディレクトリの権限変更を行う

恐らくこの状態でアクセスしたとしても、``500 内部サーバーエラー``が出ていることと思う。
どうやらWeb経由でアクセスする際は``Apache``ユーザーとしてアクセスしているようなのだが、そのユーザー自体がLaravelログファイルの生成ができないようにプロテクトがかかっているらしい（詳しくはapacheのログを参照）。
``chmod``やら``chown``やらを試してみたが効果がないようだ...と思って調べてみたら下記のような対応が必要らしい。

```bash:console
chmod -R 777 /[project]/storage
chcon -R -t httpd_sys_rw_content_t /[project]/storage
# 2017-11-09 追記
chmod -R 777 /[project]/bootstrap/cache
chcon -R -t httpd_sys_rw_content_t /[project]/bootstrap/cache
# 2017-11-16 追記
chown -R apache /[project]/storage
chown -R apache /[project]/bootstrap/cache
```

[**参考**](http://momoiro-tj.hateblo.jp/entry/2016/01/12/221657)


## SQLSTATE[HY000] [2002] Permission denied

的なエラーが吐かれる場合がある。
どうやら``SELinux``さん辺りのセキュリティに引っかかってデータベースにアクセスできていない模様。
下記の手順で対応。

```bash:console
getsebool httpd_can_network_connect
sudo setsebool -P httpd_can_network_connect 1
### 反映確認
getsebool httpd_can_network_connect
```

不要であれば``SELinux``サービス自体を止めておいたほうがいいのかもしれない。変なところで詰まりそう。
多分それやるとすごくまずいんだけど。
[**参考**](http://mazeltov7.hateblo.jp/entry/2015/08/28/174858)

### 2017-11-22追記
やっぱりSELinuxが色々障害原因となっていたので止めることにする。
なお、SELinuxには以下のモードがある模様。

|状態|内容|
|:--:|----|
|enforcing|アクセス制限も含めて有効化|
|permissive|監視のみでアクセス制限は行わない|
|disabled|無効化|

#### 一時的に止める場合

```bash:console
setenforce 0
# 0 -> 無効化（Permissive）
# 1 -> 有効化（Enforcing）
getenforce # 状態確認
```

#### 永続的に止める場合

```ini:/etc/selinux/config
#########
# 省略
#########

# 必要に応じて上記状態から選択する
SELINUX=permissive

#########
# 省略
#########
```

念のため再起動をして確認する。

## PhpDebugBar.Widgets.MailsWidget is not a constructor
ブラウザ側のキャッシュクリアで解決。

## Unable to write in the "/[project]/public" directory

```bash:console
chmod -R 777 /[project]/public
chcon -R -t httpd_sys_rw_content_t /[project]/public
```

で解決。

# ログファイルってどこにあるんだってばよ
<img src="https://qiita-image-store.s3.amazonaws.com/0/165355/6d1680ec-8f81-bb51-7e22-77d45ef5f548.png" height=150px>


|ログファイル名|場所|
|:--:|----|
|**Apache**| ``/var/log/httpd/``|
|**Laravel**|``/[project]/storage/logs/``|
|**Supervisor**|``/var/log/supervisor/supervisord.log``|
|**Supervisor (Laravel)**|``/[product]/storage/laravel_worker.log``|

# Xdebugを入れてカバレッジを出したい。ついでに他端末からも見たい。

```bash:console
php -i | grep Debug
Debug Build => no # noならOK

yum install -y php-pecl-xdebug

php -v
# PHP 7.1.12 (cli) (built: Dec  1 2017 13:53:12) ( NTS )
# Copyright (c) 1997-2017 The PHP Group
# Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
#     with Xdebug v2.5.5, Copyright (c) 2002-2017, by Derick Rethans
#          ~~~~~~~~~~~~~
```

```ini:/etc/php.ini
###################
# 末尾に以下を追加
###################
xdebug.remote_enable=1
xdebug.remote_host=10.0.2.2
```

```bash:console
cd /[product]
./vendor/bin/phpunit

# PHPUnit 4.8.36 by Sebastian Bergmann and contributors.
#
# .........................
#
# Time: 17.79 minutes, Memory: 240.00MB
#
# OK (466 tests, 3113 assertions)
#
# Generating code coverage report in HTML format ... done

cd public
ln -s ../report
```

これでブラウザからアクセス時、``/report``をつけるだけでカバレッジレポートにアクセスできるようになった。
ログファイルが出力されない！とか言う方はこちらの記事の [**phpunit.xml**](https://qiita.com/tosite0345/items/3259d408f6e5df84f2e7#phpunitxml) 辺りを参照ください。

# まだやってないこと
+ MySQLの本格的な権限設定・チューニング -> [**やりました**](https://qiita.com/tosite0345/items/7e459fc06c67fa7a2c96)
+ ログローテーションの設定 -> [**やりました**](https://qiita.com/tosite0345/items/070324492e4a2515e3db)
+ ``php.ini``のチューニング