next11에서 serverless-next를 이용하여 배포하던 방식을(serverless-next는 현재 관리가 되지 않는 오픈소스여서 next13이후 배포를 지원하지 않습니다.) next14로 버전업을 함에 따라 SST로 변경을 했습니다.
SST를 이용하여 next.js를 배포하는 방법에 대해 공유하고자 합니다.
SST는 Next.js
,Svelte
,Remix
,Astro
,Solid
와 같은 프레임워크의 배포를 손 쉽게 도와줍니다.
사용되는 AWS의 서비스는 기본적으로 다음과 같습니다.
npx create-sst@latest
를 실행후 sst.config.ts
파일이 생성이 됐는지 확인을 해줍니다.(drop-in mode)
위 사진처럼 파일이 생성되게 됩니다. npm install
을 해주고 sst모듈을 받아주시면 됩니다.(빨간줄도 사라지게 됩니다.)
//package.json
"scrips":{
"dev": "sst bind next dev"
//...
}
dev 명령어가 next dev
에서 sst bind next dev
로 바뀐것도 인지를 해줍니다.
만약 로컬 환경에서 sst가 필요 없다면 next dev
로 돌려주시면 됩니다.
(제 생각엔 로컬에서 lambda함수를 디버깅이나 테스트를 할 필요가 없다면 로컬 환경마다 credential 설정을 해야 하므로 next dev로 개발을 하는게 좋을거 같습니다.)
aws에 배포하기 때문에 SST가 사용할 IAM Credentials
설정을 해줘야 합니다.
저의 경우 로컬에서는 SST를 이용하지 않아서 로컬에 credential을 설정하는 과정은 생략했습니다.
일반적으로 credential 파일이 존재한다면 다음 경로에 위치합니다.
~/.aws/credentials
C:\Users\USER_NAME\.aws\credentials
내 컴퓨터에 credential파일이 없는 경우 다음 두가지 과정을 진행해줘야 합니다.
위 과정을 마쳤으면 다음과 같은 파일이 생성되어야 합니다.
[default]
aws_access_key_id = <YOUR_ACCESS_KEY_ID>
aws_secret_access_key = <YOUR_SECRET_ACCESS_KEY>
여러 자격 증명을 구성한 경우
[default]
aws_access_key_id = <DEFAULT_ACCESS_KEY_ID>
aws_secret_access_key = <DEFAULT_SECRET_ACCESS_KEY>
[staging]
aws_access_key_id = <STAGING_ACCESS_KEY_ID>
aws_secret_access_key = <STAGING_SECRET_ACCESS_KEY>
[production]
aws_access_key_id = <PRODUCTION_ACCESS_KEY_ID>
aws_secret_access_key = <PRODUCTION_SECRET_ACCESS_KEY>
기본적으로 SST는 [defalut] 프로필에 대한 credential을 사용합니다.
위의 staging이나 production중 하나를 사용하려면 AWS_PROFILE
환경 변수를 설정하면 됩니다.
$ AWS_PROFILE=staging npx sst deploy
이제 sst bind next dev
나 npx sst deploy
와 같은 명령어를 실행시키면 정상적으로 동작하는걸 확인할 수 있습니다.
OpenID Connect를 통해 AWS에 인증처리를 해줍니다.
공급자 추가를 눌러줍니다.
https://token.actions.githubusercontent.com
sts.amazonaws.com
위의 설정값을 넣어주고 공급자 추가를 해주면 완료입니다.
공급자 상세로 들어가 줍니다.
해당 화면에서 역할 할당을 눌러줍니다.
각 칸에 위와 같이 정보들을 제대로 입력을 했다면, 다음으로 넘어가줍니다.
AdministratorAccess
정책을 선택 후 다음을 눌러줍니다.
역할 이름을 입력을 해주고 역할 생성을 하면 완료입니다.
생성했던 역할 이름으로 역할 검색을 해주고 ARN
을 확인해줍니다.
(arn:aws:iam::?????????:role/Ssoon
과 같은 형태입니다.)
name: SST workflow
on: push
# Concurrency group name ensures concurrent workflow runs wait for any in-progress job to finish
concurrency:
group: merge-${{ github.ref }}
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
jobs:
DeployApp:
runs-on: ubuntu-latest
steps:
- name: Git clone the repository
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::????????:role/Ssoon
aws-region: us-east-1
- name: Deploy app
run: |
npm i && npx sst deploy --stage prod
두가지 부분만 수정을 해주면 됩니다.
role-to-assume : 위에서 설정한arn:aws:iam::?????????:role/Ssoon
를 입력해주면 됩니다.
aws-region : sst.config.ts
에 설정한 region
을 적어주면 됩니다.
모든 과정을 마치고 github action을 실행시켜보면 정상적으로 배포가 되는걸 확인할 수 있습니다.
stage
option을 이용하여 production과 staging환경을 나눌수 있습니다.
$ npx sst deploy --stage prod
stage에 전달한 값이 sst config파일에 아래와 같이 전달이 됩니다.
//sst.config.ts
import { SSTConfig } from "sst";
import { NextjsSite } from "sst/constructs";
export default {
config(_input) {
return {
name: _input.stage === "prod" ? "prod-web" : "staging-web",
region: "us-east-1",
};
},
stacks(app) {
if (!["dev", "prod"].includes(app.stage)) {
throw new Error("Invalid stage");
}
app.stack(function Site({ stack }) {
const site = new NextjsSite(stack, "site", {
customDomain: {
domainName:
stack.stage === "prod" ? "naver.com" : "dev.naver.com",
hostedZone: "naver.com",
},
});
stack.addOutputs({
SiteUrl: site.url,
});
});
},
} satisfies SSTConfig;
customDomain
부분의 hostedZone
은 Route 53
의 호스팅 영역을 적어주면 됩니다.
domainName
부분에는 말 그대로 도메인명을 적어주면 됩니다. 만약 하위 도메인을 적어주면 sst에서 자동으로 하위 도메인을 생성해서 배포를 진행해줍니다.
제일 간단한 방식은 Route 53으로 이동시키는 것입니다.
1. 사용 중인 도메인을 Route 53으로 DNS 서비스로 설정 - 도메인이 현재 많은 트래픽이 있을 경우에 대한 방법
2. 비활성화된 도메인을 Route 53으로 DNS서비스로 설정 - 도메인이 사용되지 않거나 많은 트래픽이 없을 경우에 대한 방법
Route 53을 사용하지 않을 경우
CNAME레코드를 생성하고 이를 CloudFront배포로 지정하면됩니다.
배포를 했을때 자동으로 생성되는 URL인 d1p6z4d11yxxds.cloudfront.net
을 가리키면 됩니다.
자세한 내용은 공식문서에 있습니다.
Infrastructure as code
패턴입니다. (aws cdk를 이용해서 CloudFormation템플릿으로 변환시켜 배포를 진행합니다. 이 과정을 타입스크립트로 관리합니다.)open-next
기반으로 배포 처리가 되는데, 공식문서를 확인해보면 현재 스트리밍 기술은 실험적인 단계로 지원을 하고 있습니다. 프로덕션에서는 사용하지 않기를 권장하고 있습니다.serverless-next에서 sst로 이관하는 방법에 대해 알아보겠습니다.