- Next.js을 Elastic Beanstalk Node.js 환경에 Github Action을 통해 자동 배포해요!
- yarn berry의 PnP zero-install을 적용한 Next.js 어플리케이션을 배포해요!
수정 ➡️ 배포
하는 과정을 자동화하여 생산성을 향상 시키고 싶었어요.release/*
branch에 commit이 push되면 stage 서버 자동 배포 main
branch에 commit이 push되면 production 서버 자동 배포❗️아래 글은 stage 서버 자동 배포에 관한 github action입니다.
release/*
브랜치에 commit이 push되면 해당 action을 실행!on:
push:
branches:
- 'release/**'
Elastic Beastalk를 사용하기 위해 aws-cli
를 github action
Node
환경에 세팅
Node
환경을 18.x
로 세팅
- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
aws-zip file을 캐싱
➡️ static한 파일이기 때문에 캐싱처리를 하면 action 속도를 개선할 수 있을 것 같았어요!
- name: Cache AWS CLI
uses: actions/cache@v3
with:
path: /usr/local/aws-cli
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/awscliv2.zip') }}
- name: Install AWS CLI 2
run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
which aws
sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update
AWS configuration을 github action secret
을 통해 진행
➡️ 가장 중요한 건 보안!!
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
Node
환경을 18.x로 세팅.cache: ‘yarn’
를 통해 매 번 npm install -g yarn을 하지 않도록 캐싱하여 action
속도를 개선해요! - name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
cache: 'yarn'
corepack
을 통해 yarn을 사용할 수 있도록해요!corepack
은 node
v16.9.0
, v14.19.0
부터 기본 포함된 실험적 기능으로 yarn
, pnpm
같은 package manager를 프로젝트별로 지정하여 사용할 수 있게 해요.yarn set version berry
를 통해 yarn berry를 세팅해요. - name: Set yarn berry
run: |
corepack enable
yarn set version berry
yarn install
.env
를 github action secret
을 통해 생성..env
파일에 추가되는 환경 변수는 github action secret
과 github action yml 파일
에도 추가 해야해요
- name: Generate .env
run: |
echo "NEXT_PUBLIC_ENV=$NEXT_PUBLIC_ENV" >> .env
echo "NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL=$NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL" >> .env
echo "NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=$NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN" >> .env
env:
NEXT_PUBLIC_ENV: ${{ secrets.NEXT_PUBLIC_ENV_STAGE }}
NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL: ${{ secrets.NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL }}
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: ${{ secrets.NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN_STAGE }}
build
한 어플리케이션을 Elastic Beanstalk 배포를 위해 zip 압축. - name: Build STAGE
run: |
yarn build:stage // package.json script에 존재하는 stage build command
- name: Generate deployment package
run: zip ./deploy.zip -r * .[^.]*
version_label
이 unique해야해서 timestamp로 우선 지정했어요!
- name: Current timestamp
id: timestamp
run: echo "::set-output name=date::$(date +'%Y-%m-%dT%H-%M-%S-%3NZ')"
- name: Deploy to EB
uses: einaregilsson/beanstalk-deploy@v18
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: ${{ secrets.APPLICATION_NAME }}
environment_name: ${{ secrets.STAGE_ENVIRONMENT_NAME }}
region: ${{ secrets.AWS_REGION }}
version_label: ${{ steps.timestamp.outputs.date }}
deployment_package: deploy.zip
- name: Send result to slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: IMCEO - STAGE
fields: repo,commit,message,author
mention: here
if_mention: failure,cancelled
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
if: always()
name: Auto Deploy - STAGE
on:
push:
branches:
- 'release/**'
jobs:
set-eb:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 18.x ]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
- name: Cache AWS CLI
uses: actions/cache@v3
with:
path: /usr/local/aws-cli
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/awscliv2.zip') }}
- name: Install AWS CLI 2
run: |
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
which aws
sudo ./aws/install --bin-dir /usr/local/bin --install-dir /usr/local/aws-cli --update
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 18.x ]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
cache: 'yarn'
- name: Set yarn berry
run: |
corepack enable
yarn set version berry
yarn install
- name: Remove .next
run: |
rm -rf .next
- name: Generate .env
run: |
echo "NEXT_PUBLIC_ENV=$NEXT_PUBLIC_ENV" >> .env
echo "NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL=$NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL" >> .env
echo "NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN=$NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN" >> .env
env:
NEXT_PUBLIC_ENV: ${{ secrets.NEXT_PUBLIC_ENV_STAGE }}
NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL: ${{ secrets.NEXT_PUBLIC_INQUIRY_SLACK_HOOK_URL }}
NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN: ${{ secrets.NEXT_PUBLIC_MIXPANEL_PROJECT_TOKEN_STAGE }}
- name: Build STAGE
run: |
yarn build:stage
- name: Generate deployment package
run: zip ./deploy.zip -r * .[^.]*
- name: Current timestamp
id: timestamp
run: echo "::set-output name=date::$(date +'%Y-%m-%dT%H-%M-%S-%3NZ')"
- name: Deploy to EB
uses: einaregilsson/beanstalk-deploy@v18
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: ${{ secrets.APPLICATION_NAME }}
environment_name: ${{ secrets.STAGE_ENVIRONMENT_NAME }}
region: ${{ secrets.AWS_REGION }}
version_label: ${{ steps.timestamp.outputs.date }}
deployment_package: deploy.zip
- name: Send result to slack
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
author_name: IMCEO - STAGE
fields: repo,commit,message,author # action,eventName,ref,workflow,job,took 추가할 수 있음
mention: here
if_mention: failure,cancelled
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
if: always()
yarn
과 aws-cli
를 캐싱하지는 않았어요!action
속도를 개선했어요!uses: actions/setup-node@v3
에서 cache:'yarn'
을 통해서 yarn 설치 시간 줄임set-eb
와 build
job 분리를 통한 불필요한 동기처리 개선main
, release/*
branch에 따라 production
, stage
자동 배포를 사용하고 있어요 !
안녕하세요 너무 좋은글 감사합니다 덕분에 참고하여 빠른 작업 가능했습니다~
여기서 한가지 궁금한 점은 env.cache-name
cache-name을 감추는 이유는 뭔가요?