Laravel を Lolipop にワンタッチでデプロイする（Laravelのローテクデプロイのケーススタディ）


# なにがしたい？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/8b4e1c22-0d4c-8400-9e20-70b9411b6347.png)

Laravelアプリをロリポップで運用して3年になりますが、ぼちぼちAWなんとかに乗り換えを……と思っていたのですが、結局まだまだお付き合いを延長すること。
ならばせめてデプロイ方法だけはスッキリしようと、改めて **古式ゆかりのローテク環境にLaravelアプリをデプロイする方法** を考えて実践してみたので、その記録を残しておきます。

ロリポユーザーに限らず、（Herokuのようなハイテク環境ではない）ローテク環境にLaravelをデプロイする手順の参考にしていただければ幸いです。


# 免責

① **ソースコードやサーバーを壊すことになっても責任は負いかねます**。できれば新規プロジェクトに適用するか、少なくともロリポップ内ではサブドメインで別ディレクトリを作ってそこに構築してみて、うまくいったら差し替える、といった慎重な運用をお願いします。

② 本番環境、と書いてみましたが、どちらかというと **「ステージング環境」**と読み替えていただいたほうが適切です……。本当にイキナリ本番公開して問題がないかはプロジェクト規模や作っているソースコード次第ですのでリリース作業は慎重に。

# 仕様

## 前提

- 開発環境は、開発環境だけで独立して動くようになっている（WinとかmacとかCloud9とか……）。
- そこで作ったソースコードを、GITHUBにPUSHしている。
- ロリポップはSSHログインできる。


## BEFORE

- アップロードは FTP
- データベースは phpMyAdmin
- 環境設定は .env をアップロード語にリネーム
- vendorのアップロードが重労働
- どのファイルがいつアップロードされたのか、ローカルとどれがズレているのかよくわからない
- その前にどれが今回アップすべきファイルかわからない
- めんどくさい！／(^o^)＼

すみません。つい先日までのうちのやりかたです。よくこんなことしてたなぁ……（とは思いますが、逆にFTPつなげるPHPサーバーだったらどんなローテクサーバーでも動かせますよ、とは言い添えておきたい）。

## AFTER

- ソース管理は GITHUB
- ~~アップロード~~ デプロイはSSHログイン後、GITHUB から PULL
- vendor はロリポップで composer を動かして直接インストール＆更新
- FTPアップロードは今までと同様にできる
- とは言え、手動で書き換えたりアップロードしたファイルはデプロイ時に消去してGITHUBと同期
- データベースはマイグレーション
- 環境設定は自動的に .env を作成
- Laravelは最適化して不要なログファイルをきれいに
- デプロイ時に何をするかはGithubのコードベースに含めて、簡単に変更できるようにする
- といった一連のデプロイ操作は、**１つのコマンドを叩くだけのワンタッチ！**
- 早い！


# デモンストレーション

まずは完成したものをみていただきましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/52b16aa4-9f0f-707c-0deb-c1116d4d998c.png)

ログインしてパスワードを入力。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/5da5a695-236b-93d7-a2a7-5ce6c4fab21f.png)

直下にあるスクリプト（この場合 p2.sh ）を実行すると、デプロイ完了。
どのコミットまで適用されたのかがわかるように、コミットログも表示しています。
特に大きな変更がないと、**数秒程度で終わり**。早い。

※ロリポップのSSHのパスワードはどこか安全な場所にコピペしておけば良いかと思います。
※余力があればこのSSHの自動化にも挑戦してみてください。Cmderはたぶんパスワード方式のSSHの自動化には対応していないようで、心が折れました…。


# 最終構成

大きく分けて、SSHでロリポップの親階層に仕込んでおくファイルと、いつものLaravelのコードベースに混ぜておくファイルがあります。それぞれ2ファイルずつ、合わせて4ファイルの軽量な構成です。

- **(app).sh** 　　　　 ... ユーザーディレクトリ直下にデプロイスクリプトを設置
- **composer.phar** 　 ... composer はシステムにインストールせずここに設置しておきます
- web/
    - (app)/　　　　　　　 ... ロリポ管理画面のサブドメイン設定などで設定したディレクトリ
        - **deploy-lolipop.sh**　... 具体的なデプロイ手順は後から変更しやすいようにココに書きます
        - **.env.lolipop** 　　　 ... ロリポップ用の環境変数を書いておくところ
        - **app/** 　　　　　　　 ... 同じディレクトリには、通常のLaravelアプリのファイルが入っています。

※以下、(app) とあるところは、アプリケーションの、わかりやすくてキーで打ち込みやすい任意の名前を入れてください。うちではプロジェクトの実名ではなくコードネームで入れていて、たとえば p2 の2文字です。1文字目から他とかぶらないものがオススメです（シェル上でESCキーすると補完してくれるので）。

   


# 手順

## ① コードベースの準備

2ファイル追加します。このようなイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/a04e8659-1269-61c8-49c2-24ed199658a3.png)


### .env.lolipop : 環境変数ファイルを用意

内容はローカルとほぼ変わらず、DB設定がLolipopになっている、といった感じです。
APP_ENV は、本番環境ならオーソドックスに production としましょう。

```env:.env.lolipop
APP_NAME=p2
APP_ENV=production
APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
APP_DEBUG=false
APP_URL=https://p2.com

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=mysqlxxxx.xxx.lolipop.lan
DB_PORT=3306
DB_DATABASE=LAXXXXXXXX-XXXXX
DB_USERNAME=LAXXXXXXXX
DB_PASSWORD=XXXXXXXX

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
...
```

### deploy-lolipop.sh : デプロイスクリプトを準備

概ねこのような感じ。
Laravelのデプロイ時にやっておいたほうが良いことは、ロリポップに限らずほぼ変わらないかと思います。
詳しくは記事後方の解説にて。

```sh:/deploy-lolipop.sh
#!/bin/sh
# デプロイ時にサーバー上で実行されるスクリプト

# vendor以下をインストールして autoloadファイルを最適化
/usr/local/php7.1/bin/php ../../composer.phar install --no-dev

# 環境設定をコピー
cp .env.lolipop .env

# DBマイグレーション
/usr/local/php7.1/bin/php artisan migrate

# /configの設定情報を1ファイルにまとめておく
/usr/local/php7.1/bin/php artisan config:cache

# route情報をまとめておく ※CLOSUREがあると使用できないのでとりまコメントアウト……
# /usr/local/php7.1/bin/php artisan route:cache

# viewキャッシュをクリア
/usr/local/php7.1/bin/php artisan view:clear

# ログをクリア
rm -f storage/logs/*.log
```



## ② sshログインする

SSHツールは何でも良くて、Teratermなどがオススメです。個人的に（カッコいいので）Cmder を使っていますが、クセが強くてじゃじゃ馬なのでおすすめできません……（カッコよさだけをご鑑賞ください）。


### composerをインストール

といってもそんな仰々しいことではなく、composerの実行ファイルをコピーして置いておくだけです。
SSHログインしたユーザーディレクトリ直下で下記を実行しておきます。

おそらく、ここで使ったPHPのバージョンによって、適したバージョンの composer をダウンロードしてくれる、はず
（ロリポップSSHのPHPのバージョンは記事後方の解説で触れています）。

```
/usr/local/php7.1/bin/php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
/usr/local/php7.1/bin/php composer-setup.php
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/a858f492-bfe6-3aad-a3d0-3c5d1e163220.png)


composerの実行ファイルはPHPファイルなので、PHPが動く環境であればファイルを置いておけば動かせます。ちょっとコマンドが長くなりますが、スクリプトで実行するので問題ないかと思います。

### デプロイ起動スクリプトを作成

ユーザーディレクトリ直下のまま `vi (app).sh` として直接ファイルを作成します。
もし vi に使い慣れていなければ、FTPファイルでアップロードしてもOKです。ただ、ユーザーディレクトリ直下にはアップできないので、1つ上の web ディレクトリにアップしたものを移動する必要があります。

パーミションの変更は忘れないようにしてください。

```
[lolipop.jp-dp00000000@users0000 ~]$ vi (app).sh
[lolipop.jp-dp00000000@users0000 ~]$ chmod 755 (app).sh
```


```sh:(app).sh
#! /bin/bash

cd web/(app)

# 手動でアップしたり変更したファイルをなかったことに
# GitHubとのズレを許容しない
git reset --hard

git pull

# どのコミットまで適用されたかを表示
echo "----------------------------------------"
git log -1
echo "----------------------------------------"

# デプロイスクリプトの実行権限を付与
chmod 755 ./deploy-lolipop.sh

./deploy-lolipop.sh
```

下から2行目は、当方が Windows(+vagrant) なので、パーミッションをGITにPUSHしておけない苦肉の策です。
macだったら（たぶん）パーミッションを変更してPUSHしておけるので不要です。


### GITHUBからクローンする

以上でファイル設置は完了なので、GITHUBからコードベースをクローンします。

既存のディレクトリにはクローンできないっぽいので、1回削除しています。<font color="red">★のところで、新規ディレクトリでカラッポかどうかを事前によく確認してください。</font>

```
[lolipop.jp-dp00000000@users0000 ~]$ cd web
[lolipop.jp-dp00000000@users0000 web]$ ls -a (app)
. .. public
★絶対に他のファイルが出てこないことを確認してください
[lolipop.jp-dp00000000@users0000 web]$ rm -rf (app) ★危険(w
[lolipop.jp-dp00000000@users0000 web]$ git clone https://(userid)@github.com/kd9951/(app).git (app)
Password: (パスワードを入力）
```

## テストデプロイ

1回SSHをログアウトしてログインし直し、ルートディレクトリで、

```
[lolipop.jp-dp00000000@users0000 ~]$ ./(app).sh
```

としてください。最新のコミットメッセージが表示されて、最後までエラーがなければ完成です。




# 解説

本筋とはそれますが、関連したトピックスをメモしておきます。

## ロリポップのPHP

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/089ef5be-a90d-8055-248e-4df802994131.png)

コンソールのデフォルトのPHPはver.5.5なので、そのまま `php xxxxx` と使うことはまずありません。ロリポではいろんなバージョンのPHPを個別に用意してくれているので、いつもフルパスを叩いてPHPを実行します。2019年5月時点で入っているバージョンは…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129854/b151b946-14f4-3d3f-8fa2-806d4b6d31ac.png)

おっと。Pythonも入っているのか…。



## デプロイスクリプトでやっていること（Laravelのデプロイでやること）

こちらを参考にさせていただきました！

**[Laravel] デプロイ時の最適化**
https://qiita.com/qiita-kurara/items/d37dbc5b67e6b6dfbe1d


```sh
# vendor以下をインストールして autoloadファイルを最適化
/usr/local/php7.1/bin/php ../../composer.phar install --no-dev
```

composer は（開発環境で）インストールしたライブラリとそのバージョンを composer.lock に記録します。その記録されたバージョンとまったく同じものをゼロから用意するときには `composer install` します。 `composer update` するとバージョンが変わってしまうかもしれないのでダメです。また、本番環境なので開発時に要らないものを `--no-dev` オプションで除外します。

`composer optimize` や `composer dump-autoload` は上のコマンドで一緒にやってくれるのでやらなくても大丈夫です。


```sh
# 環境変数をコピー
cp .env.lolipop .env
```

環境変数やENVファイルについて詳しくは次のパタグラフにて……。


```sh
# DBマイグレーション
/usr/local/php7.1/bin/php artisan migrate
```

毎回やっておきましょう。

```sh
# /configの設定情報を1ファイルにまとめておく
/usr/local/php7.1/bin/php artisan config:cache
```

速度改善のため、本番環境ならやっておきたいところ。
そのためには、env() を使わず、config() を使うようにしましょう。

```sh
# route情報をまとめておく
/usr/local/php7.1/bin/php artisan route:cache
```

これも速度改善のため。ただしクロージャーのルートがあると動かないので、すべてコントローラにしておきましょう。

```sh
# viewキャッシュをクリア
/usr/local/php7.1/bin/php artisan view:clear
```

たまに、カスタムディレクティブを変更したときなど、VIEWキャッシュを削除しないと変更が反映されないときがあります。ただし、そんなことになるのはそういったレアケースのみで、VIEW周りで余計無いことをしていないならあえてクリアしなくてもいいかもしれません。

```sh
# ログをクリア
rm -f storage/logs/*.log
```

ログローテーションも設定でうまいことやってくれますが、デプロイしたということは過去のエラーログはあまり当てにならないので、まるごと削除しても良いかも、と。





<!--
Laravelの環境変数の優先順

実行する環境によって設定を変えたいときに便利な .env ファイル。
ただ、その使い方というか、設定方法の優先順がいつもわからなくなるのでメモ。

1. **OSの環境変数 APP_ENV** を取得。なければ production とする。`env('APP_ENV')` がセットされる。
2. アプリのベースディレクトリに **.env.xxxxxx** があるかチェック（ env('APP_ENV')=production なら .env.production ）
3. なければ、 **.env** があるかチェック
4. 見つかったenvファイルを読み込んで、**env('XXXXX')** をセット。その中にAPP_ENVが定義されていれば上書きされる。
5. **config/xxx.php** を読み込む。env() は基本的にすべて config() に移されて、以降はconfig()を使う。

なので、基本的な運用方針は下記のいずれかになります。

- **APP_ENV に環境名をセットして**（たとえば development ）、**専用の.env.xxxxxx をコードベースにPUSHしておく**（たとえば env.development ）。
- **APP_ENV は定義せず、その環境で直接 .env を作っておいておく**。

今回は、コードベースに .env.lolipop を作っているので前者でやっているように見えますが、APP_ENVはセットしていませんし、デプロイ時にそれを .env にコピーしているので、後者で動いています。逆に、Herokuなどのモダンなデプロイ環境では APP_ENV 1つだけをセットしておいて、後は .env.xxxxx に書いておくのが慣例です。
-->

# 感想

Qiitaを読んでいるとまだまだ「LaravelをLolipopで使ってます！」という記事を見かけるので、長年のロリポユーザーとしてはとても嬉しくなってきます。
複雑なことをしなければ100万PVのサイトでも動かせるチカラがあるし、転送量も無制限。月額500円～2,000円で限界までサイトを立て放題。こんなサーバー活用しない手はないでしょ。

だからこれからもがんばって！

と言いたいんですが、なんかもうすべて「良い歳したおっさんの昔話」みたいで哀しくなってきたのでやめます……。