우리 프로젝트의 현재(3주차) CI / CD 구조는 다음과 같다.
Docker
, Docker Compose
, Github Actions
, EC2
를 이용해 CI CD를 구성했다.
여러 개의 도커 컨테이너를 정의하여 한번에 많은 컨테이너를 실행하고 관리할 수 있는 툴이다.
도커 컨테이너로 시스템을 구축하면 하나 이상의 컨테이너가 서로 통신할 때 의존 관계가 생긴다.
각 컨테이너를 따로 실행하여 관리하면 힘들다.
docker-compose.yml
파일에 여러 컨테이너에 대한 옵션을 작성하면, docker-compose up
이라는 명령어로 서비스를 시작할 수 있다.
CI 과정은 다음과 같다.
CI는 develop 브랜치를 향해 Pull Request를 작성하면 실행한다.
다음은 CI 과정에 대한 상세한 이미지다.
달라진 점은 다음과 같다.
CI 코드는 다음과 같다.
name: Java CI with Gradle And Docker Image Deploy
on:
pull_request:
branches: [ "develop" ]
permissions:
contents: read
jobs:
build:
name: Gradle 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: 'temurin'
# jwt 정보 로딩
- name: Copy Secret
env:
OCCUPY_SECRET: ${{ secrets.OCCUPY_SECRET }}
OCCUPY_SECRET_DIR: src/main/resources
OCCUPY_SECRET_DIR_FILE_NAME: application-config.properties
run: echo $OCCUPY_SECRET | base64 --decode > $OCCUPY_SECRET_DIR/$OCCUPY_SECRET_DIR_FILE_NAME
# dev 정보 로딩
- name: Copy Secret1
env:
OCCUPY_SECRET1: ${{ secrets.OCCUPY_SECRET1 }}
OCCUPY_SECRET1_DIR: src/main/resources
OCCUPY_SECRET1_DIR_FILE_NAME: application-dev.properties
run: echo $OCCUPY_SECRET1 | base64 --decode > $OCCUPY_SECRET1_DIR/$OCCUPY_SECRET1_DIR_FILE_NAME
# gradle 캐싱
- 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-
# gradle 빌드 권한 설정
- name: Grant execute permission for gradlew
run: chmod +x gradlew
# gradle 빌드
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: build
# 임시 저장
- name: Temporarily save build artifact
uses: actions/upload-artifact@v2
with:
name: build-artifact
path: build
retention-days: 1
build-docker-image:
needs: build
name: Deploy Docker Image
runs-on: ubuntu-latest
steps:
# 임시 저장 결과 로딩
- uses: actions/checkout@v2
- name: Retrieve built
uses: actions/download-artifact@v2
with:
name: build-artifact
path: build
# 도커 허브 로그인
- name: Docker Hub Sign-in
run: docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_PASSWORD }}
# 도커 이미지 빌드
- name: Building Docker Image
run: docker build --build-arg JAR_FILE=build/libs/\*.jar -t ${{ secrets.DOCKERHUB_USERNAME }}/hanbange .
# 도커 이미지 푸시
- name: Publish Docker Image
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/hanbange
CD 과정은 다음과 같다.
CD는 PR을 develop에 merge하면 실행한다.
다음은 CD 과정에 대한 상세 이미지다.
docker-compose.yml
파일은 다음과 같다.
CD 작업에서는 새로운 스프링 이미지를 받아와서 실행한다.
version: "3.9"
services:
spring:
container_name: hanbange_app
image: yanjuicy/hanbange:latest
ports:
- "80:8080"
redis_container:
container_name: redis_boot
image: redis:latest
ports:
- 6379:6379
labels:
- "name=redis"
- "mode=standalone"
restart: always
command: redis-server
CD 코드는 다음과 같다.