안녕!
우아한테크코스 5기 [스탬프크러쉬]팀 깃짱이라고 합니다.
사장모드: stampcrush.site/admin
고객모드: stampcrush.site
💋 스탬프크러쉬의 무중단 배포 자동화 방식
✔️ 기존: Jenkins 사용한 CI/CD
스탬프크러쉬는 사실 이전의 포스팅에서 확인할 수 있듯, Jenkins를 사용해 무중단 배포 파이프라인을 구축했습니다.
다만, 이번에 Github Actions를 사용한 방식으로 변경하기로 다짐한 데는 아래와 같은 이유가 있었습니다.
✔️ Github Actions 도입 배경
현재 젠킨스가 실행되고 있는 서버는 우아한테크코스의 AWS 계정을 이용하고 있는 서버입니다. 그런데, 한 달 정도 이후에 우테코를 수료하게 되는데 그때부터는 서버를 더이상 사용할 수 없다는 청천벽력같은 통보를 받게 되었습니다. 따라서, 우테코 AWS에 있는 모든 EC2와 인프라들을 개인 계정으로 옮겨야 했습니다.
젠킨스를 사용한 방식을 그대로 유지하는 경우에, 서버 비용을 계속해서 내야 합니다. 하지만, 깃허브 액션을 사용하는 경우에 깃허브에서 인프라를 위한 서버를 구축했기 때문에 스탬프크러쉬의 알 바가 아닙니다.
✔️ Github Actions 사용한 CI/CD 구조
암튼 결론적으로 깃허브 액션을 사용한다면 이런 구조가 될 것입니다.
실제로 ‘무중단’에 대한 부분은 배포할 서버의 배포 스크립트 안에 구현되어 있습니다.
이렇게 바꾸게 된 김에, 어떻게 구축했는지 하나하나 설정해 나갑시다!
그 전에, 제가 글을 여러 번 쪼개서 작성한 것을 합치다 보니깐 이 뒤로는 말을 깝니다. 균일하지 못한 점 양해 바랍니당 헤헤
💋 Github Actions workflow 용어
조금 헷갈리는 workflow 내 용어 먼저 정리하고 갑시다.
✔️ Events
- workflow가 돌아가도록 하는
trigger
역할 - 예. create pull request, open issue, push a commit to a repository, 규칙적으로 REST API를 통해 POST 요청을 보내는 것
✔️ Jobs
- workflow 안의
steps들의 모음
- 각 step들은 서로 연관되어, 순차적으로 실행됨.
- 예. 테스트가 모두 통과하는지 확인 후에 애플리케이션을 빌드한다면, 이 두 가지 행동은 step으로 Job을 이룰 수 있음.
✔️ Actions
- GitHub Actions를 위해 커스텀된 애플리케이션
- 복합하지만, 자주 사용되는 일들을 수행함.
- 예. GitHub 레포지토리로부터 코드를 pull받고, 빌드하기 위한 환경을 구성하고, cloud 환경에서의 인증 과정을 설정하는 것
✔️ Runners
- trigger를 감지했을 때, workflow를 실행하는 서버
- 깃허브에서 Ubuntu Linux, Microsoft Windows, macOS를 위한 runner를 제공함.
💋 Github Actions workflow 생성
깃허브 액션은 YAML를 사용해서 workflow를 구성한다. 내 레포지토리의 .github/workflows
디렉토리 안에 yml 파일을 생성해서 넣어 놓으면 자동으로 깃허브 액션이 안에 내용을 가지고 적절한 시기에 실행함.
✔️ 스탬프크러쉬의 workflow 파일
아래는 스탬프크러쉬에서 설정한 workflow 파일이다. 복사해서 팀 프로젝트에 필요한 부분만 조금 수정하면 될 것 같다.
가장 중요한 것!
모든 아이디, 비밀번호, 토큰은 깃허브에 직접 올리면 바아로 로봇이 쓱싹해가서 우리 프로젝트 망한다. 반드시 Secrets에 저장해서 별도로 관리할 것! (설정법은 아래에 있음)
우리 파이프라인은 크게 2개의 Job으로 이루어져 있다.
- 코드 받아서 docker image로 빌드하고, docker hub에 push한다.
- 직접 빌드한 이미지를 보내는 방식이 아니라, 깃허브 액션에서 push하고 배포 서버에서 pull받는 방식이다.
- 외부 서버(배포할 서버)에 있는 github actions self-hosted runners를 돌려서, 외부 서버에 들어있는 배포 스크립트를 실행한다.
스크립트가 잘 이해가 되지 않을 수 있어서, 스크립트 아래의 접는 글을 찾아가보면 주석으로 친절하게 설명을 해 놓았다.
./github/workflows/backend-dev-cd.yml
name: ✨ StampCrush backend DEV CD ✨
env:
PROFILE: dev
DOCKER_HUB_REPOSITORY: stampcrush/stampcrush-dev
on:
workflow_dispatch:
push:
branches:
- develop
paths:
- "backend/**"
- ".github/workflows/backend-dev.cd.yml"
jobs:
backend-docker-build-and-push:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend
steps:
- name: ✨ Checkout repository
uses: actions/checkout@v3
with:
submodules: true
token: ${{ secrets.ACTION_TOKEN }}
- name: ✨ JDK 17 설정
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: ✨ Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: ✨ Gradlew 권한 설정
run: chmod +x ./gradlew
- name: ✨ Jar 파일 빌드
run: ./gradlew bootJar
- name: ✨ DockerHub에 로그인
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: ✨ Docker Image 빌드 후 DockerHub에 Push
uses: docker/build-push-action@v4
with:
context: ./backend
file: ./backend/Dockerfile-dev
push: true
platforms: linux/arm64
tags: ${{ env.DOCKER_HUB_REPOSITORY }}:latest
backend-docker-pull-and-run:
runs-on: [self-hosted, dev]
if: ${{ needs.backend-docker-build-and-push.result == 'success' }}
needs: [ backend-docker-build-and-push ]
steps:
- name: ✨ 배포 스크립트 실행
run: |
sh /home/ubuntu/deploy.sh
아래 접는 글에는 위의 workflow에 대해 주석을 달아 놓았다. 근데 주석 포함하는 경우에는 workflow에서 에러가 나니깐 위의 것을 수정하는 것 추천!
name: ✨ StampCrush backend DEV CD ✨ // 그냥 이름임.
env:
PROFILE: dev
DOCKER_HUB_REPOSITORY: stampcrush/stampcrush-dev
on:
workflow_dispatch:
push:
branches: // 이 브랜치에 push가 되는 경우, trigger가 되어 이 깃허브 액션 파이프라인이 실행됨.
- develop
paths: // develop 브랜치 안의 path를 좀 더 세밀하게 설정할 수 있음.
- "backend/**"
- ".github/workflows/backend-dev.cd.yml"
jobs:
backend-docker-build-and-push:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend
steps: // 서브모듈(설정파일 관리)을 포함해서 깃허브에서 코드를 가져온다. uses 이하는 actions에서 제공하는 메서드.
- name: ✨ Checkout repository
uses: actions/checkout@v3
with:
submodules: true
token: ${{ secrets.ACTION_TOKEN }}
- name: ✨ JDK 17 설정 // 걍 환경 설정
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: ✨ Gradle Caching // 좀더 빨리 하려고 캐시도 하나봄.
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: ✨ Gradlew 권한 설정
run: chmod +x ./gradlew
- name: ✨ Jar 파일 빌드
run: ./gradlew bootJar
- name: ✨ DockerHub에 로그인
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: ✨ Docker Image 빌드 후 DockerHub에 Push
uses: docker/build-push-action@v4
with:
context: ./backend
file: ./backend/Dockerfile-dev
push: true
platforms: linux/arm64
tags: ${{ env.DOCKER_HUB_REPOSITORY }}:latest
backend-docker-pull-and-run:
// 여러 서버에 runners를 설치해 놓았을 지라도, 그중에서 별도의 labels로 self-hosted, dev를 설정해 놓은 runner만 작동한다.
runs-on: [self-hosted, dev]
// 앞에 job 잘 실행했을 때만 배포 스크립트를 실행하겠다는 뜻
if: ${{ needs.backend-docker-build-and-push.result == 'success' }}
needs: [ backend-docker-build-and-push ]
steps:
- name: ✨ 배포 스크립트 실행
run: |
sh /home/ubuntu/deploy.sh
✔️ Secrets 설정
위 파일에서 secrets
로 설정된 내용들에 대해서는 깃허브에 올릴 수 없는 비밀이기 때문에 별도로 설정해줘야 함.
Settings > Secrets and variables > Actions
에서 New repository secret
을 선택하고, workflow 파일에서 작성한 이름과 동일하게 Secret을 만든다.
이 상태로 실행하면 당연히 에러가 난다. 배포 서버에는 아직 설정이 되어있지 않기 때문.
다음 포스팅에서는 배포 서버에 온갖 세팅을 해서 무중단 배포를 완성해봅시다!!!
💋 참고자료
도움이 되었다면, 공감/댓글을 달아주면 깃짱에게 큰 힘이 됩니다!🌟
비밀댓글과 메일을 통해 오는 개인적인 질문은 받지 않고 있습니다. 꼭 공개댓글로 남겨주세요!
'PROJECT > Stamp Crush' 카테고리의 다른 글
[우테코] JWT 방식에서 로그아웃, Refresh Token 만들기(2): 구현을 해보자! (0) | 2023.11.08 |
---|---|
[우테코] 무중단 배포 자동화(2): 배포서버에 Github Actions self-hosted runners, Nginx, Docker 설정 (2) | 2023.10.28 |
[우테코] 스탬프크러쉬의 HikariCP 커넥션 풀 사이즈 설정 (0) | 2023.10.17 |
[모집공고] 스탬프크러쉬 기획/영업/마케팅 팀원 모집 (0) | 2023.10.16 |
[우테코] 스탬프크러쉬의 실제 사용자(카페 사장)와 함께한 일주일 (5) | 2023.10.12 |