๊ณฐํ„ฐ๋ทฐ๋Š” ์™œ Cloudflare๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ•˜๊ฒŒ ๋˜์—ˆ์„๊นŒ

Dokcer, AWS, Cloudflare๋ฅผ ๋น„๊ตํ•ด์„œ ๋ฐฐํฌํ•ด๋ณด๊ณ  Cloudflare๋กœ ๋ฐฐํฌํ•˜๊ฒŒ๋œ ์ด์•ผ๊ธฐ์ž…๋‹ˆ๋‹ค.

Profile Picture
milk717
2023-11-13

์ด ๊ฒŒ์‹œ๊ธ€์˜ ์›๋ณธ ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ์šฐ๋ฆฌ NDD ํŒ€์€ Cloudflare๋ฅผ ์‚ฌ์šฉํ•ด์„œ React ํŽ˜์ด์ง€๋ฅผ ๋ฐฐํฌํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธ€์€ ์™œ ์ˆ˜๋งŽ์€ ์„ ํƒ์ง€์ค‘์— Cloudflare๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ•˜๊ฒŒ ๋˜์—ˆ๋Š”์ง€์— ๋Œ€ํ•œ ๊ณผ์ •์ด ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค.

์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐฐํฌํ• ๊นŒ?

์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฐํฌ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ธฐ ์ „์— ๋จผ์ € React ๋ฐฐํฌ ํ”„๋กœ์„ธ์Šค์— ๋Œ€ํ•ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์งš๊ณ  ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค.

  1. ๋นŒ๋“œ: React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฒˆ๋“ค๋Ÿฌ(Webpack, Vite ๋“ฑ)์„ ํ†ตํ•ด ๋นŒ๋“œ๋˜์–ด ์ •์  ํŒŒ์ผ๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
  2. ํŒŒ์ผ ์—…๋กœ๋“œ: ๋นŒ๋“œ๋œ ์ •์  ํŒŒ์ผ์ด ์„œ๋ฒ„์— ์—…๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์— ์—…๋กœ๋“œ๋œ ํŒŒ์ผ์€ ์ธํ„ฐ๋„ท์„ ํ†ตํ•ด ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํ•ด๋‹น ์ฃผ์†Œ๋กœ ์ ‘์† ์‹œ ๋ฒˆ๋“ค๋ง๋œ ์ •์  ํŒŒ์ผ์„ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค.
  3. ์‚ฌ์šฉ์ž ๋™์ž‘: ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)๋Š” ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ๋ฐ›์•„์˜จ ์ •์  ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ๋ฐ›์•„ ์›น ํŽ˜์ด์ง€๋ฅผ ๋žœ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

์œ„ ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉฐ ์ •์  ํŽ˜์ด์ง€๊ฐ€ ๋ฐฐํฌ๋˜๋Š”๋ฐ์š”. ์—ฌ๊ธฐ์„œ ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ React๋Š” SPA๊ตฌ์กฐ๋กœ ๋˜์–ด์žˆ์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ root(/) ๊ฒฝ๋กœ์—์„œ /user๋“ฑ์˜ ๊ฒฝ๋กœ๋กœ ์ด๋™ํ•ด๋„ ์‹ค์ œ๋กœ๋Š” index.html ํ•œ ํŒŒ์ผ ๋‚ด์—์„œ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋•Œ๋ฌธ์— ์ด์— ๋Œ€ํ•œ ์„œ๋ฒ„ ์„ค์ •์„ ๋ณ„๋„๋กœ ํ•˜์ง€ ์•Š์œผ๋ฉด /user ๊ฒฝ๋กœ๋กœ ์ด๋™์‹œ 404ํŽ˜์ด์ง€๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Nginx๋“ฑ์˜ ์›น ์„œ๋ฒ„์™€ ํ•จ๊ป˜ ๋ฐฐํฌํ•ด์„œ ๋ชจ๋“  ๊ฒฝ๋กœ ์š”์ฒญ์„ index.html๋กœ ๋ฆฌ๋‹ค์ด๋ž™์…˜ ํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

SPA ์‚ฌ์ดํŠธ๋ฅผ ๋ฐฐํฌํ•  ๋•Œ ๋ฆฌ๋‹ค์ด๋ž™์…˜์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ด์œ 

Docker๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ•˜๊ธฐ

์‚ฌ์‹ค React๋Š” ์ •์  ์‚ฌ์ดํŠธ๋ผ์„œ Docker๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ–ˆ์„ ๋•Œ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์ œ๊ฐ€ ์ด ์„ ํƒ์ง€๋ฅผ ๊ณ ๋ คํ–ˆ๋˜ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ด์ „ ํ”„๋กœ์ ์Šค์—์„œ ํ•™๊ต ์„œ๋ฒ„์— Node.js์™€ React๋ฅผ ๋ฐฐํฌํ•  ๋•Œ Docker๋ฅผ ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒฝํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ Docker๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ด์ „์— ์ž‘์„ฑํ•ด๋‘” Github Action ํŒŒ์ผ์„ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ ์ œ์ผ ์‰ฝ๊ณ  ๊ฐ„๋‹จํ•  ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ถ€์ŠคํŠธ์บ ํ”„์—์„œ๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ๋ชจ๋…ธ๋ ˆํฌ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์ด์— ๋”ฐ๋ผ ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋ฅผ ํ•œ ๊ณณ์— ์—…๋กœ๋“œํ•˜๋ฉด ๋ฐฐํฌ ๋กœ์ง์ด ๊ฐ„์†Œํ™” ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋ถ€์ŠคํŠธ์บ ํ”„์—์„œ ํŒ€์—๊ฒŒ NCP๋ฅผ ์ง€์›ํ•ด์ฃผ๋Š”๋ฐ ๋ถ€์ŠคํŠธ์บ ํ”„ ๊ธฐ๊ฐ„์ด ์ข…๋ฃŒ๋˜๊ณ  ๋‚˜๋ฉด NCP์˜ ์ง€์› ๋˜ํ•œ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํŒ€์€ ์„œ๋น„์Šค๊ฐ€ ๋‹ซํžˆ์ง€ ์•Š๊ณ  ๊ณ„์† ์‚ด์•„์žˆ๋Š” ๊ฒƒ์„ ์›ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— NCP ์ง€์›์ด ์ข…๋ฃŒ๋˜๊ณ  ๋‚˜๋ฉด ๋ฐฐํฌ๋œ ํŒŒ์ผ์„ ๋‹ค๋ฅธ ์„œ๋ฒ„๋กœ ์˜ฎ๊ฒจ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ๋„์ปค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ–ˆ๋‹ค๋ฉด ์„œ๋ฒ„๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ๋™์ผํ•œ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‰ฝ๊ฒŒ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ„์™€ ๊ฐ™์€ ์ด์œ ๋“ค์ด ์žˆ์—ˆ์ง€๋งŒ ์šฐ๋ฆฌ ํŒ€์€ Docker๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์šฐ๋ฆฌ๊ฐ€ NCP๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ๋กœ ๊ฒฐ์ •ํ•ด์„œ ํ˜ธ์ŠคํŒ… ์„œ๋ฒ„๋ฅผ ๋ณ€๊ฒฝํ•  ์ผ๋„ ์—†์—ˆ๊ณ , ๋ชจ๋…ธ๋ ˆํฌ๋ผ๊ณ  ํ•ด์„œ ๊ผญ ํ•œ ์„œ๋ฒ„์— ์—…๋กœ๋“œํ•  ํ•„์š”๋Š” ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ํŒ€์€ NCP ๋Œ€์‹  AWS EC2๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๊ณ , ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋ฅผ ํ•œ ๊ณณ์— ์—…๋กœ๋“œํ•˜๋Š” ๊ฒƒ์€ ์˜คํžˆ๋ ค EC2์˜ ๋น„์šฉ๋งŒ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ์ผ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด ์„ ํƒ์ง€๋Š” ๊ธฐ๊ฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ „ ํ”„๋กœ์ ํŠธ์—์„œ Docker๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌ๋ฅผ ํ–ˆ๋˜ ์ด์œ 

์•„๊นŒ ์ œ๊ฐ€ Docker ๋„์ž…์„ ์—ผ๋‘ํ–ˆ๋˜ ํฐ ์ด์œ ์ค‘ ํ•˜๋‚˜๋Š” ์ด์ „์— Docker๋ฅผ ํ†ตํ•ด ๋ฐฐํฌํ–ˆ๋˜ ๊ฒฝํ—˜์ด ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋•Œ๋Š” ๋ฐฐํฌ ๋ฐฉ์‹์— ๋Œ€ํ•ด ํฐ ๊ณ ๋ฏผ์„ ํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ Docker๋ฅผ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ์š”. ๊ทธ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.

  • ๋ฐฐํฌํ•ด์•ผํ•˜๋Š” ์„œ๋ฒ„๊ฐ€ ํ•™๊ต ์ „์‚ฐ์›์œผ๋กœ๋ถ€ํ„ฐ ์ œ๊ณต๋ฐ›์€ ๋ฆฌ๋ˆ…์Šค ์„œ๋ฒ„์˜€๊ธฐ ๋•Œ๋ฌธ์— S3, Cloudflare ๋“ฑ ๋‹ค๋ฅธ ์„ ํƒ์ง€๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ์ „์‚ฐ์› ์„œ๋ฒ„์—์„œ ๋Œ์•„๊ฐ€๋Š” ๋‹ค๋ฅธ ์„œ๋น„์Šค๋“ค์€ ๋Œ€๋ถ€๋ถ„ ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์œ„์—์„œ ๋Œ์•„๊ฐ€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ๋„์ปค๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์ „์‚ฐ์› ์„œ๋ฒ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ „์‚ฐ์› ๋ฆฌ๋ˆ…์Šค ์„œ๋ฒ„์˜ ๊ตฌ์กฐ
  • ์–ผ๋งˆ ์ „์— ์Šคํ”„๋ง ์„œ๋ฒ„๋ฅผ ๋ฐฐํฌํ•˜๋ฉด์„œ ์ž‘์„ฑํ•ด์ค€ Dockerfile, Github Action ํŒŒ์ผ์ด ์žˆ์—ˆ๊ณ , ์ด๋ฅผ ์กฐ๊ธˆ ์ˆ˜์ •ํ•ด์„œ ๋น ๋ฅด๊ฒŒ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๋ฐฐํฌ์‹œ์— ์‚ฌ์šฉํ–ˆ๋˜ ์Šคํฌ๋ฆฝํŠธ

name: Docker CD

on:
  push:
    branches:
      - 'production'
    tags:
      - 'v*'
  pull_request:
    branches:
      - 'production'

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18.x'

      - name: Make env
        run: |
          touch ./.env
          echo "${{ secrets.ENV }}" > ./.env
          echo .env
        shell: sh

      - name: Install dependencies
        run: yarn

      - name: Build Project
        run: yarn build

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: |
            ${{ secrets.DOCKER_USERNAME }}/home-appcenter
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}

      - name: Login to DockerHub
        if: github.event_name != 'pull_request'
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: ${{ github.event_name != 'pull_request' }}
          tags: ${{ steps.meta.outputs.tags }}

      - name: Deploy
        uses: appleboy/ssh-action@v0.1.7
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.PASSWORD }}
          script: |
            docker stop inu-hompage
            docker rm inu-hompage
            docker pull ${{ secrets.DOCKER_USERNAME }}/home-appcenter:production
            docker run -d --name inu-hompage -p 3000:3000 ${{ secrets.DOCKER_USERNAME }}/home-appcenter:production
            docker image prune -f

S3์™€ CloundFront๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ•˜๊ธฐ

AWS๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•œ ํ›„ S3๋ผ๋Š” ์„ ํƒ์ง€๊ฐ€ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค! S3๋Š” AWS์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. React๋Š” ์ •์  ์‚ฌ์ดํŠธ์ด๋ฏ€๋กœ ์Šคํ† ๋ฆฌ์ง€์— ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์„ ์˜ฌ๋ ค๋‘๋Š” ๋ฐฉ์‹์œผ๋กœ๋„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. S3๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ๋“ค์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฐฐํฌ ๊ณผ์ •์ด ๋งค์šฐ ๊ฐ„๋‹จํ•ด์ง„๋‹ค! ๋นŒ๋“œ๋œ React์•ฑ ํŒŒ์ผ์„ S3 ๋ฒ„ํ‚ท์— ์—…๋กœ๋“œ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ์„œ๋ฒ„ ์„ค์ •์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • CloundFront์—์„œ ์ปค์Šคํ…€ ์—๋Ÿฌ ์‘๋‹ต์„ ์ง€์ •ํ•ด์„œ nginx ์—†์ด React์•ฑ์˜ ๋ผ์šฐํŒ… ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

S3์— ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ๋ฒ•

์ „์ฒด ์‹œ๋‚˜๋ฆฌ์˜ค

  • S3 ์ €์žฅ์†Œ์— public์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” IAM ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • Github Action์„ ์‚ฌ์šฉํ•ด์„œ S3์— ์›นํŒฉ์œผ๋กœ ๋ฒˆ๋“ค๋ง๋œ ํŒŒ์ผ์„ ์˜ฌ๋ฆฝ๋‹ˆ๋‹ค
  • S3๋Š” ์ •์  ํŒŒ์ผ ํ˜ธ์ŠคํŒ…์ด๋ฏ€๋กœ ๋ฆฌ์•กํŠธ ๋ผ์šฐํ„ฐ ์ฒ˜๋ฆฌ๋Š” Cloudfront์—์„œ ๋”ฐ๋กœ ์ฒ˜๋ฆฌํ•ด์ค๋‹ˆ๋‹ค.
  • CloudFront๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์˜ค๋ฅ˜ ์‘๋‹ต์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ, 404 ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ 'index.html'๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋™์ž‘์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

IAM ์‚ฌ์šฉ์ž ์ƒ์„ฑ

  1. IAM ์„œ๋น„์Šค๋กœ ์ด๋™ํ•ด์„œ ์‚ฌ์šฉ์ž ์ƒ์„ฑ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  2. IAM ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์Œ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.

  • AmazonS3FullAccess
  • CloudFrontFullAccess

  1. ์‚ฌ์šฉ์ž๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  2. ์•ก์„ธ์Šคํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅํ•ด๋‘ก๋‹ˆ๋‹ค. (๋‹ค์‹œ ๋ณผ ์ˆ˜ ์—†์œผ๋‹ˆ ๊ผญ!! ์ €์žฅํ•ด๋‘์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.)

S3 ๋ฒ„ํ‚ท ์ƒ์„ฑํ•˜๊ธฐ

  1. ๋ฒ„ํ‚ท์— ์ ๋‹นํ•œ ์ด๋ฆ„๊ณผ ๋ฆฌ์ „์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  2. ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค ์ฐจ๋‹จ์€ ์ฒดํฌ๋ฐ•์Šค ํ•ด์ œ๋ฅผ ํ•ด์ค์‹œ๋‹ค.

  • ์šฐ๋ฆฌ๋Š” S3๋ฅผ ์ •์  ์‚ฌ์ดํŠธ ๋ฐฐํฌ์šฉ์œผ๋กœ ์‚ฌ์šฉํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ํผ๋ธ”๋ฆญ ์—‘์„ธ์Šค๊ฐ€ ํ—ˆ์šฉ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  1. ๋‚˜๋จธ์ง€ ์˜ต์…˜์€ ๊ทธ๋Œ€๋กœ ๋‘”์ฑ„๋กœ ๋ฒ„ํ‚ท์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  2. ์ƒ์„ฑ๋œ ๋ฒ„ํ‚ท์˜ ์†์„ฑ ํƒญ์œผ๋กœ ์ด๋™ํ•ด์„œ ๋งจ ์•„๋ž˜๋กœ ์Šคํฌ๋กค์„ ๋‚ด๋ ค์„œ ์ •์  ์›น ์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ… ์„ค์ •์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

  3. ์ •์  ์›น ์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ… ์˜ต์…˜์„ ํ™œ์„ฑํ™”๋กœ ๋ฐ”๊ฟ”์ค€ ํ›„ ์ธ๋ฑ์Šค ๋ฌธ์„œ์™€ ์˜ค๋ฅ˜ ๋ฌธ์„œ์˜ ํŒŒ์ผ๋ช…์„ index.html๋กœ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค.

  4. ๋ฒ„ํ‚ท์˜ ๊ถŒํ•œ ํƒญ์œผ๋กœ ์ด๋™ํ•ด์„œ ๋ฒ„ํ‚ท ์ •์ฑ…์„ ํŽธ์ง‘ํ•ฉ๋‹ˆ๋‹ค.

  5. ๋ฒ„ํ‚ท ARN์„ ๋ณต์‚ฌํ•œ ํ›„ ์ •์ฑ… ์ƒ์„ฑ๊ธฐ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

  6. ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์ฑ…์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

  • Select Type of Policy: S3์ •์ฑ…์ด๋ฏ€๋กœ S3 Bucket Policy๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  • Principal์˜ * ์€ ๋ชจ๋“  ์œ ์ €๋ฅผ ๋œปํ•ฉ๋‹ˆ๋‹ค.
  • Actions๋Š” GetObject๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  • ARN์—๋Š” ์•„๊นŒ ๋ณต์‚ฌํ–ˆ๋˜ ๋ฒ„ํ‚ท ARN ๋’ค์— /*๋ฅผ ๋ถ™์—ฌ์ค๋‹ˆ๋‹ค.
  1. Generate Policy๋ฅผ ๋ˆŒ๋Ÿฌ์„œ ์ƒ์„ฑ๋œ ์ •์ฑ…์„ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.

  2. ์ƒ์„ฑ๋œ ์ •์ฑ…์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

S3๋กœ ์˜ฌ๋ฆฌ๋Š” Github Action ํŒŒ์ผ ์ž‘์„ฑํ•˜๊ธฐ

name: Deploy React App to Amazon S3

on:
  push:
    branches:
      - dev

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Change to FE directory
        run: cd ./FE

      - name: Install Dependencies
        run: yarn install
        working-directory: ./FE

      - name: Build
        run: yarn build
        working-directory: ./FE

      - name: Deploy to S3
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        run: |
          aws s3 sync ./FE/dist/ s3://${{ secrets.AWS_S3_BUCKET }} --region ap-northeast-2 --delete

์šฐ๋ฆฌํŒ€์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ์˜ฌ๋ผ๊ฐ€์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— FE ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™ํ•˜๋Š” ๊ณผ์ •์„ ์Šคํฌ๋ฆฝํŠธ์— ์ถ”๊ฐ€๋กœ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

โ”œโ”€โ”€ BE
โ”œโ”€โ”€ FE
โ””โ”€โ”€ README.md

์ด ์•ก์…˜ ํŒŒ์ผ์— ํ•„์š”ํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • AWS_ACCESS_KEY_ID: ์œ„์—์„œ ์ƒ์„ฑํ•œ IAM ์‚ฌ์šฉ์ž์˜ ์—‘์„ธ์Šค ํ‚ค ID
  • AWS_SECRET_ACCESS_KEY : IAM ์‚ฌ์šฉ์ž์˜ ์—‘์„ธ์Šค ํ‚ค๋ฅผ ์ฒ˜์Œ ๋ฐœ๊ธ‰๋ฐ›์„ ๋•Œ ๋ฐ›์•˜๋˜ ์‹œํฌ๋ฆฟ ํ‚ค
  • AWS_S3_BUCKET: S3 ๋ฒ„ํ‚ท์˜ ์ด๋ฆ„

CloundFront์—์„œ ์ปค์Šคํ…€ ์—๋Ÿฌ ์‘๋‹ต ์„ค์ •ํ•˜๊ธฐ

์œ„์™€ ๊ฐ™์€ ๊ณผ์ •์„ ๊ฑฐ์น˜๊ณ  Github Action์ด ์ˆ˜ํ–‰๋˜๊ณ  ๋‚˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด S3 ๋ฒ„ํ‚ท์— ๋นŒ๋“œ๋œ ํŒŒ์ผ์ด ์˜ฌ๋ผ๊ฐ‘๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ index.html์— ์ ‘๊ทผํ•ด๋ณด๋ฉด ์šฐ๋ฆฌ์˜ ํŽ˜์ด์ง€๋Š” ๋ณด์ด์ง€ ์•Š๊ณ  404์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋งŒ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ํ•˜์œ„ ๊ฒฝ๋กœ๋กœ ์ ‘์†ํ•ด๋ณด๋ฉด 403 ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด S3 ๋ฒ„ํ‚ท์—์„œ ํผ๋ธ”๋ฆญ ์ ‘๊ทผ์€ index.html๋งŒ ํ—ˆ์šฉ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

์ด๋Ÿฌํ•œ ๋ฌธ์ œ์ ์€ ์ปค์Šคํ…€ ์—๋Ÿฌ ์‘๋‹ต์„ ์„ค์ •ํ•ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธ€ ์ดˆ๋ฐ˜๋ถ€์—์„œ ์„ค๋ช…ํ–ˆ๋“ฏ์ด SPA์—์„œ ๋ผ์šฐํ„ฐ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์›น์„œ๋ฒ„ ๋“ฑ์—์„œ ๋ฆฌ๋‹ค์ด๋ž™์…˜ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•œ๋ฐ์š”. CloundFront์—์„œ ์—๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ index.html๋กœ ์ปค์Šคํ…€ํ•˜๋ฉด ์ด ๋™์ž‘์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. CloudFront ๋ฐฐํฌ ์ƒ์„ฑํ•˜๊ธฐ AWS CloudFront ์„œ๋น„์Šค์— ๋“ค์–ด๊ฐ€์„œ S3๋กœ ๋ฐฐํฌ๋œ ์›น์‚ฌ์ดํŠธ์˜ ๋„๋ฉ”์ธ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  2. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฉํ™”๋ฒฝ์€ ๋น„ํ™œ์„ฑํ™” ํ•œ ํ›„ ๋ฐฐํฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (๋ฐฉํ™”๋ฒฝ ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋ˆ๋“ค์–ด์š”!)

  3. ์ƒ์„ฑ๋œ ๋ฐฐํฌ์—์„œ ์‚ฌ์šฉ์ž ์ •์˜ ์˜ค๋ฅ˜ ์‘๋‹ต ์ƒ์„ฑ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

  4. ์•„๋ž˜์™€ ๊ฐ™์ด 404 ์—๋Ÿฌ์— ๋Œ€ํ•ด index.html๋กœ ๋ฆฌ๋‹ค์ด๋ž™์…˜ ์‹œ์ผœ์ฃผ๊ณ  200 ์‘๋‹ต์„ ๋‚ด๋ ค์ฃผ๋Š” ์ปค์Šคํ…€ ์‘๋‹ต์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

  5. 403 ์—๋Ÿฌ์— ๋Œ€ํ•ด์„œ๋„ ๋™์ผํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค.

  6. CloudFront์˜ ๋ฐฐํฌ ๋„๋ฉ”์ธ์œผ๋กœ ์ ‘์†ํ•˜๋ฉด ํŽ˜์ด์ง€๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ํ‘œ์‹œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

S3์™€ CloudFront๋ฅผ ์„ ํƒํ•˜์ง€ ์•Š์€ ์ด์œ 

์œ„์˜ ๊ณผ์ •์ฒ˜๋Ÿผ S3์™€ CloudFront์— ๋Œ€ํ•ด ํ•™์Šตํ•˜๊ณ  ๋ฐฐํฌํ•˜๋Š” ๊ณผ์ •๋„ ์ง์ ‘ ์ˆ˜ํ–‰ํ–ˆ์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์„ ์„ ํƒํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋ฒ„์ „ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์ด Cloudflare์— ๋น„ํ•ด ๋นˆ์•ฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ์š”. Cloudflare์—์„œ๋Š” ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๋กœ PR์ด ๋จธ์ง€๋  ๋•Œ ๋งˆ๋‹ค ํ•ด๋‹น ๋ฒ„์ „์— ๋Œ€ํ•œ preview URL์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ด์ค๋‹ˆ๋‹ค. ์ด ๋ฐ–์—๋„ S3์™€ CloudFront์—์„œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ๋“ค์˜ ์ƒ์œ„ ํ˜ธํ™˜๋˜๋Š” ์ž‘์—…์„๋“ค Cloudflare์—์„œ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— S3์™€ CloudFront ๋Œ€์‹  Cloudflare๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

Cloudflare๋กœ ๋ฐฐํฌํ•˜๊ธฐ

์šฐ๋ฆฌํŒ€์€ ์ตœ์ข…์ ์œผ๋กœ Cloudflare๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฐํฌ ๋ฐฉ์‹์„ ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์žฅ์ ๋“ค์ด ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

  • ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ ๋งŒ์œผ๋กœ ๋ฐฐํฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , CDN์„ ํ†ตํ•œ ์บ์‹ฑ๋„ ์ž๋™์œผ๋กœ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.
  • PR ๋ฒ„์ „๋ณ„ ์›น์‚ฌ์ดํŠธ ์Šค๋ƒ…์ƒท ์‚ฌ์‹ค์ƒ Cloudflare๋ฅผ ์„ ํƒํ•œ ๊ฐ€์žฅ ์ฃผ๋œ ์ด์œ ์ธ๋ฐ์š”. Cloudflare์—์„œ๋Š” ๋ฉ”์ธ ๋ธŒ๋žœ์น˜๋กœ PR์„ ๋ณด๋‚ผ ๋•Œ ๋งˆ๋‹ค ์ด์— ํ•ด๋‹นํ•˜๋Š” ์Šค๋ƒ…์ƒท ๋ฒ„์ „์˜ ์›น์‚ฌ์ดํŠธ๋ฅผ ์ƒ์„ฑํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ด์ค๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ๋‚˜์ค‘์— UX๋ฅผ ๊ฐœ์„ ํ•˜๊ฑฐ๋‚˜ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ์ง„ํ–‰ํ–ˆ์„ ๋•Œ ์ด์ „ ๋ฒ„์ „๊ณผ ๋” ์ˆ˜์›”ํ•˜๊ฒŒ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค. Cloudflare์˜ ๋ธŒ๋žœ์น˜๋ณ„ ์Šค๋ƒ…์ƒท ๊ธฐ๋Šฅ

Cloudflare ๋ฐฐํฌ ๋ฐฉ๋ฒ•

  1. Cloudflare์—์„œ Workers & Pages ํƒญ์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

  2. Pages ํƒญ์—์„œ Connect to Git ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ €์žฅ์†Œ์™€ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

  3. Connect Github๋ฅผ ํ†ตํ•ด ๊นƒํ—ˆ๋ธŒ์™€ ์—ฐ๋™ํ•ฉ๋‹ˆ๋‹ค.

  4. ์—ฐ๊ฒฐํ•˜๊ณ ์‹ถ์€ ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์„ ํƒํ•œ ํ›„ ์„ค์ •์„ ๋งˆ์นฉ๋‹ˆ๋‹ค.

  5. ํ”„๋กœ์ ํŠธ์˜ ๋นŒ๋“œ ์„œ์ •์— ๋งž๊ฒŒ ์•„๋ž˜ ๊ฐ’๋“ค์„ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

  6. Save and Deploy๋ฅผ ๋ˆŒ๋Ÿฌ์ฃผ๋ฉด ๋นŒ๋“œ ์„ค์ •์ด ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค~!

๋งˆ๋ฌด๋ฆฌ

Docker, S3์™€ CloudFront, Cloudflare๋ฅผ ํ†ตํ•ด React ์›น์‚ฌ์ดํŠธ๋ฅผ ๋ฐฐํฌํ•ด๋ณธ ๊ฒฐ๊ณผ Cloudflare๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ฐฐํฌํ•˜๋Š” ๋ฐฉ์‹์„ ์ฑ„ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐํฌ ์—…๋ฌด๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ๋Š” ํฐ ํ•™์Šต ์—†์ด "์˜ฌ๋ฆฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค!" ๋ผ๋Š” ์ƒ๊ฐ์„ ๊ฐ–๊ณ  ์žˆ์—ˆ๋Š”๋ฐ์š”. ์ด๋ฒˆ ๊ธฐํšŒ์— ๋‹ค์–‘ํ•œ ๋ฐฐํฌ ๋ฐฉ์‹์— ๋Œ€ํ•ด ํ•™์Šต ํ•ด๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ์œ ์ตํ–ˆ์Šต๋‹ˆ๋‹ค.๐Ÿ˜Š ํ•™์Šตํ•œ ๋‚ด์šฉ์— ๋น„ํ•ด Cloudflare์—์„œ ๋„ˆ๋ฌด ์‰ฝ๊ฒŒ ๋ฐฐํฌ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์„œ ํ—ˆ๋ฌดํ•˜๊ธฐ๋„ ํ–ˆ์Šต๋‹ˆ๋‹ค. (~~๋กœ๋ด‡์—๊ฒŒ ์ผ์ž๋ฆฌ๋ฅผ ๋บ๊ธด ๋…ธ๋™์ž๊ฐ€ ๋œ ๊ธฐ๋ถ„~~) ์•ž์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ Cloudflare์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์— ๋Œ€ํ•ด ์•Œ๊ฒŒ๋œ๋‹ค๋ฉด ์ถ”๊ฐ€๋กœ ํฌ์ŠคํŒ…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹คใ…Žใ…Ž

์ฐธ๊ณ  ์ž๋ฃŒ

AWS S3๋กœ React ๋ฐฐํฌํ•˜๊ธฐ

ยฉ 2024 Adultlee. All rights reserved.Made with โค by ์ด์„ฑ์ธ