백엔드 팀원과 프로젝트에 적용할 기술 스팩을 상의하면서 CI/CD를 사용하기로 했다.
팀원 분은 이미 CI/CD를 사용해본 경험이 있으셔서 팀원 분이 사용해보셨던 CI/CD 코드를 적용하기로 했다.
나는 CI/CD를 사용한 경험이 없기 때문에, 팀원이 작성한 코드를 분석하기로 했다.
CI/CD란
GitHub Actions 워크플로 설정
GitHub Actions은 GitHub의 내장 CI/CD 도구로, 코드 변경 사항에 반응하여 자동으로 빌드, 테스트, 배포를 수행할 수 있다.
name: CI/CD using github actions & docker
# event trigger
on:
push :
branches : ["master","dev"]
permissions:
contents: read
이 설정은 코드 저장소에서 발생하는 특정 이벤트(push 이벤트)가 발생할 때, 특정 브랜치(master 또는 dev)에 대해 지속적 통합 및 배포 작업을 자동으로 실행하도록 GitHub Actions를 구성한다.
- on
: GitHub Actions 워크플로를 언제 실행할지를 설정하는 부분이다. - push
: 코드를 푸시할 때 실행된다. - branches: ["master", "dev"]
: 코드가 master 또는 dev 브랜치로 푸시될 때 이 워크플로가 실행되도록 설정한다. - permissions
: GitHub Actions가 코드 저장소의 권한을 어떻게 처리할지를 정의한다. - contents: read
: 코드 저장소의 내용을 읽을 수 있도록 설정한다. GitHub Actions가 저장소에서 필요한 파일을 읽고 작업을 수행할 수 있도록 한다.
JDK 설정
GitHub Actions에서 Java 프로젝트를 빌드하거나 테스트할 때 필요한 초기 설정 단계이다.
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- - uses: actions/checkout@v4
: 현재 레포지토리의 코드를 가져오는 역할을 한다. - - name: Set up JDK 17
: GitHub Actions에서 사용할 JDK 17을 설정하는 단계이다. name 필드는 이 단계의 이름을 지정하는 것이고, JDK 설정을 시작한다는 의미이다. - uses: actions/setup-java@v4
: JDK 설정을 위해 사용되는 액션이다. 특정 버전의 Java를 설정하고 환경을 준비하는 역할을 한다. - with
: 이 키워드 아래에는 설정 옵션이 나열된다. - java-version: '17'
: Java 버전을 17로 설정한다. - distribution: 'temurin'
: JDK를 제공하는 배포판을 지정한다. temurin은 오픈 소스 기반의 JDK 구현체로, 최신 LTS 버전과 장기 지원을 받을 수 있는 버전을 제공한다.
Gradle 빌드
GitHub Actions 에서 Gradle을 이용한 Java 프로젝트의 빌드를 자동화하는 방법을 보여준다.
Gradle 빌드는 코드 컴파일, 의존성 관리, 리소스 복사 등을 수행해 프로젝트를 실행 가능한 형태로 준배하는 역할을 한다.
1. Gradle Caching 설정
- name: Gradle Caching
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
이 부분은 Gradle 캐싱을 설정해 빌드 시간을 단축하는 목적으로 사용된다.
- uses: actions/cache@v4
: GitHub에서 제공하는 액션으로, 이전에 캐시된 파일을 사용하여 빌드 속도를 향상시킨다. - path
: 캐싱할 경로를 지정한다. ~/.gradle/caches 와 ~/.gradle/wrapper 는 Gradle 라이브러리와 Wrapper 스크립트의 캐시를 포함한다. - key
: 캐시를 식별하는 키이다. ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} 는 Gradle 설정 파일의 내용에 따라 동적으로 생성된다. - restore-keys
: 캐시를 복원할 때 사용할 키 목록이다.
2. Gradle 빌드 실행
- name: Build with Gradle
run: |
chmod +x ./gradlew
./gradlew build -x test
이 부분은 Gradle을 사용해 프로젝트를 빌드하는 단계이다.
- chmod +x ./gradlew
: Gradle Warpper 스크립트에 실행 권한을 부여하는 명령어이다. - ./gradlew build -x test
: Gradle Wrapper를 사용해 프로젝트를 빌드하는 명령어이다. -x test 옵션은 테스트를 실행하지 않도록 설정한다.
Docker 빌드 및 프로덕션 환경 배포
1. Docker 빌드 & Push to Prod
- name: Docker build & push to prod
if: contains(github.ref, 'dev')
run: |
docker login -u {사용자명} -p {비밀번호}
docker build -t {사용자명}/{프로젝트명} .
docker push {사용자명}/{프로젝트명}
- docker login -u {사용자명} -p {비밀번호}
: Docker Hub에 로그인한다. {사용자명}은 Docker Hub 계정명이며, {비밀번호}는 Docker Hub 계정의 비밀번호이다. - docker build -t {사용자명}/{프로젝트명} .
: 현재 디렉토리의 Dockerfile을 사용하여 Docker 이미지를 빌드한다. t 옵션을 통해 이미지의 태그를 {사용자명}/{프로젝트명}로 지정한다. - docker push {사용자명}/{프로젝트명}
: 빌드한 Docker 이미지를 Docker Hub의 {사용자명}/{프로젝트명}레포지토리에 푸시한다.
2. Deply to Prod
이 설정은 GitHub Actions를 통해 지속적 통합 및 배포를 자동화하여 개발 효율성을 높이고, 프로덕션 환경에서 신속하게 변경 사항을 배포할 수 있도록 한다.
- name: Deploy to prod
uses: appleboy/ssh-action@master
id: deploy-prod
if: contains(github.ref, 'dev')
with:
host: {서버의 IP 주소}
username: {사용자 이름}
password: {비밀번호}
port: 2222
key: ${{ secrets.PRIVATE_KEY }}
envs: GITHUB_SHA
script: |
sudo docker ps
sudo docker stop springboot
sudo docker rm -f springboot
sudo docker pull {사용자명}/{프로젝트명}
sudo docker run -d -p 8080:8080 --name springboot --network=net {사용자명}/{프로젝트명}
sudo docker image prune -f
GitHub Actions의 ssh-action 을 사용해서 원격 서버에 접속하고 배포하는 단계이다.
- if: contains(github.ref, 'dev')
: 이 조건은 dev 브랜치로 푸시될 경우에만 이 액션을 실행하도록 설정한다. - uses: appleboy/ssh-action@master
: SSH를 통해 원격 서버에 접속하여 배포하는 GitHub Action을 사용한다. - host: {서버의 IP 주소}, username: {사용자 이름}, password: {비밀번호}, port: 2222
: 배포할 서버의 IP 주소, SSH 접속할 때 사용할 사용자명과 비밀번호, SSH 연결에 사용할 포트를 설정한다. - key: ${{ secrets.PRIVATE_KEY }}
: GitHub Secrets에 등록된 개인 키를 사용하여 SSH 접속을 인증한다. - envs
: 환경 변수로 GitHub Actions에서 제공하는 ${{ GITHUB_SHA }}를 사용하여 현재 커밋의 SHA 값을 전달할 수 있다. - script
: 원격 서버에서 실행할 명령어들을 포함한다. - sudo docker ps, sudo docker stop springboot, sudo docker rm -f springboot
: 현재 실행 중인 Docker 컨테이너(springboot)를 확인하고 중지한 뒤 삭제한다. - sudo docker pull {사용자명}/{프로젝트명}
: Docker Hub에서 지정한 사용자명과 프로젝트명으로 된 Docker 이미지를 다시 받아옵니다. - sudo docker run -d -p 8080:8080 --name springboot --network=net {사용자명}/{프로젝트명}
: 업데이트된 Docker 이미지를 포트 8080에서 실행하고, springboot라는 이름으로 컨테이너를 생성한다.
네트워크는 net에 연결된다. - sudo docker image prune -f
: 사용하지 않는 Docker 이미지를 강제로 삭제한다.
정리
이 설정은 GitHub Actions를 사용하여 CI/CD 프로세스를 자동화한다.
코드 저장소에 푸시 이벤트가 발생하면, master 또는 dev 브랜치에 대해 작업이 순서대로 수행된다.
- JDK 설정: Java 프로젝트를 빌드하기 위해 JDK 17을 설치하고 구성한다.
- Gradle 빌드: Gradle을 사용하여 Java 프로젝트를 컴파일하고 패키지한다.
- Docker 이미지 빌드 및 배포: Docker를 사용하여 애플리케이션을 컨테이너화하고, 개발 중 또는 프로덕션 환경에 배포하기 위해 Docker Hub에 이미지를 푸시한다.
- 프로덕션 환경 배포: 개발된 Docker 이미지를 프로덕션 서버에 자동으로 배포하고, 실행 중인 컨테이너를 업데이트한다.
'Projects > 청하-청년을 위한 커뮤니티 서비스' 카테고리의 다른 글
[청하] 6. 게시글 등록 기능 - @ModelAttribute를 이용한 form-data 처리 개선 (0) | 2024.10.07 |
---|---|
[청하] 5. 게시글 등록 기능 - @RequestPart를 이용한 JSON 데이터와 파일 데이터 분리 (0) | 2024.10.07 |
[청하] 4. 게시글 등록 기능 구현 (feat. NCP Object Storage 파일 업로드) (1) | 2024.10.06 |
[청하] 2. 데이터베이스 설계 (0) | 2024.06.21 |
[청하] 1. 프로젝트 기술 스택 정의 (0) | 2024.06.21 |
댓글