FrontEnd Skils

Front-end 배포 (3) - 개발용과 실제 서비스용 배포 분리하기

JellyApple 2024. 7. 1. 10:46

회사에서 만든 웹 서비스를 Github Actions와 S3 + Cloudfront 로 배포를 했는데 이 때 새로 오신 사수 개발자분께서 개발용 서버와 실제 서버를 분리해주셨고 그에 맞춰 배포도 다르게 가야 한다고 말씀해주셔서 배포 했던 것을 간단히 수정하고자 했다. 

 

1. 기존 구조

gitflow를 사용하고 있었기 때문에 dev를 default로 잡고 이 곳에 push 해주었다. 그리고 main에 PR을 올릴 때 CD actions가 수행되어 배포가 되게 하였다.

1) branch 구조

feature/#123 -> dev (default branch) -> main

 

2) CD Script

name: CD

on:
  push:
    branches:
      - main
  pull request:
    branches: 
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@v2

      - uses: actions/cache@v4
        id: cache
        with:
          path: "**/node_modules"
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: Create .env file
        run: |
          echo "VITE_API_KEY=${{ secrets.VITE_API_KEY }}" >> .env
          echo "VITE_NCBI_URL=${{ secrets.VITE_NCBI_URL }}" >> .env

      - name: Build
        run: npm run build

      - name: S3 Deploy
        run: aws s3 sync ./dist s3://biomatz-frontend/ --acl bucket-owner-full-control
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }}

      - name: Invalidate CloudFront Cache
        uses: chetan/invalidate-cloudfront-action@master
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }}
          PATHS: "/*"
        continue-on-error: true

      - name: Microsoft Teams Notification
        uses: skitionek/notify-microsoft-teams@master
        if: always()
        with:
          webhook_url: ${{ secrets.MSTEAMS_WEBHOOK }}
          needs: ${{ toJson(needs) }}
          job: ${{ toJson(job) }}
          steps: ${{ toJson(steps) }}
          dry_run: false

 

2. 수정 사항

 1) s3 버킷 루트 폴더에 배포가 되어 왔는데 그 안에 /dev 와 /prod 폴더를 만들어서 각각의 배포를 수행 해야 한다.

 2) NCBI 사이트로 이동하는 것 같은건 굳이 환경변수로 숨겨줄 필요가 없기 때문에 이를 제거 해도 될 것 같다.

 3) pull request를 script에 넣으면 push 말고 PR만 올려도 수행 된다... 큰 일 날 수 있기 때문에 제거 해야 함

 

 

3. 개선 과정

1) deploy.yml 파일과 deploy-dev.yml 파일을 각각 만들어 주었다. 이 과정에서 PR은 빼고 push 과정만 넣어주었다.

2) S3 Deploy 단계에서 버킷 경로에서 /dev와 /prod를 각각 추가해주었다. 

3) 항상 캐시 무효화를 하는 과정이 필요하므로 Cloudfront 무효화 과정에서 경로를 /*에서 /dev/* 와 /prod/*로 바꿔 주었다.

4) AWS 들어가서 최상위 폴더와 /dev , /prod의 무효화를 생성해서 한 번 수동으로 무효화 해주었다.

 

4. 결과 Script 

1) deploy-dev.yml 

: VITE_TEST_API_KEY를 github actions secrets에 추가해주어 dev일 때는 실제 배포용 서버가 아닌 개발용 서버와 연결 시켜 주었다.

name: CD-DEV

on:
  push:
    branches:
      - dev

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@v2

      - uses: actions/cache@v4
        id: cache
        with:
          path: "**/node_modules"
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: Create .env file
        run: |
          echo "VITE_API_KEY=${{ secrets.VITE_TEST_API_KEY }}" >> .env

      - name: Build
        run: npm run build

      - name: S3 Deploy
        run: aws s3 sync ./dist s3://biomatz-frontend/dev/ --acl bucket-owner-full-control
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }}

      - name: Invalidate CloudFront Cache
        uses: chetan/invalidate-cloudfront-action@master
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }}
          PATHS: "/dev/*"
        continue-on-error: true

      - name: Microsoft Teams Notification
        uses: skitionek/notify-microsoft-teams@master
        if: always()
        with:
          webhook_url: ${{ secrets.MSTEAMS_WEBHOOK }}
          needs: ${{ toJson(needs) }}
          job: ${{ toJson(job) }}
          steps: ${{ toJson(steps) }}
          dry_run: false

 

2) deploy.yml

name: CD

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout source code
        uses: actions/checkout@v2

      - uses: actions/cache@v4
        id: cache
        with:
          path: "**/node_modules"
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-

      - name: Install Dependencies
        if: steps.cache.outputs.cache-hit != 'true'
        run: npm ci

      - name: Create .env file
        run: |
          echo "VITE_API_KEY=${{ secrets.VITE_API_KEY }}" >> .env

      - name: Build
        run: npm run build

      - name: S3 Deploy
        run: aws s3 sync ./dist s3://biomatz-frontend/prod/ --acl bucket-owner-full-control
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }}

      - name: Invalidate CloudFront Cache
        uses: chetan/invalidate-cloudfront-action@master
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ${{ secrets.AWS_REGION }}
          DISTRIBUTION: ${{ secrets.AWS_DISTRIBUTION_ID }}
          PATHS: "/prod/*"
        continue-on-error: true

      - name: Microsoft Teams Notification
        uses: skitionek/notify-microsoft-teams@master
        if: always()
        with:
          webhook_url: ${{ secrets.MSTEAMS_WEBHOOK }}
          needs: ${{ toJson(needs) }}
          job: ${{ toJson(job) }}
          steps: ${{ toJson(steps) }}
          dry_run: false

 

3) AWS

: /dev와 /prod를 나눠주었다.

: 추가로 초기 무효화도 한 번 수동으로 생성 해주었다. 

 

5. 배운 점

개발용, 메인용 배포 분리해야하는 필요성과 중요성을 배웠고 그 방법 또한 처음엔 어려워 보였으나 막상 해보니 괜찮았단 점, 그리고 조금 AWS랑 친해져가고 있단 점이 크게 배운 점으로 다가 왔다.