Laravelを本番サーバーにデプロイしてみた

大学でいただいたアルバイトを通じて、Laravelで作ったWebアプリを本番環境（レンタルサーバ）にデプロイする際にちょっとだけ足止め食らったので、メモ程度に。

# 前提
前提としては、こんな感じ。

* 開発環境はmySQL含め全てローカル
* アプリは完成済み
* サーバーにssh接続できる

# とりあえずComposerをインストール
sshでサーバーに入るところは省略します。Terminalからsshするだけ。
問題はその後で、自分がやったのは以下のような感じ。

```bash:~/
% mkdir bin
% curl -sS https://getcomposer.org/installer | php -- --install-dir=bin --filename=composer
% chmod 755 bin/composer
```
`HOMEディレクトリ`下に`bin`フォルダを作って、その中に入れる。
一度ログアウトしてもう一度入り直すと、`composer`が使えるようになってます。

# 導入
## プロジェクトをサーバーに移す
自分はgit経由で持ってきました。scpで上げるのも面倒だったので……。
プロジェクトがあげられればなんでもいいと思います。
問題は、この時どこに置くか。
公開ディレクトリは`~/www/`以下になると思うんですが、Laravelの本体をここに置くのは色々問題なので、こんな風に置くといいらしい。

> / (home dir)
　├ bin/
　│　└ composer/
　└ laravel/ `<-新しく作る`
　 　└ [プロジェクト名]/

```bash:~/
% mkdir laravel
% cd laravel
% git clone <git_clone_link>
```

　とりあえず配置完了。

## 公開する下準備①
次に`.env`を書き直す。vimを使ってもいいし、FileZillaとかで編集してもいい。お好みで。
cloneした場合は、`.env.example`などをコピーして.envファイルを作る。

```:.env（ローカル）
APP_ENV=local
APP_DEBUG=true
APP_URL=http://localhost
DB_HOST=127.0.0.1
DB_PORT=0000
DB_DATABASE=hogefugadb
DB_USERNAME=hoge
DB_PASSWORD=fuga
```

```:.env（修正後）
#APP_ENV=production
#APP_URL=[アプリのURL]
#APP_DEBUG=false
#DB_HOST=[WebアプリのURL]
#DB_PORT=[DBポート番号]
#DB_DATABASE=[データベース名]
#DB_USERNAME=[DBユーザ名]
#DB_PASSWORD=[DBパスワード]
```

それぞれの名前などはご自身の環境に合わせてください。

## 公開する下準備②
laravelは、index.phpからいろんなモジュールやら何やらを読んでいるらしい。ので、それを公開フォルダに移す。

```bash 
% cd ~/laravel/[product_name]/public
% pwd
/home/[USER]/laravel/[product_name]/public
% cp -r ~/laravel/[product_name]/public/* ~/www/[product_name]/
```

自分は今回サブディレクトリを作ったのですが、そのままwwwにするときになんか制約があるのかはわからないので、ダメだったらググってください。

コピー後、`index.php`が読み込むモジュールのパスを修正しましょう。
本体にある方じゃなく、コピーして**公開ディレクトリにある方**。

```php:index.php（修正前）
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__.'/../vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';
```

```php:index.php（修正後）
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__.'/../../laravel/[product_name]/vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../../laravel/[product_name]/bootstrap/app.php';
```

これで、laravel本体にパスを張ることができました。

## 公開する下準備③
パスを張ったのはいいんですが、このままだとlaravelフォルダに繋がらないらしいので、`.htaccess`を編集。
ちなみにこれも**公開ディレクトリにある方**。

```diff:htaccess
 <IfModule mod_rewrite.c>
-    <IfModule mod_negotiation.c>
-       Options -MultiViews -Indexes
-    </IfModule>
    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    
    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
 </IfModule>
```


下準備はこんな程度です。
ここまで来れば後はすぐ。

## Laravelセットアップ

`composer`と`php artisan`のおなじみの呪文を唱えましょう。

```bash
% pwd
/home/[user_name]/laravel/[product_name]/
% composer install
~~~ インストール ~~~
% php artisan key:generate
% php artisan migrate:fresh
```

`production`に設定されているので確認メッセージが出てきますが、`yes`にして実行しましょう。

終わりです。慣れれば簡単。

# まとめ

いろんな記事を参考にさせていただいてはみたのですが、シンボリックリンクを張ったり、公開ディレクトリに直接デプロイしたりなど、あちこちで情報が錯綜……。

とりあえず自分はこの方法でデプロイできましたので、メモがわりに上げさせてもらいました。
にしても、普段フロントばっかりいじってるとdistをそのまま上げるだけになりがち……。Laravel自体でモックの開発なんかは良くやってますがデプロイ自体は初めてだったので、ちょっと躓きました。

### 追記(2020/03/07)
投稿から1年と少し経ち、多くの方に参考にしていただけているようで恐縮です。
先日久々にLaravelで開発した案件をデプロイする機会がありましたが、この手順でできました。

ちなみにフロントをVueのSPAで作っていたので、アップデートの度に公開ディレクトリ(`~/www`下)にある`public/assets/*`や`mix-manifest.json`などを更新する必要がありました。
publicディレクトリにある静的ファイルを更新する場合は、公開ディレクトリへのコピーを忘れずに。