Next.Js 정적 사이트 S3 + Cloudfront 배포와 Dynamic Route 설정

jys9962·2021년 12월 18일
2

aws

목록 보기
2/6

1. S3 버킷 생성

  • 이름 적고 리전만 서울로 해서 기본값 생성

2. NextJS 빌드

# package.json
# "build" : "next build && next export"

> npm run build

3. S3에 올리기

빌드해서 생긴 out 폴더 통째로 1에서 만든 버킷에 올리기

  • aws cli 구성 되있으면
    # project root에서
    aws s3 sync out s3://{s3버킷이름}
  • 아니면 그냥 통째로 드래그

S3 루트에 _next 폴더 있어야함


4. cloudfront 생성

  • 원본 도메인 아까 만든 s3 선택
  • 예, OAI 사용 선택
    - 새 OAI 생성 누르고
    • 예, 버킷정책업데이트 선택
  • 나머지 기본값으로 하고 배포생성

5. lambda@Edge 생성

  • labmda 서비스에서 버지니아 북부 리전으로 변경
  • 함수 생성
    • 함수 이름 적고 런타임 node.js 최신 선택

6. 코드에 dynamic route 처리 함수 추가

출처
https://stackoverflow.com/questions/70096145/nextjs-dynamic-routing-in-amazon-cloudfront/70123764
여기서 조금바꿈

모든 dynamic route 처리는 못하고
경로 마지막에 숫자로 끝나는 것만 path/[id].html로 보냄
ex] /post/123 -> post/[id].html

const config = {
    suffix: '.html',
    appendToDirs: 'index.html',
    removeTrailingSlash: false,
};

const regexSuffixless = /\/[^/.]+$/; // e.g. "/some/page" but not "/", "/some/" or "/some.jpg"
const regexTrailingSlash = /.+\/$/; // e.g. "/some/" or "/some/page/" but not root "/"
// const dynamicRouteRegex = /\/subpath\/\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b/; // e.g /urs/some-uuid; // e.g. '/subpath/uuid'
const dynamicRouteRegex = /^(.+)\/\d+\/?$/; // e.g. /post/123

exports.handler = function handler(event, context, callback) {
    const { request } = event.Records[0].cf;
    const { uri } = request;
    const { suffix, appendToDirs, removeTrailingSlash } = config;


    if(uri.match(dynamicRouteRegex)) {
        request.uri = uri.replace(dynamicRouteRegex, '$1/[id].html')
        callback(null, request);
        return;
    }
    
    // Append ".html" to origin request
    if (suffix && uri.match(regexSuffixless)) {
        request.uri = uri + suffix;
        callback(null, request);
        return;
    }
    
    // Append "index.html" to origin request
    if (appendToDirs && uri.match(regexTrailingSlash)) {
        request.uri = uri + appendToDirs;
        callback(null, request);
        return;
    }

    // Redirect (301) non-root requests ending in "/" to URI without trailing slash
    if (removeTrailingSlash && uri.match(/.+\/$/)) {
        const response = {
            // body: '',
            // bodyEncoding: 'text',
            headers: {
                'location': [{
                    key: 'Location',
                    value: uri.slice(0, -1)
                 }]
            },
            status: '301',
            statusDescription: 'Moved Permanently'
        };
        callback(null, response);
        return;
    }

    // If nothing matches, return request unchanged
    callback(null, request);
};

7. lambda 함수 cloudfront로 연결

  • 트리거 추가 클릭
  • cloudfront 선택
  • labmda@Edge 배포 클릭
  • 트리거 구성
    - 배포에 위에서 만든 cloudfront 선택
    - cloudfront 이벤트에 오리진요청 선택 (default)
    - lambda@Edge로 배포확인 체크

    cloudfront-동작 탭에서 하나 있는거 선택 후 편집
    최하단에 함수연결에 원본요청에 Lambda@Edge 들어온거 확인


8. html 외에 나머지 경로는 labmda 실행 안하게 설정 (js, css)

  • cloudfront에서 동작 - 동작 생성
    - 경로에 /_next/* 입력

    동작탭에서
    우선순위: 경로패턴
    0 : /_next/*
    1 : 기본값(*)
    되있어야함


9. Cloudfront 무효화 후 확인

  • aws cli 구성 되있으면
    aws cloudfront create-invalidation --distribution-id {cloudfront 아이디} --paths "/*"
  • 아니면 cloudfront 배포에서 무효화생성
    - /* 입력 후 무효화 생성 (전체경로)

완료 후 일반 탭에 있는 도메인 들어가서 확인

0개의 댓글