๐จ3๋ถ๋ง์ Next.js ์๋น์ค ์ฅ์ ๋์ ๋์ํ๊ธฐ: GitHub Actions + AWS ECS + CodeDeploy ๋กค๋ฐฑ ์์คํ
0. ํ๋กค๋ก๊ทธ
์ด๋ฒ๊ธ์์๋ ์ง๋๋ฒ๊น์ง ๊ตฌ์ถํ ECS ํ๊ฒฝ์์, ์ค๋ฅ ๋ฐ์ ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ์ ์ผ๋ก ๋กค๋ฐฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค. ํนํ GitHub Actions, AWS CodeDeploy๋ฅผ ํ์ฉํ์ฌ ์๋ํ๋ ๋ฐฐํฌ ๋ฐ ๋กค๋ฐฑ ํ๋ก์ธ์ค๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ์ค์ฌ์ผ๋ก ์ค๋ช ๋๋ฆด ์์ ์ ๋๋ค.
๋ฌธ์ ์ค๋ช
ํํ๋ก์ด ์ ๊ธฐ ๋ฐฐํฌ์ ๋ , ๋ ๊ทธ๋ฌ๋ฏ ๋ฐฐํฌ ๋ฒํผ์ ๋๋ฅด๊ณ ์ปคํผ ํ ์์ ์ฌ์ ๋ฅผ ์ฆ๊ธฐ๋ฉฐ ๋ฐฐํฌ ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ ธ์ต๋๋ค. ์ปคํผ๋ฅผ ๋ค ๋ง์๊ณ ๋์์ผ ๋ฐฐํฌ ์๋ฃ ๋ฉ์์ง๋ฅผ ํ์ธํ๋ฉฐ "์ค๋๋ ๋ฌด์ฌํ ๋์ด๊ฐ๊ตฌ๋"๋ผ๋ ์๋์ ํ์จ์ ๋ด์ฌ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ฝ 2์๊ฐ ํ, ํ ๊ณ ๊ฐ์ผ๋ก๋ถํฐ "ํน์ ๊ธฐ๋ฅ ์ฌ์ฉ ์ ํ์ด์ง๊ฐ ๋ค์ด๋๋ค"๋ ์ ๊ณ ๊ฐ ์ ์๋์์ต๋๋ค. ํด๋น ๊ธฐ๋ฅ์ ๋น์ผ ์๋กญ๊ฒ ๋ฐฐํฌ๋ ๊ฒ์ผ๋ก, ์ํฉ์ ์ฌ๊ฐ์ฑ์ ๋ํ์ต๋๋ค.
๋ฌธ์ ์ ์์ธ์ ์กฐ์ฌํ ๊ฒฐ๊ณผ, ๋ฐฑ์๋์ ์ฌ์ ์ ํ์ํ API ๋ฐฐํฌ ์ผ์ ์ด ๋ด๋ถ ์ปค๋ฎค๋์ผ์ด์ ์ค๋ฅ๋ก ์ธํด ์งํ๋์ง ์์ ์ํ์์ ํ์ธํ ์ ์์์ต๋๋ค. ๋ฐฑ์๋์์๋ ์์ง ๊ฐ๋ฐ์ด ์งํ ์ค์ด์์ผ๋, ํ๋ก ํธ์๋์์๋ ์ด๋ฏธ ๋ฐฐํฌ๋ ์ํฉ์ด์๊ธฐ์ ๊ธด๊ธํ๊ฒ ๋กค๋ฐฑ์ ๊ฒฐ์ ํ๊ฒ ๋์์ต๋๋ค.
๋ฐฐํฌํ๋ ๋ธ๋์น๋ฅผ ์ฌํ์ธํ๊ณ ๋น๋๋ถํฐ ๋ฐฐํฌ๊น์ง ์งํํ๋ ๋ฐ ์ด 30๋ถ์ด ์์๋์์ต๋๋ค.
๋น๋ก ๋น์ฅ์ ์๊ธฐ๋ ํด์๋์์ผ๋, ์ด๋ฌํ ์ํฉ์ด ์ฌ๋ฐ๋ ๊ฒฝ์ฐ๋ฅผ ๋๋นํ์ฌ ๋ณด๋ค ์ ์ํ๊ณ ํจ์จ์ ์ผ๋ก ๋์ํ ์ ์๋ ์์คํ ์ ํ์์ฑ์ ์ ์คํ ๋๋ผ๊ฒ ๋์์ต๋๋ค. ์ด์ ๋ฐ๋ผ, ๋กค๋ฐฑ ์์คํ ์ ๊ฐ์ ์ ๊ฒฐ์ฌํ๊ฒ ๋์์ต๋๋ค.
1. ํ์ฌ ๋ฌธ์ ์ค์
-
ํ์ํ ๋ฐฐํฌ ๋ฒ์ ์ ์ ๋ฐ ๊ฒฐ์
- ํ์ํ ๋ฒ์ ์ ๋ ธ์ ์ ์์ฑ๋ ๋ฐฐํฌํธ๋ ์ปค๋ฅผ ํตํด ์ฐพ๋๋ค.
- ํด๋น merge pr๋ฅผ ์ฐพ๋๋ค.
- ์ฝ๋๋ฅผ ์ฝ๊ณ ํ์ํ ๋ด์ฉ์ธ์ง ๊ฒํ ํ๋ค.
โป ํนํ 2๋ฒ๊ณผ 3๋ฒ ๋จ๊ณ์์๋ ์์ ์๊ฐ์ด ๋ง๊ณ , ์ค์๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ๋ ์์์ ์ ๋ ํด์ผ ํฉ๋๋ค.
-
๋น๋ ๋ฐ ๋ฐฐํฌ
- ๋น๋ (์ฝ 6๋ถ ์์): ์ด๋ฏธ ECR์ ๋ฑ๋ก๋ ์ด๋ฏธ์ง๊ฐ ์กด์ฌํจ์๋ ๋ถ๊ตฌํ๊ณ , ์ํฉ์ ๋ฐ๋ผ ์ฌํ์ฉํ์ง ์๊ณ ์๋กญ๊ฒ ๋น๋๋ฅผ ์งํ ํฉ๋๋ค.
- ๋ฐฐํฌ (์ฝ 3๋ถ ์์): ๋น๋ ์๋ฃ ํ ๋ฐฐํฌ ์ ์ฐจ๋ฅผ ์งํํฉ๋๋ค.
2. ๊ฐ์ ๋ชฉํ
esc ์ code deploy ๊ฐ ์ฐ๋ ๋์ด ์์ผ๋ฉด task definition์ ์๋ก ๋ง๋ค์ด ์ฌ๋ฆฌ๋ฉด ํด๋น ํ ์คํฌ๋ฅผ ์๋ก ์ํ ํฉ๋๋ค. ์ด๋ฅผ ์ด์ฉํ์ฌ ๋กค๋ฐฑ์ ๊ตฌํ ํฉ๋๋ค.
-
ํจ์จ์ ์ธ ๋ฒ์ ์ ์ ๋ฐ ๋กค๋ฐฑ ์ ์ฐจ
- ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ฒด๊ณํํ์ฌ ํ์ํ ๋ฐฐํฌ ๋ฒ์ ์ ์ฝ๊ณ ๋น ๋ฅด๊ฒ ํ์ธํ ์ ์๋๋ก ๊ฐ์ ํฉ๋๋ค.
- ์ฝ๋ ๊ฒํ , ๋น๋, ๋ฐฐํฌ ์ ๊ณผ์ ์์ ๋ถํ์ํ ์๊ฐ ๋ญ๋น๋ฅผ ์ค์ด๊ธฐ ์ํด ์๋ํ๋ ๊ฒ์ฆ ์ ์ฐจ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
-
๋ฐฐํฌ ์๊ฐ ๋จ์ถ
- ECR ์ด๋ฏธ์ง๋ฅผ ์ฌํ์ฉํ ์ ์๋ ํ๊ฒฝ์ ๋ง๋ จํ์ฌ, ๋น๋ ์๊ฐ์ ๊ฐ๋ฅํ ํ ๋จ์ถํฉ๋๋ค.
- ๋ถํ์ํ ํ๋ก์ธ์ค๋ฅผ ์ ๊ฑฐํ์ฌ ๋ฐฐํฌ์ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ์ค์ ๋๋ค.
-
๋ฌธ์ ๋ฐ์ ์ ๋น ๋ฅธ ๋์ฒ
- ๋กค๋ฐฑ์ด ์ ์ํ ์คํ๋ ์ ์๋๋ก ๊ธฐ์กด ์คํฌ๋ฆฝํธ ๋ฐ ์ค์ ์ ๊ฐ์ํํฉ๋๋ค.
- ๋ฌธ์ ๋ฐ์ ์ ์๋ฆผ ๋ฐ ๊ด๋ จ ์ ๋ณด๋ฅผ ๋น ๋ฅด๊ฒ ์ ๊ณตํ๋ ์์คํ ์ ์ฐ๊ณ ๋์ ํฉ๋๋ค.
3 ๊ฐ์ ๋ฐฉ๋ฒ
-
ํจ์จ์ ์ธ ๋ฒ์ ์ ์ ๋ฐ ๋กค๋ฐฑ ์ ์ฐจ
-
๋ฒ์ ๊ด๋ฆฌ ์์คํ ๊ฐ์
- ๋ฐฐํฌ ํ๊ธฐ ์ ์ ๋ ธ์ ์ ๋ฐฐํฌ ํธ๋ ์ปค์ ๋ด์ฉ๊ณผ ๋ฒ์ ์ ์ ์ด ๋ด์ฉ์ ๋ฐ๋ก ํ์ธ ํ๋๋ก ํ๊ธฐ
- ๋ฐฐํฌ ์ package.json์ ์๋ versoin์ ์ฌ์ฉํด ecr์ ํด๋น ๋ฒ์ ๊ณผ latest๋ฅผ ๋๋ค push ํ๋ค.
-
yaml
- name: 'VERSION ์ถ์ถ ๋ฐ ๊ฒ์ฆ' id: set-version run: | # package.json์์ version ์ถ์ถ VERSION=$(jq -r '.version' apps/web1/package.json) VERSION="v${VERSION}" # ๋ฒ์ ๊ฐ์ด ์ฌ๋ฐ๋ฅธ์ง ๊ฒ์ฆ if [[ ! $VERSION =~ ^v[0-9a-zA-Z._-]+$ ]]; then echo "์ ํจํ์ง ์์ ๋ฒ์ ํ์์ ๋๋ค: $VERSION" exit 1 fi echo "VERSION=$VERSION" >> $GITHUB_ENV echo "ํ์ ๋ ๋ฒ์ : $VERSION" - name: '๋์ปค ์ด๋ฏธ์ง ๋น๋ & ECR ํธ์ฌ ' id: build-image run: | DOCKER_BUILDKIT=1 docker build \ docker build docker tag ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:latest ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:${{ env.VERSION }} docker push ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:${{ env.VERSION }} docker push ${{ secrets.AWS_ECR_REPOSITORY_NEXT }}:latest
-
๋ฒ์ ์กฐํ ์๋ํ
- git acton ์ workflow์ ํตํด์ ์ฌ์ฉํ๊ณ ์ ํ๋ vesion์ ์ ๋ ฅ ๋ฐ์ต๋๋ค.
-
yaml
workflow_dispatch: inputs: version: description: '๋ฒ์ ๋ฒํธ๋ฅผ ์ ๋ ฅํ์ธ์ ex) v1.0.0' required: true default: 'latest' - ํน์ ๋ฒ์ ์ image๊ฐ ecr์ ์๋ ์ง ํ์ธ ํฉ๋๋ค.
-
yaml
- name: 'ECR image tag ํ์ธ' run: | aws ecr describe-images \ --repository-name web1 \ --image-ids imageTag=${{ env.VERSION }} \ >/dev/null 2>&1 && echo "Image found" || { echo "Image not found"; exit 1; }
-
๋กค๋ฐฑ ์ ์ฐจ ์ต์ ํ
- task-definition ๋ด ์ด๋ฏธ์ง ํ๊ทธ๋ฅผ ์ง์ ๋ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ ํฉ๋๋ค.
-
yaml
- name: 'task-definition ์ ๋ฐ์ดํธ' run: | sed -i -e 's|\(web1\)"|\1:${{ env.VERSION }}"|g' \ -e 's|\(web1\)"|\1:${{ env.VERSION }}"|g' \ ./deploy/ops/web1/task-definition.json - ecs deploy๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐํฌ๋ฅผ ์ํ ํฉ๋๋ค.
-
yaml
- name: '[ROLLBACK] ECS ๋กค๋ฐฑ ๋ฐฐํฌ' run: | aws ecs deploy \ --task-definition ./deploy/ops/web1/task-definition.json \ ~~ ๋๋จธ์ง arg
-
4. ์ํ ๊ฒฐ๊ณผ
๋ฌธ์ํ๋ ๊ธ์ ํ์ธํ์ฌ ๋ฐฐํฌ ํ๋ฏ๋ก ์ฝ๋๋ฅผ ๋ณด๊ณ ๋ด์ฉ์ ํ์ธ ์ ํด๋ ๋๋ฉฐ ์ด๋ฏธ ecr์ ๋ฑ๋ก๋ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฌ์ฉํจ์ผ๋ก ๋น๋ ์๊ฐ์ ์ค์ผ ์ ์์ต๋๋ค.
๊ทธ๋์ ๋ฐฐํฌ ์๊ฐ(3๋ถ)๋ง ์์ผ๋ฉด ์์ ์ ์ธ ๋กค๋ฐฑ์ ์ํ ํ ์ ์์ต๋๋ค. ์ฌ์ง์ด ํน์ ๊ฐ๋ฐ์์๊ฒ ์์กดํ์ง ์๊ณ ๋๊ตฌ๋ ๋กค๋ฐฑ์ ์ํ ํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ด์ ๋ค์ ๋ง์ ๋๊ณ ํ ์คํฌ๋ฅผ ์ํํ๋ฌ ๊ฐ ์ ์๊ฒ ๋์์ต๋๋ค.(์ ๋ง?)
5. ์์ฌ์ด ๋ถ๋ถ
์ ํฌ ์๋น์ค ์ฝ๋๋ ๋ชจ๋ ธ๋ ํฌ๋ก ๊ตฌ์ฑ๋์ด ์์ด tag๋ฅผ ํ์ฉํ ๋ฒ์ ๊ด๋ฆฌ ์๋ํ๊ฐ ์ด๋ ค์ด ์ํฉ์ ๋๋ค. ์ด๋ก ์ธํด ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ฌ์ ํ ์๋์ผ๋ก ์ํํด์ผ ํ๋ค๋ ์ ์ด ์์ฝ์ต๋๋ค.
ํน์ ์ด ๊ธ์ ์ฝ๋ ๋ ์๋ถ๋ค ์ค์ ํด๋น ๋ฌธ์ ๋ฅผ ๊ฒช์ผ์๊ฑฐ๋ ํด๊ฒฐ์ฑ ์ ์์๋ ๋ถ์ ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค.
6. ๋๋์
์ด๋ฒ ๊ฐ์ ์์ ์ ํตํด ๋ฐฐํฌ ํ๋ก์ธ์ค์ ํจ์จ์ฑ๊ณผ ์์ ์ฑ์ด ํฌ๊ฒ ํฅ์๋์์ต๋๋ค. ํนํ, ECR ์ด๋ฏธ์ง์ ์ฌํ์ฉ๊ณผ ์๋ํ๋ ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ํตํด ๋น๋ ๋ฐ ๋กค๋ฐฑ ์๊ฐ์ ๋จ์ถํ ์ ์์๋ ์ ์ด ๋ง์กฑ์ค๋ฝ์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ , ๋๊ตฌ๋ ์ฝ๊ฒ ๋กค๋ฐฑ์ ์ํํ ์ ์๋๋ก ์์คํ ์ ๊ฐ์ํํ ๊ฒ์ด ์ด๋ฒ ์์ ์ ํฐ ์ฑ๊ณผ ์ค ํ๋์์ต๋๋ค. ๋ค๋ง, ๋ชจ๋ ธ๋ ํฌ ๊ตฌ์กฐ๋ก ์ธํด ํ๊ทธ ๊ธฐ๋ฐ ๋ฒ์ ๊ด๋ฆฌ ์๋ํ๊ฐ ์ด๋ ค์ด ์ ์ ์ฌ์ ํ ์์ ๋ก ๋จ์ ์์ต๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ ์ถ๊ฐ์ ์ธ ์ฐ๊ตฌ์ ๋ ธ๋ ฅ์ด ํ์ํ๋ฉฐ, ์์ผ๋ก๋ ๊ณ์ํด์ ๊ฐ์ ์์ ์ ์งํํด์ผ ํ๋ค๊ณ ๋๊ผ์ต๋๋ค.