밍쯔와 안작고 안귀여운 에러들🖤
[INFRA/AWS] Docker, Git actions로 SpringBoot CI/CD 구축 ! 본문
미루고 미루다 드디어 쓰는 CI/CD 파이프라인 구축 !
CI/CD는 도대체 무엇인고~ 어떻게 하는 것이지~ 찬찬히 알아봅시다 :-)
CI/CD란?
CI ( Continuous Integration) : 지속적 통합
소프트웨어의 새로운 코드들이 자동으로 빌드 및 테스트 되어 레포지토리에 통합되는 것을 의미합니다.
point !
- 최대한 작은 단위로 개발하며 자주 merge 하기
- 빌드, 테스트, 병합하는 과정을 주기적으로 자동화 시키기
이를 통해 병합 시 충돌 예방과 코드의 결함이나 문제점을 빠르게 발견할 수 있습니다.
또한, 작은 단위로 merge 할 경우 문제의 발생 범위가 작기 때문에 빠르게 해결할 수 있고
결과적으로 코드의 품질이 올라갑니다 !
CD ( Continuous Delivery/Deployment) : 지속적 제공/배포
CI를 통해서 빌드, 테스트가 완료되어 배포될 준비가 끝난 소프트웨어를 수동(delivery) or 자동(deployment)으로 배포하는 것
즉, CI/CD에서는 변경 사항을 자주 커밋하고, 이러한 업데이트를 엄격하게 테스트하고,
피드백을 즉각적으로 처리하고, 릴리즈 준비가 완료되면 배포됩니다.
이렇게 자동화 할 경우 배포 과정이 빨라질 뿐만 아니라 각 단계의 일관성 및 안정성을 확보할 수 있습니다.
[ 참고 ]
GitHub Actions
깃헙에서 제공하는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼입니다.
리포지토리에서 다른 이벤트가 발생할 때 워크플로를 실행할 수 있도록 하고
이때, Linux, Windows, macOS 가상 머신을 제공하거나, 사용자 고유의 데이터 센터 또는 클라우드 인프라에서 자체 호스트형 실행기를 호스트할 수 있습니다.
구성 요소
- Workflow
자동화된 전체 프로세스. 하나 이상의 Job으로 구성되고, Event에 의해 예약되거나 트리거될 수 있는 자동화된 절차를 말한다.
Workflow 파일은 YAML으로 작성되고, Github Repository의 .github/workflows 폴더 아래에 저장된다. Github에게 YAML 파일로 정의한 자동화 동작을 전달하면, Github Actions는 해당 파일을 기반으로 그대로 실행시킨다.
- Event
Workflow를 트리거(실행)하는 특정 활동이나 규칙. 예를 들어, 누군가가 커밋을 리포지토리에 푸시하거나 풀 요청이 생성 될 때 GitHub에서 활동이 시작될 수 있다.
- Job
Job은 여러 Step으로 구성되고, 단일 가상 환경에서 실행된다. 다른 Job에 의존 관계를 가질 수도 있고, 독립적으로 병렬로 실행될 수도 있다.
- Step
Job 안에서 순차적으로 실행되는 프로세스 단위. step에서 명령을 내리거나, action을 실행할 수 있다.
- Action
job을 구성하기 위한 step들의 조합으로 구성된 독립적인 명령. workflow의 가장 작은 빌드 단위이다. workflow에서 action을 사용하기 위해서는 action이 step을 포함해야 한다. action을 구성하기 위해서 레포지토리와 상호작용하는 커스텀 코드를 만들 수도 있다. 사용자가 직접 커스터마이징하거나, 마켓플레이스에 있는 action을 가져다 사용할 수도 있다.
- Runner
Gitbub Action Runner 어플리케이션이 설치된 머신으로, Workflow가 실행될 인스턴스
🐳 CI/CD 구축하기
** 저는 이미 프로젝트를 수동으로 docker에 배포한 상황입니다 !
1. Github Actions 환경변수 설정
구축을 진행할 리포지토리에서 다음과 같이 들어가 주고,
자신의 도커허브의 username과 password를 아래와 같이 등록합니다.
2. Actions의 gradle.yml 파일 생성
기존의 yml 파일을 나의 필요에 맞게 수정하면 됩니다.
저의 경우 아래와 같이 docker 이미지를 생성한걸 ec2에 올려서 배포해야하기 때문에
기존에 수동으로 하던 작업들을 각각의 step으로 만들어서 아래와 같이 작성했습니다.
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
# CI : Docker Image Build
build-docker-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 1. Java 17 세팅
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# 2. Spring Boot 애플리케이션 빌드
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle Wrapper
run: ./gradlew build
# 3. Docker 이미지 빌드
- name: docker image build
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/이미지-이름 .
# 4. DockerHub 로그인
- name: docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# 5. Docker Hub 이미지 푸시
- name: docker Hub push
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/이미지-이름
# CD : 푸시한 이미지를 EC2에서 컨테이너화 작업
run-docker-image-on-ec2:
needs: build-docker-image
runs-on: self-hosted
steps:
# 6. EC2에서 도커 이미지 pull 하기
- name: docker pull
run : sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/이미지-이름
# 7. 기존에 실행 중이던 컨테이너 중단
- name: docker stop container
run: |
if [ $(sudo docker ps -a -q -f name=이미지-이름) ]; then
sudo docker stop 이미지-이름
fi
# 8. 새로운 컨테이너 실행
- name: docker run new container
run: sudo docker run -d -p 8080:8080 --name 이미지-이름 ${{ secrets.DOCKERHUB_USERNAME }}/이미지-이름
# 9. 이전 도커 이미지 삭제
- name: delete old docker image
run: sudo docker system prune -f
3. self-hosted 설정
yml 파일에 이미 CI, CD 의 과정을 모두 담았습니다.
이제 제대로 CD 과정을 수행할 수 있도록 구축해줘야 합니다.
self-hosted runner의 경우, 사용자가 원하는 서버에서 github actions application을 실행할 수 있습니다 !
아래 명령어를 EC2에서 실행시켜줍니다.
이때, 맨 아래 라인은 실행하지 않습니다!!
쭉 실행시키고 성공적으로 연결이 된 경우 아래와 같이 뜬다!
이후, 아래의 명령어를 차례로 실행시켜서 서비스를 설치 및 실행시킨다.
sudo ./svc.sh install
sudo ./svc.sh start
4. 실행 결과 테스트
커밋을 남겨보면서 테스트를 진행해봅니다.
여러 테스트를 거쳐서 완료된걸 확인할 수 있습니다 !
확실히 수동으로 모든 과정을 하는 것 보다 시간과 안정성 측면에서 모두 좋은 것 같습니다:)
yml 파일을 작성할때 제공된 코드를 그대로 쓰기보다는
github actions의 구성요소를 한번 보시고 직접 작성해 나가면
훨씬 그 프로세스를 이해하기 쉬울 것 같다고 느껴졌습니다 !
모두들 즐거운 개발하세요:-)
'Develop > AWS | Cloud' 카테고리의 다른 글
[AWS] AWS RDS 만들기 (2) | 2024.11.19 |
---|---|
[AWS] RDS - now() 현재시간 수정하기 (0) | 2024.11.19 |
[MAC/AWS] EC2의 DB를 로컬의 MySQL Workbench에 연결하기 (4) | 2024.11.11 |
[AWS] 탄력적 IP(EIP) 할당하기 (0) | 2024.11.07 |
[MAC/AWS] EC2 인스턴스 MySQL 구축 및 DB 생성, 권한 설정까지 ! (0) | 2024.11.06 |