근래의 대부분의 웹앱의 경우 동적인 방식이 많지만
전통적으로 단일페이지와 같은 랜딩페이지류의 원페이지 형태는
화면의 내용이 바뀔 일이 없는 정적인 방식이 다수다.
Next.js를 통해 ssg방식의
정적 웹사이트를 AWS에 배포해서
캐싱을 위해 클라우드프론트를 적용하고
가비아와 같은 서비스에서
원하는 도메인을 구매해서
Route53에 적용하기 까지 기억이 휘발되지 않도록
기록을 남겨보려한다.
1. Next.js 정적사이트로 앱 빌드(SSG)
https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation
Rendering: Static Site Generation (SSG) | Next.js
Using Pages Router Features available in /pages
nextjs.org
배포할 페이지는 Nexst.js 12.4 버전의 단순한 정적페이지이며
2023년 9월 기준 Next13 버전의 App Router버전이 최신이지만
이 글은 Page Router인 12.4 버전 기준으로 글을 작성했다.
정적웹사이트 배포는 build 된 파일 또는 html파일기준이기에
어떤 라이브러리로 만들더라도 배포방법은 비슷할 것 같다.
배포하려는 프로젝트는
Home 화면과 admin 화면, 두 페이지로 구성되었다.
각각의 작업물을 정적사이트로 배포하려면
export 기능을 사용해 빌드하고 각각의 index.html을 배포해야 만한다.
Next.js 기준으로 아래와 같은 설정이 필요하다.
1. package.json파일의 script에 next build & next export 추가
2 next.config.js에서 trailingSlash를 true로 설정
터미널에 명령을 실행하고 나면 out 디렉터리가 생성된다.
각각의 정적페이지가 추출된 것을 확인할 수 있다.
├── out
│ ├── 404
│ │ └── index.html
│ ├── _next
│ ├── admin
│ │ └── index.html
│ ├── favicon.ico
│ ├── images
│ ├── index.html
│ └── vercel.svg
2. S3 정적 웹호스팅 배포
out directory에 build 된 프로젝트를 s3에 배포한다.
Create bucket
- 버킷을 생성
- ACL(액세스 제어 목록) 비활성화
- 공개 액세스 설정 차단해제 -> 모든 공개허용
S3 퍼블릭 액세스 차단 설정 편집
기존 버킷을 퍼블릭 액세스를 포함하는 정적 웹 사이트로 구성하려면
해당 버킷에 대한 퍼블릭 액세스 차단 설정을 편집해야 합니다
모든 퍼블릭 액세스 차단(Block all public access)을 선택 취소
정적 웹호스팅 설정
- S3 > bucket > 생성한 버킷명 > Properties > Static website hosting
- ‘정적 웹 사이트 호스팅’을 활성화하고 이전에 업로드한 index.html을 입력합니다.
- 설정이 완료되면 배포 URL이 활성화된다
파일 업로드
- out에 있는 모든 파일을 업로드해 준다.
권한설정
- 버킷의 객체를 공개적으로 읽기 가능하게 만들려면 모든 사용자에게 s3:GetObject 권한을 부여하는 버킷 정책을 작성해야 함
- 해당 bucket > Permissions > Bucket Policy
버켓 리소스를 복사해 두고(ARN) 정책생성기 선택
정책생성기에서는 손쉽게 정책을 생성할 수 있다.
- Principal : 사용자 또는 역할과 같은 엔터티로 모든 사용자가 접근할 수 있어야 하기에 와일드카드로 입력(*)
- Actions : 주체가 어떤 작업을 수행하는지를 나타내는데 s3객체에 접근할 수 있도록 getObject권한을 부여한다.
- ARN: 이 정책을 적용할 리소스를 선택하는 것으로 현재 배포하려는 bucket 리소스를 선택해 준다. (모든 파일의 경로를 확인할 수 있도록 path에 와일드카드를 같이 입력해 준다
생성된 정책을 기존 정책에 입력하고 상태를 변경해 준다.
{
"Id": "Policy1694145811390",
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1694145809060",
"Action": [
"s3:GetObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::{버켓이름}/*",
"Principal": "*"
}
]
}
3. Cloudfront를 통한 콘텐츠 가속화
위의 S3호스팅 작업을 완료했다면 모든 사람이 웹사이트를
확인할 수 있다.
이제 클라이언트가 어디에 있더라도 빠르게 우리 웹사이트를 볼 수 있도록
CDN서비스인 Cloudfront를 적용해 보자.
CloudFront 설정
Origin
- Origin domain : 배포하려는 도메인을 선택해야 한다. 자동으로 s3호스팅이 되어있다면 아이템으로 선택할 수 있는데 정적웹호스팅의 경우 엔드포인트를 배포된 웹사이트 엔드포인트로 설정한다.
Default cache behavior
- Viewer protocol policy: 기본 캐시 패턴을 설정하는 구성목록으로 만약 https 프로토콜만 유지하고 싶다면 프로토콜정책을 Redirect HTTP to HTTPS로 선택할 경우 HTTP://내 웹사이트로 접근해도 HTTPS://내 웹사이트로 리다이렉트 된다.
- Cache key and origin requests: 클라우드 프런트를 사용하는 가장 큰 목적으로 내 웹사이트를 캐시로 저장하기 위해 캐시최적화 옵션을 선택해 준다.
Settings
- Web Application Firewall (WAF) : 별도의 보안보호가 필요하지 않은 경우 비활성화한다.
- Price class: Use all edge locations (best performance)
- Alternate domain name (CNAME) : 사용하려고 구매한 도메인을 입력한다. 만약 www.혹은 다른 서브도메인 붙이고자 한다면 구매한 도메인 앞에 와일드카드를 붙여준다. *. example.com
- Custom SSL certificate : https를 적용하기 위해해선 ssl 인증서가 필요하다. AWS Certificate Manager (ACM)은 SSL/TLS 인증서를 생성하고 관리하는 서비스입니다. ACM을 사용하면 SSL/TLS 인증서를 쉽게 생성, 발급, 갱신 및 관리할 수 있으며, 무료로 발급받을 수 있고 갱신되더라도 추가비용이 부과되지 않는다. HTTPS를 적용해야 한다면 발급받아야 한다. 인증서발급이 필요하다면 Hold 하고 인증서 생성과정으로 간다.
ACM SSL/TLS 인증서 설정
인증서를 적용하려는 도메인은 클라우드프런트가 적용된 Global 리전으로
ACM도 Virginia리전이어야 한다.
- Domain Names: 적용하고자 하는 도메인명을 모두 작성해 준다.
- Validation Method: 검증방법은 Route53을 통해 진행할 예정으로 DNS validation으로 설정
요청을 마치고 나면 각 도메인별로 CNAME name과 value값이 나온다
Route53을 이용할 경우 각 CNAME 값을 수동으로 등록해 주거나 Create records inRoute53을 통해 등록을 요청한다.
route53에 호스팅 되어있다면 레코드를 추가한다.
호스팅존이 만들어져있지 않았다면, 아래 단락처럼 Route53에서 호스트존을 만들고 진행한다.
인증서검증까지 약간의 시간이 필요한데 몇 분지 나면 status가 바뀌어 있으면 정상적으로 반영된 것이다.
4. AWS Route 53을 사용한 도메인 등록 및 관리
클라이언트에서 우리가 원하는 도메인으로 향하려면
배포된 주소를 우리의 도메인으로 라우팅 시켜줘야 한다.
만약 Route53을 이용하지 않을 경우
별도의 웹호스팅 서버를 구축해
우리가 사용하고자 하는 도메인을 해당서버호스팅 IP주소로 라우팅 해줘야 하는데
이를 쉽게 연결할 수 있도록 제공하는 서비스다.
Route53을 통해 진행할 경우
우선 우리가 사용하고자 하는 도메인의 호스트존을 생성해줘야 한다
Route53에서 직접 도메인을 구매해 호스팅 할 수도 있으며,
이번엔 가비아에 구매한 도메인을 적용하기 위해
가비아에서 구매한 도메인을 기준으로 설명할 예정이다.\
호스트 존 생성
Route 53 > Hosted zones > Create
사용하고자 하는 도메인으로 호스트존을 생성할 경우
아래와 같이 2개의 레코드가 생성된다.
여기서 NS레코드정보를 가비아에 등록해 준다
About 레코드타입
- A Record (IPv4 Address):
- 도메인 이름을 IPv4 주소에 매핑하는 레코드. 웹사이트의 도메인 이름을 웹 서버의 IP 주소와 연결할 때 사용.
- AAAA Record (IPv6 Address):
- 도메인 이름을 IPv6 주소에 매핑하는 레코드. IPv6 주소 체계를 사용하는 환경에서 사용.
- CNAME Record (Canonical Name):
- 도메인 이름을 다른 도메인 이름에 매핑하는 레코드. 주로 서브도메인이나 별칭에 사용
- MX Record (Mail Exchange):
- 이메일을 처리하는 메일 서버의 정보를 지정하는 레코드
- TXT Record (Text):
- 주로 SPF (Sender Policy Framework) 등과 같은 이메일 인증을 위해 사용.
- NS Record (Name Server):
- 도메인의 네임서버를 지정하는 레코드. 도메인을 관리하는 네임서버의 정보를 포함.
5. 가비아 도메인을 AWS에 연결
홈 > 전체도메인> 도메인상세페이지 > 네임서버 설정
네임서버 설정에 Route53의 NS레코드 값을 하나씩 채워준다.
인증하고 나면 적용이 완료된다.
6. CLI로 자동 Deploy 간소화
여기까지 진행되었다면 우리가 원하는 도메인에 CDN서비스로 캐시가 적용된 정적웹사이트가 배포되었을 것이다.
이제 수정사항이나 웹사이트의 변경사항이 생길 경우 만약 자동화되어있지 않다면 아래처럼 번거로운 과정이 생긴다
1. 프로젝트 빌드
2. 빌드파일 S3 업로드
3. 캐시적용된 클라우드프런트 invalidate
4. 사이트확인
이를 deploy과정에서 CLI를 활용해 자동화할 수 있다. CLI를 사용하기 위해선 각 CLI 명령어를 수행할 수 있는 권한이 부여되어야 한다.
IAM
- 기존사용자가 있다면 아래권한을 추가하고, 없다면 새로운 유저를 생성하고 액세스키와 시크릿키를 생성하고 aws configure에 등록해 둔다.
- s3:ListBucket 및 s3:GetBucketLocation: S3 버킷 목록을 가져오기 위해 필요.
- s3:PutObject, s3:GetObject, s3:DeleteObject: S3 버킷에 객체(파일)를 업로드, 다운로드 및 삭제하기 위해 필요.
- s3:ListAllMyBuckets: 사용자가 소유한 모든 버킷을 나열.
- cloudfront:CreateInvalidation: CloudFront 캐시에 대한 무효화(invalidation)를 생성
프로젝트에 쉘스크립트 작성
아래 쉘스크립트는
build파일을 배포하고자 하는 s3 bucket경로로 sync를 맞춰주고
배포한 클라우드프런트를 캐시무효화하는 간단한 CLI로
아래 쉘스크립트를 실행할 경우 배포단계를 축소해 번거로움을 줄일 수 있다.
# Deploy
read -e -p "> Do you want to deploy (y/N)? " deploy
if [ "$deploy" = "y" ]
then
echo "> Deploy starts..."
aws s3 sync ./build s3://{버킷명} --exclude ".DS_Store" --profile {credential에 등록한 aws user 프로필}
aws cloudfront create-invalidation --distribution-id {클라우드 프론트 id} --paths "/*" --profile confin-user-server-dev-2022
echo "> Deploy finished!"
echo ""
else
echo ""
fi
참고
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html
s3 — AWS CLI 2.13.16 Command Reference
This section explains prominent concepts and notations in the set of high-level S3 commands provided. If you are looking for the low level S3 commands for the CLI, please see the s3api command reference page. Order of Path Arguments Every command takes one
awscli.amazonaws.com
https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-help.html
Get help with the AWS CLI - AWS Command Line Interface
You can pipe (|) the output of the help command to the more command to view the help file one page at a time. Press the space bar or PgDn to view more of the document, and q to quit. C:\> aws ec2 describe-instances help | more
docs.aws.amazon.com
https://nextjs.org/docs/pages/building-your-application/deploying/static-exports
Deploying: Static Exports | Next.js
Using Pages Router Features available in /pages
nextjs.org
https://nextjs.org/docs/app/api-reference/next-config-js/trailingSlash
'AWS' 카테고리의 다른 글
Next13 App router SSR(server side rendering) Amplify 배포 이슈(feat.슬랙에 배포알림 연동하기) (0) | 2023.08.24 |
---|---|
SSL/TLS 인증서 자동갱신이 되지 않을때 - AWS ACM, Route53 (0) | 2023.08.17 |
[AWS]DynamoDB Scan vs Query 성능 및 비용테스트 및 DB설계의 중요성 (0) | 2023.02.03 |
[AWS Amplify Studio] - 초스피드 풀스택 서비스 만들기(React) (0) | 2022.06.24 |