Laravel5.4、rsyncでデブロイする

タグ: Laravel5.4  

デプロイツールは便利です。以前の状態へロールバックするなど、機能が豊富です。

しかし、ソースは戻せてもマイグレーションなどが絡み、ソースを巻き戻してもマイグレーションはロールバックすべきかどうか、慎重に検討が必要な場合も多く、全てが機械的に行えない状況も起きます。また、小さなプロジェクトでは、高機能なツールはそもそも必要ないでしょう。

今回、自分の個人プロジェクト用に、デプロイ作業をシェルにまとめたので、紹介します。rsyncで開発したソースファイルなどのみ転送し、composerの依存プロジェクトは実働環境上でupdateする方針です。(ただし、どのデプロイ方法がベストであるかは状況によって異なります。)

Ubuntu16.10で検証したスクリプトです。

パーミッションと所有者設定スクリプト

所有者やパーミッションの設定は初心者には難しいところがあります。内容を解説すると長くなるため、簡単ですがスクリプトだけ紹介しておきます。

#!/bin/bash

# 実働サーバーのLaravelプロジェクトディレクトリで実行

sudo chown -R myUserName:myUserName .
sudo find . -type d -exec chmod 0755 {} +
sudo find . -type f -exec chmod 644 {} +

sudo chown -R myUserName:www-data bootstrap/cache storage/app storage/framework storage/logs
sudo find bootstrap/cache -type d -exec chmod 2775 {} +
sudo find bootstrap/cache -type f -exec chmod 664 {} +
sudo find storage/app -type d -exec chmod 2775 {} +
sudo find storage/app -type f -exec chmod 664 {} +
sudo find storage/framework -type d -exec chmod 2775 {} +
sudo find storage/framework -type f -exec chmod 664 {} +
sudo find storage/logs -type d -exec chmod 2775 {} +
sudo find storage/logs -type f -exec chmod 664 {} +

デプロイ先のLaravelプロジェクトの中で実行します。ですから、後述のデプロイスクリプトを実行し、デプロイ先にLaravelプロジェクトが転送された後に、一度実行します。

毎回デプロイするごとに実行する必要はありません。

myUserNameを自分のログインユーザー名へ変更してください。

スクリプト本体

ローカルの開発環境で実行する、rsyncを使った転送スクリプトです。

この場合、ユーザーのホームディレクトリ下のexample.comディレクトリーがLaravelプロジェクトのホスト先という前提です。環境に合わせ、適当に修正して使用してください。

#!/bin/bash

# Laravelアプリケーションをメンテナンスモードへ
ssh production "php example.com/artisan down"

# 転送
rsync -rltvz --delete \
# -r ディレクトリを再帰的に下り処理する \
# -l シンボリックリンクをシンボリックリンクとしてコピーする \
# -t 変更時間を反映する\
# -v verboseモード \
# -z gzipをしてから送信する \
# --delete 転送元にないファイルは、転送先から削除する。 \
#   ただし、転送除外の対象になっている場合は、 \
#   転送先に存在していても除外されない。 \
 \
# 除外したいフォルダーを適当に \
--exclude="nbproject/" \
--exclude="vendor/" \
--exclude="foundation6/" \
--exclude="node_modules/" \
--exclude="tests/" \
# ドットで始まるフォルダーは除外 \
--exclude=".*/" \
# ドットファイルは除外するが、.env.exampleは転送対象とする \
--include=".env.example" \
--exclude=".*" \
# 除外したいファイル \
--exclude="gulpfile.js" \
--exclude="package.json" \
--exclude="phpunit.xml" \
--exclude="readme.md" \
--exclude="server.php" \
--exclude="webpack.mix.js" \
# フレームワーク生成のファイルは転送しない \
--exclude="storage/framework/cache/**" \
--exclude="storage/framework/sessions/**" \
--exclude="storage/framework/views/**" \
--exclude="storage/logs/*" \
/home/転送元サーバーのディレクトリー/example.com/ production:/転送先サーバーのディレクトリー/example.com

# 依存パッケージを--no-dev(no開発=本番環境)としてアップデートする
ssh production "cd example.com && composer update --no-dev -n"

# 念のためにキャッシュクリア
ssh production "php example.com/artisan config:cache"

# マイグレーションを実行
ssh production "php example.com/artisan migrate --force"

# アプリケーションのメンテナンスモードを解除
ssh production "php example.com/artisan up"

ルートの数が多い場合は、ルートキャッシュもシェルに含めると良いでしょう。

.envファイルは除外してありますので、転送されません。実働環境にあったものを最初に作成してください。

rsyncのexclude/includeファイル指定は別ファイルにすることもできますが、オプションとして上記のように記述したほうが、管理が楽です。

注意点

今回はUbuntu16.10上にホストしているLaravelプロジェクトで試しています。そのサーバーの設定のうち、関連する項目は以下のとおりです。

  • Webサーバーは、www-dataユーザー、www-dataグループで動作している。
  • 私のローカルのアカウント(hiro)と同じ名前のユーザーを実働サーバーに用意している。
  • 実働サーバーに対するSSH接続情報は~/.ssh/configファイルで設定済み。productionと言う名前でSSH接続が簡単に行えるようにしてある。
# 例
Host production
  Hostname xx.xx.xxx.xxx
  IdentityFile ~/.ssh/id_production
  Port 20022
  • 私(hiro)は自分のグループhiroと、www-dataに所属している。
  • webサーバーには、umaskに002を指定している。これにより、作成されるファイルのパーミッションは664、ディレクトリのパーミッションは775となる。結果、www-dataに所属する私のアカウントと、webサーバーは、bootstrap/cachestorage/appstorage/frameworkstorage/logs以下のファイルやディレクトリの削除、変更、新規作成が自由にできる。

難しいポイント

グループへユーザーを追加する方法などは、検索すれば簡単に見つかります。

多少面倒な部分の方法のみメモしておきます。詳細は自分で調べてください。

スティッキーの立て方

example.comディレクトリ下のディレクトリへグループのスティッキービットを立てる。

find example.com -type d -exec chmod 2775 {} +

これでうまく設定されない場合は、sudoを付けてください。

ディレクトリ下全部の所有者の指定

chown -R ユーザー:グループ example.com

webサーバーに対するumaskの設定

今回はNginxを使用しました。そのため、実際にはサーバーのumaskではなく、php-fpmに対するumaskです。

また、phpにはphp7.0を使用しています。

スーパーユーザーとして/etc/systemd/system/multi-user.target.wants/php7.0-fpm.serviceファイルの[Service]セクションの下へ、以下の一文を追加してください。

UMask=002

この変更をシステムに反映するため、以下のコマンドを実行します。スーパーユーザーの権限がもちろん必要です。

systemctl daemon-reload
service php7.0-fpm restart

以上です。前半はデプロイ方法の簡単な説明、後半はサーバー設定の話でした。