공식홈페이지 소개에 따르면, GitHub Actions는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트)플랫폼이라고 한다.
즉, Git Repository에 pull request 또는 issue 생성 등 특정한 event가 발생했을 때, 자동으로 테스트를 수행하거나 병합된 코드를 자동으로 배포하는 워크플로를 만들 수 있다.
만약 gradle, docker, ec2를 쓴다면
./gradlew clean build
docker build 이미지
docker push 도커허브
aws 접속
docker stop 컨테이너
docker pull 이미지
docker run 컨테이너
어떤 도구를 사용하든 코드를 통합하고 배포하는 노력이 필요하다.
그리고 수동으로 관리하는 것은 너무 귀찮다.
Jenkins, ArgoCD 등 다양한 CI/CD 자동화 도구 들이 있지만
쉽고 빠르게 해커톤 프로젝트에 CI/CD를 적용하기 위해서, GitHub Actions를 사용하기로 결정했다.


name: CI-CD
on:
push:
branches: [ "main" ]
env:
IMAGE_NAME: wtw-spring
CONTAINER_NAME: wtw-spring-container
jobs:
build-docker-image-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# 1. Java 17 세팅
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
# 2. Spring Boot 환경변수 할당
- name: Retrieve application properties
env:
APPLICATION_PROPERTIES: ${{ secrets.APPLICATION_PROPERTIES }} # 시크릿에 등록시킨 application.yml
run: |
touch ./src/main/resources/application.yml
echo "${APPLICATION_PROPERTIES}" > ./src/main/resources/application.yml
# 3. Spring Boot 애플리케이션 빌드
- name: Build with Gradle
run: ./gradlew clean build -x test
# 4. DockerHub 로그인
- name: DockerHub login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
# 5. Docker 이미지 빌드
- name: Build Docker image
run: docker build -t chancehee/${{ env.IMAGE_NAME }}:latest .
# 6. DockerHub 이미지 푸시
- name: Push Docker image to DockerHub
run: docker push chancehee/${{ env.IMAGE_NAME }}:latest
pull-and-docker-deploy:
runs-on: self-hosted
needs: build-docker-image-and-push
steps:
- name: Pull Docker image from DockerHub
run: sudo docker pull chancehee/${{ env.IMAGE_NAME }}:latest
# 7. 기존 컨테이너 중지 및 삭제
- name: Stop and remove existing container
run: |
if [ "$(sudo docker ps -q -f name=${{ env.CONTAINER_NAME }})" ]; then
sudo docker stop ${{ env.CONTAINER_NAME }}
sudo docker rm ${{ env.CONTAINER_NAME }}
fi
# 8. 새로운 컨테이너 실행
- name: Run new Docker container
run: |
sudo docker run -d --name ${{ env.CONTAINER_NAME }} --network my-network -p 8080:8080 chancehee/${{ env.IMAGE_NAME }}:latest
# 9. 오래된 도커 이미지 제거
- name: Remove old Docker images
run: |
sudo docker image prune -f --filter "until=1h"
위 코드를 간단하게 해석하면 아래와 같다.
main 브랜치에 push event가 발생하면 workflow가 실행된다.
(on은 if문과 같은 조건문이라고 생각하면 된다.)
Job은 크게 2가지로 구성했다.
1. Docker Image Build & Docker Image Push
2. Docker Image Pull & Run Docker Container on EC2
GitHub Actions를 사용할 때, 드는 의문이 있었다.
CD 작업은 어떻게 해야 하지?
찾아본 방법은 여러 가지가 있었다.
대표적으로 3가지 방법이 일반적이었다.
1. EC2 인스턴스 내에서 CD 작업을 하는 스크립트 작성 후 특정 시간 혹은 WebHooks 기반 실행
2. Jenkins와 같은 CD 도구 사용
3. GitHub Actions Runner를 이용한 인스턴스 접속 후 명령어 실행
필자는 설정이 가장 쉽고 빠르게 적용할 수 있는 3번 방법을 선택했다.
Runner는 자동화된 작업을 처리하는 환경을 의미한다.
위에서 main 브랜치 event를 감지하고 docker image 파일을 만들고 EC2 인스턴스에서 명령어를 실행하는 것 모두 Runner 환경 위에서 동작한 것이다.
Runner도 크게 2가지 종류가 있었다.
결론적으로 private repo를 사용하고 비용 절감을 원하는 나는 2번 방식을 사용했다.
Self-Hosted Runner 사용하려면 아래 순서로 작업을 수행하면 된다.
정상 상태라면 아래와 같이 idle 상태를 확인 할 수 있다.

Jenkins와 같은 CI/CD 도구 너무 좋다.
근데 설정 귀찮다.
권장 RAM도 4GB임..
GitHub Actions 설정 쉽다.
CI/CD Jar 파일만 EC2에 던져도 되고, EC2에서 Git Pull 해도 되고.. (다양한 방법 존재)
근데 Docker가 제일 편한 것 같다. (DB 등 여러 컨테이너랑 같이 쓸 때)