📚

Next.js(Amplify) + Laravel(ECS)でJamstackなアプリを動かす

2023/08/19に公開

Objective

  • Next.js(Amplify) + Laravel(ECS)でAPI通信できる環境を構築する
    • Route 53でドメイン取得する
    • ACMで証明書取得する
    • ECSをALBで動かす

Precondition

以下の記事でNext.js、Laravelアプリをデプロイ済みであること

Route 53

Route 53 > Registered domains > Register domainsからドメインを取得する
今回は例としてdeploy-test.comとする

Certificate Manager

SSL化のために証明書を取得する
Certificate Manager > Certificates > Requestからリクエストを発行する

Domain names

対象のドメイン名を設定する
今回はアプリ側をapp.deploy-test.com, API側をapi.deploy-test.comのようにしたいので、*.deploy-test.comとしてサブドメインを設定する

After Certificate

証明書の詳細画面に遷移し、Create records in Route 53からレコードを作成する

Setting Amplify

Amplify > deploy-front(作成した名前) > Domain management > Add domainからドメインを追加する
アプリ側はapp.deploy-test.comに設定する

これでAmplifyの画面でもURLが変更され、指定したURLでアクセスが可能になる

Setting ECS

ECS側ではLoad Balancerに習得したURLを指定する

Create LoadBalancer

EC2 > LoadBalancers > Create load balancerからロードバランサーを作成する

Load balancer types

Application Load Balancer(ALB) を選択

VPC, Security groups, Target groupを設定して作成
作成後にAdd Listenerからリスナーを追加

Listener details

HTTPS 443を設定

Secure listener settings

作成したACMを設定

Route 53

Route 53 > Hosted zones > deploy-test.com > Create recordからALBへのルーティングを設定する
api.deploy-test.comに設定し、AliasをONにして作成したロードバランサーを設定する

以上でロードバランサーの設定はOKなので、ECSにロードバランサーを設定をする

ECS

起動中のサービスがある場合は停止して、新たにサービスを立ち上げ直す
preconditionの参考記事にある設定 + Load balancingの設定で作成したロードバランサーを設定する

サービス起動後にapi.deploy-test.comにアクセスして画面が表示されればOK

Check API

API動作の確認に適当なものを実装してみる

Create API

laravel側でapi.php, APIControllerで以下を実装

// api.php
use App\Http\Controllers\APIController;

Route::get('/test', [APIController::class, 'testResponse']);
// APIController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class APIController extends Controller
{
    public function testResponse()
    {
        return response()->json(['success api response']);
    }
}

Call API

Next.js側で作成したAPIをpages/index.tsxから呼び出し(npm install axios必要)

... 
import axios from 'axios'
import { useEffect, useState } from 'react'
...
export default function Home() {
  const [response, setResponse] = useState(null);
  useEffect(() => {
    axios.get('https://api.deploy-test.com/api/test')
      .then((res: any) => {
        setResponse(res.data);
      });
  }, []);

  return (
...
        <h1 className={styles.title}>
          Welcome to <a href="https://nextjs.org">Next.js!</a>
        </h1>

        <p>response = {response}</p>

        <p className={styles.description}>
          Get started by editing{' '}
          <code className={styles.code}>pages/index.tsx</code>
        </p>
...

app.deploy-test.comにアクセスして以下のようにレスポンスが表示されればOK

Discussion