본문 바로가기
DevOps

Github Actions를 활용한 이미지 빌드 자동화 파이프라인 구성

by Jammini 2025. 12. 12.
728x90

목차

  1. 개요
  2. AWS EC2 인스턴스 만들기
  3. Docker 설치
  4. Github Actions 을 이용한 파이프라인
  5. Workflow 파일 작성
    1. Workflow 트리거 전략
    2. Docker 이미지 빌드 및 배포
    3. EC2 자동 배포 프로세스
  6. Secret 환경 변수 설정
  7. 배포 플로우
  8. 결론

1. 개요

AWS 프리티어 한도 안에서 서버를 구축하는 것을 목표로 한다.

즉, 가장 간단한 형태로 웹 애플리케이션을 배포할 예정이고 이를 작성해보려고 한다.

간단하게 ec2를 빌리고 Docker를 이용해 앱을 실행시키고 네트워크를 설정시켜서 외부에서 접속 가능하게 할 것이다.

2. AWS EC2 인스턴스 만들기

먼저 AWS 인스턴스를 만들어 주어야 한다.

EC2 → 인스턴스 → 인스턴스 시작을 클릭하여 이름을 설정해주고 AMI 플랫폼 이미지를 선택해준다.

나는 Amazon Linux 를 선택해주었다.

AWS 프리 티어 한도 내에서 비용을 사용하기 때문에 인스턴스는 t3.micro 를 이용하였다.

나머지 설정을 완료하고 인스턴스 시작 버튼을 클릭하여 인스턴스를 생성한다.

방금 생성한 EC2 인스턴스를 확인할 수 있고, 해당 인스턴스를 클릭하여 연결 버튼을 클릭하면 해당 Shell 에 접속 할 수 있다.

3. Docker 설치

  1. docker 설치

2. docker 설치 확인

3. docker compose 설치

4. docker 권한 수정 설치 확인

5. docker hub access 토큰 생성

4. Github Actions 을 이용한 파이프라인

내 프로젝트는 아래와 같이 5개의 모듈로 구성된 시스템이다.

  • Backend 3개 (board-server, board-admin-server, board-batch-server)
  • Frontend 2개 (board-client, board-admin-client)

각 모듈별 독립적인 배포 파이프라인을 구성할 것이며 Docker 기반 컨테이너화로 일관된 배포 환경을 구현할 예정이다.

5. Workflow 파일 작성

name: board-server-build-and-push

on:
  push:
    branches:
      - main
    paths:
      - 'board-server/**'

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and Push
        uses: docker/build-push-action@v4
        with:
          context: .
          file: ./board-server/Dockerfile
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/board-server:latest
            ${{ secrets.DOCKERHUB_USERNAME }}/board-server:${{ github.sha }}
          platforms: linux/amd64,linux/arm64

      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USERNAME }}
          key: ${{ secrets.EC2_SSH_KEY }}
          script: |
            # Pull latest image
            docker pull ${{ secrets.DOCKERHUB_USERNAME }}/board-server:latest

            # Stop and remove existing container
            docker stop board-server || true
            docker rm board-server || true

            # Run new container
            docker run -d \\
              --name board-server \\
              --network app-network \\
              -p 8080:8080 \\
              -e SPRING_PROFILES_ACTIVE=local \\
              -e JWT_SECRET="${JWT_SECRET}" \\
              --restart unless-stopped \\
              ${{ secrets.DOCKERHUB_USERNAME }}/board-server:latest

            # Clean up old images
            docker image prune -f

5-1. Workflow 트리거 전략

# Path-based Trigger 구성
on:
  push:
    branches:
      - main
    paths:
      - '{module-name}/**'
  • 변경된 모듈만 선택적 배포
  • 불필요한 빌드/배포 방지
  • 배포 시간 및 비용 절감

5-2. Docker 이미지 빌드 및 배포

# Multi-platform 빌드
platforms: linux/amd64,linux/arm64

# 듀얼 태깅 전략
tags:
  - {username}/{module}:latest  # 항상 최신 버전
  - {username}/{module}:${github.sha}  # 특정 커밋 버전

  • latest 태그로 간편한 배포
  • SHA 태그로 버전 추적 및 롤백 가능
  • ARM64 지원으로 다양한 환경 대응

5-3. EC2 자동 배포 프로세스

# SSH Action을 통한 배포 자동화

# 이미지 Pull
docker pull {username}/{module}:latest

# 기존 컨테이너 중지 및 제거
docker stop {module} || true
docker rm {module} || true

# 새 컨테이너 실행
docker run -d \\
 --name {module} \\
 --network app-network \\
 -p {port}:{port} \\
 -e SPRING_PROFILES_ACTIVE=local \\
 --restart unless-stopped

# 불필요한 이미지 정리
docker image prune -f

6. Secret 환경 변수 설정

워크플로우 실행 중에 민감한 데이터를 안전하게 처리하기 위해서는아래와 같이 Github에서 환경 변수를 설정해주어야 한다.

  1. GitHub Repository → Settings → Secrets and variables → Actions
  2. New repository secret 클릭
  3. 각 Secret 추가

7. 배포 플로우

각 작업의 워크플로우 실행결과는 Github 를 통해 확인할 수 있다.

워크플로우가 정상적으로 동작하지 않았다면 아래와 같이 빨간불이 뜨면서 에러를 확인할 수 있다.

초록불이 들어오면 모든 작업이 성공적으로 수행 되었다는 뜻이고 클라우드를 통해 접속하면 자동으로 배포되어 있는 것을 확인할 수 있다.

시나리오 CI/CD

  1. GitHub의 main 브랜치에 프로젝트가 업데이트되어 push 된다.
  2. GitHub Action 이 해당 프로젝트를 빌드한다.
  3. 빌드된 프로젝트를 Docker Image로 빌드하여 DockerHub에 Push 한다.
  4. GitHub Action 이 SSH를 통해서 AWS EC2에 접속한다.
  5. AWS 인스턴스에서 DockerHub의 새로운 이미지를 Pull 받아 이미지를 업데이트하고 컨테이너를 재실행한다.

8. 결론

위와 같이 CI/CD 프로세스를 개선하였다.

5개 모듈 독립적 배포 파이프라인 구축하였고 Docker 기반 컨테이너화로 환경 일관성을 확보했다.

특히 이 프로젝트처럼 여러 모듈로 구성된 시스템에서 각 모듈을 독립적으로 관리하면서도 통합된 배포 파이프라인을 경험할 수 있어서 흥미로웠다.

완벽한 시스템은 아니지만, 지속적으로 개선해 나가면 더 나은 개발 환경을 만들고자 한다.

반응형