GitHub Actions 사용하여 CI/CD 구현 방법

GitHub Actions를 사용하여 NestJS 프로젝트를 빌드 및 배포하는 과정을 작성하였습니다.

프로젝트 기술스택별로 패키지 관리 모듈, 의존성 및 빌드 결과물 위치가 달라서 변경이 필요합니다.


GitHub Actions 사용하여 CI 구축 방법

GitHub 리포지토리에서 빌드, 테스트, 배포 등 CI/CD 파이프라인을 자동화할 수 있는 플랫폼입니다.
CI/CD 작업을 수행할 Job과 Step을 정의한 워크플로는 .github/workflows 경로에 .yml 파일로 작성합니다.
push/pull_request 이벤트, 스케줄, 외부 이벤트 등으로 워크플로를 자동 실행할 수 있습니다.
워크플로 작업은 GitHub에서 제공하는 가상 머신 또는 직접 등록한 Runner에서 실행됩니다.

GitHub Actions 실행 테스트

name: GitHub Actions Demo # GitHub Actions 워크플로명
run-name: $ is testing out GitHub Actions # Actions 실행 기록에 표시되는 이름 실행 이름
on: [push] # GitHub 저장소에 push 이벤트 발생 시 워크플로 실행
jobs:
  Explore-GitHub-Actions: # Job ID
    runs-on: ubuntu-latest # GitHub에서 제공하는 최신 우분투 서버 = 가상 머신 Runner에서 작업 실행
    steps:
      - run: echo "🎉 The job was automatically triggered by a $ event." # echo 명령어를 통해 문자열 출력
      - run: echo "🐧 This job is now running on a $ server hosted by GitHub!"
      - run: echo "🔎 The name of your branch is $ and your repository is $."
      - name: Check out repository code # Step 이름
        uses: actions/checkout@v6 # Runner의 작업 공간에 리포지토리 코드를 체크아웃하는 Action 사용
      - run: echo "💡 The $ repository has been cloned to the runner."
      - run: echo "🖥️ The workflow is now ready to test your code on the runner."
      - name: List files in the repository
        run: |
          ls $
      - run: echo "🍏 This job's status is $." # Job 최종 실행 상태 출력

프로젝트폴더/.github/workflows 경로에 위와 같은 .yml 파일을 생성하고 커밋 후 Push 하면 자동 실행됩니다.

GitHub Actions 실행 이력 및 결과 확인

GitHub 저장소 > Actions 탭 > 좌측 워크플로 목록에서 워크플로명 선택 > 워크플로 실행 이력 목록에서 실행 이름 클릭 > 워크플로 실행 페이지 왼쪽 Jobs 아래에서 작업명 클릭 또는 우측 yml 파일명 하단에서 작업명 버튼 클릭 > 각 Step 단계별 세부 정보 로그 확인

GitHub Actions 실행 시 자동 빌드 및 테스트 방법

name: GitHub Actions Demo # GitHub Actions 워크플로명
run-name: $ is testing out GitHub Actions # Actions 실행 기록에 표시되는 이름 실행 이름
on: [push] # GitHub 저장소에 push 이벤트 발생 시 워크플로 실행
jobs:
  Explore-GitHub-Actions: # Job ID
    runs-on: ubuntu-latest # GitHub에서 제공하는 최신 우분투 서버 = 가상 머신 Runner에서 작업 실행
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4 # 리포지토리 체크아웃

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18' # Node.js 설치 및 노드 버전 세팅

      - name: Install dependencies
        run: npm ci # # package-lock.json을 기준으로 의존성 패키지 설치 (node_modules 폴더 생성)

      - name: Build project
        run: npm run build # 프로젝트 빌드

      - name: Run tests
        run: npm test # 단위테스트 등 package.json에 정의된 test 스크립트 실행

      - run: echo "🍏 This job's status is $." # Job 최종 실행 상태 출력

프로젝트폴더/.github/workflows 경로에 위와 같은 .yml 파일을 생성하고 커밋 후 Push 하면 자동 실행됩니다.
Push가 발생할 때마다 정상적으로 빌드되고 정의된 테스트가 성공하는지 자동으로 확인할 수 있습니다.


GitHub Actions 사용하여 CD 구축 방법

AWS 환경에서 배포 자동화에 사용되는 AWS CodeDeploy, AWS CodePipeline을 거치지 않고
GitHub Actions로 EC2에 실행되는 NestJS 프로젝트를 배포 및 재실행하는 방법입니다.

NestJS 프로젝트 구축 방법

https://0songha0.github.io/web-dev/2026-08-13-1
NestJS 프로젝트를 생성하고, EC2 서버에 배포 후 실행합니다.

GitHub Actions Secret 등록

GitHub Actions Secret에 EC2 SSH 키 등록
GitHub > 프로젝트 리포지토리 > Settings 탭 > Security > Secrets and variables > Actions 메뉴 > Repository secrets 선택 (개발/운영 서버 분리 시에는 Environment secrets 사용) > Name : AWS_SSH_KEY 입력 > Secret : EC2 서버 생성 시 다운로드된 키 파일 (.pem) 전체 내용 복사 후 붙여넣기 > Add secret
EC2 SSH 키처럼 민감한 인증정보는 커밋하지 않고, secret으로 관리하는 것이 GitHub 권장 방식입니다.

GitHub Actions >Secret에 EC2 Public IP 등록
GitHub > 프로젝트 리포지토리 > Settings 탭 > Security > Secrets and variables > Actions 메뉴 > Repository secrets 선택 (개발/운영 서버 분리 시에는 Environment secrets 사용) > Name : EC2_PUBLIC_IP 입력 > Secret : EC2 서버 Public IP 복사 후 붙여넣기 > Add secret
EC2 Public IP는 민감정보가 아니므로 Repository Variable로 관리할 수도 있습니다.

GitHub Actions 실행 시 자동 빌드 및 배포 방법

name: GitHub Actions Demo # GitHub Actions 워크플로명
run-name: $ is testing out GitHub Actions # Actions 실행 기록에 표시되는 실행 이름

on: [push] # GitHub 저장소에 push 이벤트 발생 시 워크플로 실행

jobs:
  build-and-deploy: # Job ID (빌드 및 배포는 Job을 분리하는 것이 좋습니다)
    runs-on: ubuntu-latest # GitHub에서 제공하는 최신 우분투 서버 = 가상 머신 Runner에서 작업 실행

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4 # 리포지토리 체크아웃

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18' # Node.js 설치 및 노드 버전 세팅

      - name: Install dependencies
        run: npm ci # package-lock.json을 기준으로 의존성 패키지 설치 (node_modules 폴더 생성)

      - name: Build project
        run: npm run build # 프로젝트 빌드

      - name: Configure AWS SSH key
        env:
          AWS_SSH_KEY: $ # GitHub Actions Secret에 등록한 EC2 SSH 키 내용 가져오기
        run: |
          mkdir -p ~/.ssh/ # Runner에 SSH 설정 폴더 생성
          echo "$AWS_SSH_KEY" > ~/.ssh/aws.key # SSH 키 내용을 파일로 저장
          chmod 600 ~/.ssh/aws.key # SSH 키 파일 접근 권한 설정
          echo "StrictHostKeyChecking no" >> ~/.ssh/config # 최초 SSH 접속 시 호스트 확인 질문 생략

      - name: Deploy to EC2
        env:
          EC2_PUBLIC_IP: $ # GitHub Actions Secret에 등록한 EC2 Public IP 가져오기
          EC2_USER: ec2-user # Amazon Linux EC2 기본 접속 사용자
        run: |
          # 프로젝트 실행에 필요한 빌드 파일 등을 EC2 서버로 전송하여 복사
          scp -o StrictHostKeyChecking=no -i ~/.ssh/aws.key -r \
            dist/ \
            package.json \
            tsconfig.json \
            tsconfig.build.json \
            $EC2_USER@$EC2_PUBLIC_IP:~/ci-test-server

          # EC2 서버에 SSH로 접속하여 애플리케이션 프로세스 재실행
          ssh -o StrictHostKeyChecking=no -i ~/.ssh/aws.key $EC2_USER@$EC2_PUBLIC_IP << 'ENDSSH'
            cd ~/ci-test-server
            npm install
            pm2 restart ci-test-server || pm2 start dist/main.js --name "ci-test-server"
          ENDSSH

      - run: echo "🍏 This job's status is $." # Job 최종 실행 상태 출력

프로젝트폴더/.github/workflows 경로에 위와 같은 .yml 파일을 생성하고 커밋 후 Push 하면 자동 실행됩니다.
프로젝트 내부 코드를 변경하고 정상적으로 서버에 반영되었는지 확인하면 좋습니다.