概説
個人開発しているLaravelのアプリケーションの稼働環境として「ロリポップ!マネージドクラウド」を選択しました。
以前、GitHub Actionsを使って、静的HTML一式をロリポップ!マネージドクラウドにデプロイする方法をブログにまとめているのですが、今回はLaravelのアプリケーションをデプロイしてDBのマイグレーション実行までやってみたので、メモとして残しておきます。
前提
今回はGitで管理しているsrcディレクトリをロリポップ!マネージドクラウドの/var/wwwディレクトリ配下へrsyncを使ってデプロイします。
- デプロイ元となるGitリポジトリのディレクトリ構成
.
├── .git
│ ├── COMMIT_EDITMSG
│ ・
│ ・
├── .github
│ └── workflows
│ └── deploy.yml ← GitHub Actionsの設定ファイル
├── .gitignore
├── README.md
└── src ← デプロイ元ディレクトリ(Laravelのアプリケーションディレクトリ)
├── app
│ ├── Console
│ │ └── Kernel.php
│ ├── Exceptions
│ │ └── Handler.php
│ ├── Http
│ │ ├── Controllers
・
・
- デプロイ先となるロリポップ!マネージドクラウドのディレクトリ構成
/var/www/
├── html -> /var/www/src/public ← ロリポップ!マネージドクラウド環境のDocumentRoot
└── src ← デプロイ先ディレクトリ
注意点として、ロリポップ!マネージドクラウドでは「/var/www/html」が固定のDocumentRootとなっているため、「/var/www/src/public」のシンボリックリンクを作成する必要があります。
初回デプロイの前は「/var/www/src/public」が存在しないため、デプロイが成功したあとに以下の手順でシンボリックリンクを作成します。
デフォルトで準備されている「htmlディレクトリ」を残す必要がない場合はmvではなく $ rm -fr /var/www/html
でよいでしょう。
$ mv /var/www/html /var/www/html_orig
$ ln -s /var/www/src/public /var/www/html
設定手順
GitHubの「Secrets」の設定
-
GitHubの「Secrets」の画面で以下のように設定します。
- SSH_HOST:マネージドクラウドの「ホスト名」
- SSH_PORT:マネージドクラウドの「ポート」
- SSH_USERNAME:マネージドクラウドの「ユーザー名」
- SSH_PRIVATE_KEY:マネージドクラウドのSSH接続用の「秘密鍵」の内容
- Macの場合はpbcopyコマンドでコピー可能です。
$ cat ~/.ssh/マネージドクラウドの秘密鍵 | pbcopy
- SSH_KNOWN_HOSTS:ssh-keyscanの実行結果
マネージドクラウドの「環境変数」の設定
-
マネージドクラウドの「環境変数の設定と管理」の画面で以下のように設定します。
本番環境用.envの雛形ファイルの設定
-
src/.env.production
のデータベースに関連する箇所を以下のように記述しておきます。(マネージドクラウドの環境変数で設定した項目については削除) - 今回、秘匿すべき情報についてはマネージドクラウドの環境変数に設定することにしましたが、このあたりはプロジェクトのポリシーなどもあるかと思いますので、環境ごとのルールに合わせてもらえると。
DB_CONNECTION=mysql
#DB_HOST=127.0.0.1
#DB_PORT=3306
#DB_DATABASE=laravel
#DB_USERNAME=root
#DB_PASSWORD=
GitHub Actionsの設定
以下のように .github/workflows/deploy.yml
を準備しました。
name: Deploy
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: composer
run: |
cd src
composer install --prefer-dist --no-interaction
- name: npm
run: |
cd src
npm install
npm run prod
- name: dot env copy
run: |
cd src
cp .env.production .env
- name: ssh key generate
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "${{ secrets.SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts
- name: rsync deploy
run: rsync -av -e "ssh -i ~/.ssh/id_rsa -p ${{ secrets.SSH_PORT }}" src ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/var/www/
- name: database migration
run: ssh -i ~/.ssh/id_rsa -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} 'cd /var/www/src && php artisan migrate --force'
.github/workflows/deploy.yml
の解説
name: Deploy
このアクションの名前です。今回は単純に「Deploy」としました。
on:
push:
branches:
- master
masterブランチにpushされた場合にこのアクションが実行されるようにしています。
runs-on: ubuntu-latest
runs-on
で指定した仮想マシンの詳細については公式のページに解説がありますので、そちらを参照してください。
- サポートされているランナーとハードウェアリソース
- GitHubホストランナーにインストールされるソフトウェア
- サポートされているパッケージエコシステム
- uses: actions/checkout@v2
公式の actions/checkout を使って、git checkoutを行います。
- name: composer
run: |
cd src
composer install --prefer-dist --no-interaction
composerパッケージのインストールを行います。
- name: npm
run: |
cd src
npm install
npm run prod
npmパッケージのインストールとアセットファイルの生成を行います。
- name: dot env copy
run: |
cd src
cp .env.production .env
本番環境用.envの雛形ファイルを元に .env
を作成します。
- name: ssh key generate
run: |
mkdir -p ~/.ssh/
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
echo "${{ secrets.SSH_KNOWN_HOSTS }}" > ~/.ssh/known_hosts
事前にSecretsの画面で登録しておいた秘密鍵を ~/.ssh/id_rsa
としてファイルに出力し、ファイルの権限を600に設定します。
SSH接続時のオプションで -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
を設定することで接続時の警告を無視することができますが、中間者攻撃の観点から ~/.ssh/known_hosts
に登録することにします。
ssh-keyscan -p ${{ secrets.SSH_PORT }} -H ${{ secrets.SSH_HOST }} > ~/.ssh/known_hosts
とやりたいところですが、マネージドクラウド側の都合(参考情報)によりssh-keyscanに失敗する場合があるようなので手元の環境でssh-keyscanを実行した結果を SSH_KNOWN_HOSTS
として設定しておき、その内容を ~/.ssh/known_hosts
に書き込みます。
- name: rsync deploy
run: rsync -av -e "ssh -i ~/.ssh/id_rsa -p ${{ secrets.SSH_PORT }}" src ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/var/www/
対象ディレクトリの src
をrsyncコマンドを使ってデプロイします。
--delete
オプションを利用していない理由は php artisan storage:link
で設定している /var/www/src/public/storage
のシンボリックリンクが削除されないようにするためです。(デプロイの前にシンボリックリンクを作成してrsyncするとうまくいくかもしれません)
- name: database migration
run: ssh -i ~/.ssh/id_rsa -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} 'cd /var/www/src && php artisan migrate --force'
最後はDBのマイグレーションです。デプロイ先のサーバーにSSH接続して実行しています。
GitHub Actionsの動作確認
一連の処理に成功すると、GitHubの「Actions」の画面で「Complete job」の文字が確認できます。
参考URL
- LOLIPOPマネージドクラウドで、Laravel環境を構築する
- ロリポップマネージドクラウドでLaravelアプリのセットアップ手順
- GitHub Actionsで「ロリポップ!」「ヘテムル」をもっと便利に使おう
- GitHub ActionsでRailsアプリをロリポップマネージドクラウドにデプロイする
- GitHub Actions で快適なデプロイを実現する(rsync・laravel)
- GitHub Actions で LaravelのCI/CD環境を構築する(MySQL, Deployer)
- GitHub Actions で Laravel + Vue 環境を自動デプロイ
- deployerを使って簡単にLaravelのアプリケーションをロリポップ!マネージドクラウドにデプロイする
- 「SSHホスト鍵が変わってるよ!」と怒られたときの対処