Dockerの思い出しついでにlaravel動作環境を構築してみた

# 導入
ちょっと前に取り組んでいたdockerの内容を思い出しついでにlaravelの動作環境構築にチャレンジしてみました。
過去に `docker laravel 環境構築` とかでググった参考サイトをもとに環境構築したことはありますが、
alpineオフィシャルイメージ(クリーンインストール状態?)を環境構築のスタートとし、PHP動作環境を構築 + nginxを導入 + laravelのインストールnginxとの連携までを行いました。
無事環境構築に成功したので、今回の総括の意味を込めて振返り記事を作成しました。

完成した内容は以下のリポジトリで公開してます
※ ツッコミどころ満載だと思います
https://github.com/AiRKING-no9/nginxBuildEnvOnAlpine

## 投稿者のすぺっく
* 仕事 or 趣味でwebブラウザのフロント関連とPHPのサーバーサイドアプリケーションをさわる
* 仕事で使う開発環境はvirtualbox or dockerで動作する環境を提供してもらってた。フロントソースを動作させる上で開発環境に調整必要そうならググって調整加えるくらいならやってた
* Linuxで動いているサーバーに入ってコマンド叩いてちょこちょこ触れる
* クリーンインストールされた状態のLinux系OSに対してPHP動作環境構築とかやったことない  
自分のホストOS汚したくなくてalpineのオフィシャルイメージからコンテナ立ち上げ→node突っ込んでフロントソースコンパイルを過去やってみた程度
* nginxを手順に沿って導入してwelcome画面をみて満足した  
nginxの細かい設定とか設定ファイルの内容よく知らない
* dockerfileとdocker-composeファイルをある程度調べながらdockerコンテナの構築はできる


## つまづいた・悩んだポイント
### その１: パッケージマネージャー(apk)経由でPHP7をインストールしようとしたら見つからない
今回 2020/11月頃時点で最新だったalpine3.12を利用しましたが、最新のalpineバージョンを利用するとPHP本体とPHP関連のパッケージが見つからなかった...
最終的にapkが参照するリポジトリを追加することで無事 `apk add パッケージ名` でPHP本体とPHP関連のパッケージがインストールできました。
※ 今回は `http://dl-cdn.alpinelinux.org/alpine/edge/community` のURLを `/etc/apk/repositories` ファイルに追記することでリポジトリが追加されうまくインストールできました。

### その2 : php-fpmをインストール成功 → `php-fpm not found` になる
apk add php-fpm ですんなりインストールできたと思ったら php-fpm -v を実行してもphp-fpm not foundが表示されてしまう...
結果としてphp-fpm7 という名前で /usr/sbin/ ディレクトリ配下にインストールされていた。
自分の場合1文字多くなるけどphp-fpm7でいいやと思ったのでそのままphp-fpm7でコマンド実行をつづけたが、
どうしてもphp-fpmで実行したいという人はphp-fpm7を対象にphp-fpm命名でシンボリックリンクを作成すればOKです。

今回の件を通して、apkのインストール先ディレクトリどこ？とか色々調べましたが、
調べている中で、binディレクトリsbinディレクトリの役割があることを知りました。
Macで何気なくbinディレクトリとか触ってたけど役割あるなんて知らなかったんよ(´・ω:;.:...
以下、調査時に参考にした資料

- [Linuxの/bin、/usr/bin、$HOME/binのそれぞれの役割](https://qiita.com/totzyuta/items/84d610f56129a186f0c5)

### その３ : laravelとnginxの連携がうまく行かない
nginxの導入→ welcome画面の表示がうまくいき、composer経由でlaravelプロジェクトの作成までは順調に進めた。
しかし、nginxとlaravelを連携させようとするとnginxがlaravelのページ出力を返してくれなかった。
うまく行かなった原因として、nginxの設定ファイルとphp-fpmの設定ファイルを編集することでうまく応答してくれるようになった。
nginxとかphp-fpmの設定全く知らなかったのでここが一番解決まで時間かかった。

- nginxの設定ファイル(/etc/nginx/conf.d/default.conf)

```config
server {
    listen 80;
    server_name  localhost;

    access_log  /var/log/nginx/laravelProject/access.log  main;
    error_log   /var/log/nginx/laravelProject/error.log  warn;
    # 以下でlaravelプロジェクトのpublicを参照するように設定
    root /www/laravelProject/public;

    location / {
        index index.php index.html;
        try_files $uri $uri/ /index.php$is_args$args;
    }
    
    # phpファイル実行時のfastCGIの接続設定
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
```
* php-fpmの設定ファイル(/etc/php7/php-fpm.d/www.conf)

```config
[www]

user = nginx
group = nginx

listen =/var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = nginx

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
```

### その4 : ホストとコンテナのディレクトリ同期を行うと空ディレクトリになる
dockerfile内ではじめは`composer create-project laravel/laravel=5.5 プロジェクト名`でコンテナ内でlaravelプロジェクトが作成され動作することを確認していました。
ある程度のlaravel動作環境が構築できたので、ホストとコンテナを同期ディレクトリでマウント → 同期ディレクトリ先にlaravelプロジェクトインストールを実行したところ空ディレクトリになってしまいました。

最終的にコンテナを一旦構築完了したあとに`docker exec`経由でlaravelプロジェクトの作成コマンドを実行することで同期ディレクトリ内にうまく展開することができましたが、
正直今回のやり方が正解だとは思わないので現在も原因調査中です。
※ コンテナ構築中に同期ディレクトリ触るとダメなのかな？

# 総括
いままでLinux系OSがクリーンインストールされた状態からここまで環境構築したことがなかったので、いろいろと苦戦しました。
が、当初の目標を達成できたことで学べた内容も新鮮でした。途中で折れない・諦めない心大事。
正直__alpineベースのPHP動作環境コンテナが構築できるオフィシャル・アンオフィシャルイメージがある__のでそちらをベースイメージに利用すればここまでやる必要がないのですが、
必要最低限のミドルウェアを導入して環境構築できた謎の自己満足は満たされました。
なによりLinux系OSを学ぶ上でクリーンインストールされた状態から色々Tryして実験できたのでそちらのほうが得るものが大きかったです。:thumbsup:
やっぱりDockerは触って失敗したら即破棄→再構築できるので便利だなと再確認できました。

以上!!