학습일지

[스나이퍼팩토리] 한컴AI아카데미(26.06.02) GitHub CI/CD

cd-record 2026. 6. 4. 00:43

 

CI/CD란 무엇인가?

  • CI (Continuous Integration, 지속적 통합): 개발자가 수정한 코드를 자주 중앙 저장소(GitHub)에 병합하고, 자동으로 빌드 및 테스트를 수행하여 코드의 품질을 유지하는 과정입니다.
  • CD (Continuous Deployment/Delivery, 지속적 배포): 빌드된 코드를 테스트 서버 또는 실제 운영 서버에 자동으로 배포하는 과정입니다.

요약: "코드를 저장소에 올리기만 하면, 서버에 적용되기까지의 모든 과정을 자동으로 처리하는 시스템"입니다.

# CI/CD 파이프라인의 이점

  1. 휴먼 에러 방지: 매번 직접 SSH로 접속해 git pull하고 restart하는 번거로움과 실수를 줄입니다.
  2. 즉각적인 피드백: 코드 수정 후 바로 서버에 반영되어 결과를 확인할 수 있습니다.
  3. 일관성: 항상 동일한 절차로 배포되므로 배포 환경의 일관성이 보장됩니다.

참고: appleboy/ssh-action 방식은 외부 서버를 깃허브가 '원격 조종'하는 느낌이라면, Self-hosted Runner는 내 서버가 깃허브의 '일꾼'이 되어 명령을 스스로 수행하는 방식이라고 이해하면 쉽습니다.

 

# 배포 방식 비교

구분 SSH 원격 배포 (appleboy/ssh-action) Self-hosted Runner (액션 러너)
작동 원리 깃허브 서버에서 내 서버로 SSH 접속 후 명령 실행 내 서버에 설치된 러너가 깃허브의 작업을 가져옴
보안 SSH Key 관리 필요 내 서버 내에서 작업 수행 (외부 노출 적음)
특징 외부 서버(클라우드 등) 배포에 범용적 서버 내부 자원을 활용하여 속도가 빠름
추천 간단한 프로젝트, 클라우드 환경 높은 보안 요구, 특정 서버 직접 제어

 

# Self-hosted Runner

액션러너방식

name: Self-hosted Runner

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: self-hosted
 
    steps:
      - name: Execute Deploy Script
        run: |
          cd /home/ubuntu/flaskapp/address
          git fetch origin main
          git reset --hard origin/main
          cd /home/ubuntu/flaskapp            
          docker-compose restart was-host

1단계: 깃허브 설정

  1. Repository ➡️ Settings 탭 이동.
  2. 좌측 Actions ➡️ Runners 선택.
  3. New self-hosted runner 버튼 클릭.
  4. 본인의 서버 OS와 아키텍처(예: Linux/x64) 선택.

2단계: 서버에 설치 (터미널 명령)

깃허브 화면에 나오는 명령어를 순서대로 서버 터미널에 입력합니다.

  • 다운로드 및 압축 해제 명령을 따라 하세요.
  • ./config.sh --url ... --token ... 명령어를 실행하여 깃허브와 서버를 연결합니다.

 주의점:  ./run.sh는 임시실행이라 여기서는 사용하지 마세요

3단계: 백그라운드 서비스 등록 (중요)

터미널을 닫아도 러너가 죽지 않도록 서비스(Service)로 등록해야 합니다.

# 1. 러너를 시스템 서비스로 설치
sudo ./svc.sh install

# 2. 서비스 시작
sudo ./svc.sh start

# 3. 서비스 상태 확인 (실행 중인지 확인)
sudo ./svc.sh status
  • Tip: run.sh는 테스트용입니다. 반드시 svc.sh를 사용하여 서비스로 등록하세요. 그래야 서버 재부팅 시에도 자동으로 실행됩니다.

# 세미나룸 예약 API

1단계: 환경 및 저장소 준비

  • GitHub 저장소 생성: Organization(또는 본인 계정)에 seminar-api 리포지토리를 생성합니다.
  • 초기 구조 생성: 로컬에서 폴더를 만들고 README.md만 담아 main 브랜치에 올립니다.
  • 브랜치 생성: 로컬에서 git checkout -b devA와 git checkout -b devB를 만들어 둡니다.

2단계: B의 역할 먼저 수행 (기반 다지기)

순서가 중요합니다. 배포 환경이 없으면 API를 만들어도 확인하기 어렵습니다.

  1. devB 브랜치로 이동합니다.
  2. Dockerfile과 docker-compose.yml을 작성합니다.
  3. .github/workflows/ci-cd.yml 파일을 작성하여 GitHub Action 러너가 작동하는지 확인합니다.
  4. devB를 main으로 PR(Pull Request)하고 머지합니다.
    • 이때 서버에서 배포 스크립트가 잘 도는지(예: git pull 후 docker-compose up 확인) 체크합니다.

3단계: A의 역할 수행 (API 개발)

  1. devA 브랜치로 이동합니다.
  2. migrations/001_init.sql (DB 스키마)를 먼저 작성합니다.
  3. Flask 앱(app/ 폴더 내 파일들)을 구현합니다.
  4. tests/test_api.py를 작성하여 기능이 의도대로 동작하는지 검증합니다.
  5. 구현 완료 후 devA를 main으로 PR을 보냅니다.

4단계: 머지 및 자동 배포 확인

  1. GitHub 사이트에서 devA -> main 머지를 수행합니다.
  2. Actions 탭에서 워크플로가 자동으로 실행되는지 관전합니다.
  3. 서버에 SSH로 접속하거나 웹 서비스 호출(curl)을 통해 정상 배포되었는지 확인합니다.

5단계: 데이터 영속화 테스트 (Docker Volume 검증)

  • 핵심 테스트:
    1. 데이터를 몇 개 생성합니다 (예: POST /api/rooms 실행).
    2. 서버에서 docker-compose down을 실행해 컨테이너를 완전히 삭제합니다.
    3. 다시 docker-compose up -d를 실행합니다.
    4. GET /api/rooms로 데이터가 그대로 남아있는지 확인합니다. (볼륨 설정 성공 여부 판단)

6단계: API 테스트 및 기록

  • Postman이나 cURL을 이용해 API 명세에 나온 모든 기능을 호출하고 결과를 캡처합니다.
  • 에러가 발생하면 서버 로그(docker logs <컨테이너명>)를 확인하여 수정합니다.

7단계: 제출물 정리

  • GitHub 저장소 링크
  • docker-compose up으로 한 번에 뜨는지 확인한 스크린샷
  • API 응답 값 캡처 (명세서와 일치하는지)
  • GitHub Actions 초록색(성공) 로그 스크린샷

 

 

 

 

 

——————————————————————————

본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.