Laravel + Nginx + Vite + Vue3をECSへ自動デプロイする
2024年8月3日
Laravelにviteを積んだアプリケーションをECSへデプロイするのに苦労したので、記事に残したいと思います。
本番環境へのデプロイに関してはあまり記事が出てこなかったというのもあります。
構成はLaravel + Nginxです。
まず前提として、以下の手順でローカルでビルドしてデプロイすることはうまくいっておりました。
- vite buildでpublic/build内にビルドファイルを生成
- Laravel用のDockerイメージを生成 → ECRへプッシュ
- Nginx用のDockerイメージを生成 → ECRへプッシュ
- 必要に応じてタスク定義を作成
- ECSサービスの更新
これでうまく本番環境へ反映されます。
ローカルでのこの作業はスクリプト化してあるとはいえ、やはりCIで自動化したいのがエンジニアのさがです。
そのため、今回はGithub Actionsで自動化するということを目指しました。
遭遇していたのは
GET https://xxxxx/build/assets/index-BUJF58Fs.js net::ERR_ABORTED 404 (Not Found)
このようなエラーでフロント側で大量に発生していました。
結論を先に書いてしまうと、
Nginxイメージ内にビルドファイルが配置されていなかった
が原因でした。後から考えればそりゃそうだよね、ということなのですが。
夜中に根を詰めてやりましたが、結局その日は解決できず一晩起きたらこれに気づいてすんなり解決しました笑
ここに至るまでに試行したことは、
- LaravelのDockerfile内でnpm run buildする
- Nginxのdefault.confに/build/ locationを追加する
- github actionsのLaravelイメージ生成時にnpm run buildする
ということをやってきました。 Dockerfile内でビルドするでも良いかもしれませんが、Github Actions内で以下のように実装してデプロイ自動化まで辿り着けました。 まずフロントエンドのビルド部分です。 このプロセスでビルドを行い、アーティファクトをアップロードします。
build-frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Cache Node.js modules
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install dependencies
run: npm ci
- name: Build frontend assets
run: npm run build
- name: Archive build artifacts
uses: actions/upload-artifact@v4
with:
name: build
path: public/build
次にphpイメージ生成プロセスでダウンロードし、public/buildへファイルを配置します。
build-php:
runs-on: ubuntu-latest
needs: build-frontend
steps:
- name: Checkout Project
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build
path: public/build
同様にNginxイメージへもダウンロードし、public/buildへ配置します。
build-nginx:
runs-on: ubuntu-latest
needs: build-frontend
steps:
- name: Checkout Project
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: build
path: public/build
気づけばこれだけのことなのですが、結構苦労しました。