CICD
GitHub Action & Docker를 사용해서 배포
웅둘
2023. 9. 8. 23:15
프로젝트를 진행하면서 소스 코드의 변경사항이 발생하면 새롭게 배포를 해야합니다.
이때는 수동으로 배포를 진행해서 매번 빌드 후 jar 파일을 서버에 올려서 배포를 했었습니다.
매번 수동으로 배포할 수 없었기 때문에 자동으로 빌드 및 배포되도록 하기 위해서 CI/CD를 적용하기로 했다.
이러한 CI/CD를 위한 툴은 대표적으로 Jenkins가 있지만 Jenkins는 회사에서 사용중이였고 다른 CI/CD를 사용해보고 싶었고 간단하게 하기 위해서 Github Action을 선택하게 되었다.
간단하게 Github Action에 대해 알아보고 적용해보자
GitHub Action 이란?
- GitHub에서 제공하는 CI(지속 통합), CD(지속 배포) 플랫폼이다.
Workflow
- 작업의 흐름으로 특정한 목적을 위한 실행 트리거, 환경, 기능들을 모두 포함하는 파일입니다.
- 레퍼지토리내의 github/workflows 폴더 아래 YAML 파일로 작성
Job
- Job은 독립된 환경에서 돌아가는 하나의 처리 단위
- 모든 작업은 기본적으로 동시에 실행되며 필요 시 작업 간에 의존 관계를 설정하여 실행순서를 제어할 수 있다.
- 필수적으로 정의해야 할 속성 runs-on → Job을 실행할 환경(윈도우, 리눅스) 정의
Steps
- Job 내에서 실행되는 개별적인 작업 단위
- 스크립트, 명령어 또는 외부 액션을 실행하여 특정 작업을 수행합니다.
Actions
- uses로 action 사용
- 재사용 가능한 코드 단위, 특정 작업을 수행하는 명령어 또는 스크립트
- GitHub Marketplace에서 다양한 액션을 제공해줍니다.
프로젝트에서 사용
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew bootJar
## 웹 이미지 빌드 및 도커허브에 push
- name: web docker build and push
run: |
sudo docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }}
sudo docker build -f Dockerfile -t ${{ secrets.DOCKERHUB_USERNAME }}/omo-be .
sudo docker push ${{ secrets.DOCKERHUB_USERNAME }}/omo-be
- name: Deploy Front to prod
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.AWS_HOST }}
username: ${{ secrets.AWS_USERNAME }}
password: ${{ secrets.AWS_PASSWORD }}
port: 22
script: |
if docker ps -a --format '{{.ID}}' | grep -q .; then
sudo docker rm -f $(docker ps -qa)
else
echo "No Docker containers to remove."
fi
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/omo-be
sudo docker run --name omo-be -d -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/omo-be
sudo docker run --name redis-server -d -p 6379:6379 redis
docker image prune -f
on:
push:
branches: [ "main" ]
- main bracnh에 push할 때 Workflow 작동
permissions:
contents: read
- Workflow 실행 환경에서 권한
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
- ubuntu 환경 사용
- action/checkout@v3 : Github 저장소의 코드를 워크플로우 실행 환경으로 체크아웃하여 가져옵니다.
- actions/setup-java@v3 : Workflow 실행 환경에 JDK 17 설정
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew bootJar
- gradlew 실행 권한을 부여하고 프로젝트 빌드
- name: web docker build and push
run: |
sudo docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_TOKEN }}
sudo docker build -f Dockerfile -t ${{ secrets.DOCKERHUB_USERNAME }}/omo-be .
sudo docker push ${{ secrets.DOCKERHUB_USERNAME }}/omo-be
- 웹 이미지 빌드 및 도커허브에 푸시
- 도커 허브에 로그인, Dockerfile을 사용하여 이미지 빌드 → 도커 허브 push
- 이때 도커허브에 레퍼지토리를 만들어야 한다. 현재 예시에는 omo-be로 되어있다.
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.AWS_HOST }}
username: ${{ secrets.AWS_USERNAME }}
password: ${{ secrets.AWS_PASSWORD }}
port: 22
script: |
if docker ps -a --format '{{.ID}}' | grep -q .; then
sudo docker rm -f $(docker ps -qa)
else
echo "No Docker containers to remove."
fi
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/omo-be
sudo docker run --name omo-be -d -p 8080:8080 ${{ secrets.DOCKERHUB_USERNAME }}/omo-be
sudo docker run --name redis-server -d -p 6379:6379 redis
docker image prune -f
- appleboy/ssh-action@master : AWS 호스트로 SSH 연결 수립
- host : ssh 접속을 위한 ip
- username : ssh 접속을 위한 username
- passwrod : Private Key
script
- 실행 중인 도커 컨테이너 모두 종료
- 도커 허브에서 이미지를 가져오고 컨테이너 실행
- Redis 서버 컨테이너 실행
- 불필요한 이미지 정리
Github Action으로 배포가 성공했지만 한번 배포하는데 3분이 넘게 걸린다...
도커 허브에 이미지를 만들고 올리는 작업이 오래걸리는 것 같아 도커를 사용하지 않는 방법으로 Github Action을 진행하기로 했다. -> 다음 블로그 글 작성