이번 시간에는 현대 소프트웨어 개발 및 DevOps 환경에서 필수 요소로 자리 잡은 CI/CD(지속적 통합 및 지속적 배포)의 개념과 배포 모델(Push vs Pull), 그리고 GitHub Actions를 활용하여 AWS EC2 인스턴스에 코드를 자동으로 배포하는 실습까지 한눈에 알기 쉽게 정리해 보겠습니다.
1. CI/CD 개요 및 필요성
💡 CI/CD란?
- CI (Continuous Integration, 지속적 통합): 개발자들이 작업한 소스 코드를 주기적으로 중앙 저장소에 자동 합치고, 이를 검증하기 위해 자동화된 빌드 및 테스트를 수행하는 프로세스입니다.
- CD (Continuous Delivery / Deployment, 지속적 제공 / 배포):
- Continuous Delivery: CI 통과 후 프로덕션 환경에 배포할 수 있도록 준비(릴리스)하는 과정입니다. (최종 배포 버튼은 사람이 클릭)
- Continuous Deployment: CI를 통과한 코드를 사람이 개입하지 않고 실제 프로덕션 서버에 자동으로 배포하는 완벽 자동화 과정입니다.
🎯 CI/CD 도입 시 이점
- 개발 라이프사이클 단축: 코드 작성 후 배포까지 걸리는 수동 작업 시간을 획기적으로 줄여줍니다.
- 안정성 및 소프트웨어 품질 향상: 커밋마다 자동 테스트가 실행되므로 버그와 코드 충돌을 빠르게 감지합니다.
- 생산성 증가 및 비용 절감: 반복적인 배포 작업이 자동화되어 개발자가 비즈니스 로직 작성에만 집중할 수 있습니다.
2. CI/CD 배포 모델 (Push vs Pull)
배포 방식은 크게 Push 방식(전통적 방식)과 Pull 방식(GitOps 방식)으로 나누어 볼 수 있습니다.
[ Push 모델 ]
GitHub (CI) ─────SSH 접속/파일전송(Push)─────> AWS EC2 (운영서버)
[ Pull 모델 (GitOps) ]
GitHub (CI) ──(Manifest 변경)──> Git Repo <──주기적 감지/가져오기(Pull)── ArgoCD (클러스터 내부)
1) Push 모델 (전통적 방식)
- 정의: CI 서버(GitHub Actions, Jenkins 등)가 빌드/테스트를 완료한 후, 직접 원격 서버(AWS EC2 등)에 접속(SSH)하여 배포 명령을 밀어넣는(Push) 방식입니다.
- 특징:
- 하나의 파이프라인 안에서 [빌드 ➔ 테스트 ➔ 배포]를 일괄적으로 직관 처리할 수 있습니다.
- 구성이 매우 간단하여 소규모 프로젝트나 단일 서버 환경에 적합합니다.
- 주의점: CI 서버가 운영 서버의 접근 권한(SSH Key, IP 정보 등)을 들고 있어야 하므로, CI 서버가 해킹당할 경우 보안 위험이 발생할 수 있습니다.
2) Pull 모델 (GitOps 방식)
- 정의: 배포 서버 내부의 에이전트(ArgoCD 등)가 Git 저장소를 주기적으로 모니터링하다가 새로운 변경 사항(Manifest)이 생기면 스스로 가져와(Pull) 적용하는 방식입니다.
- 특징:
- CI 서버가 운영 환경에 직접 접근하지 않으므로 보안상 매우 유리합니다.
- 쿠버네티스(Kubernetes) 환경에서 버전 관리 및 선언적 배포(Declarative Deployment) 관리가 수월합니다.
💡 Tip: 단일 EC2에 소규모 서비스를 배포할 때는 Push 모델(GitHub Actions + SSH)이 훨씬 간단하고 효율적입니다. 반면, 쿠버네티스 기반의 클러스터 환경에서는 Push(CI) + Pull(CD via ArgoCD)을 조합하는 것이 현대적인 대세 패턴입니다.
3. [실습] GitHub Actions를 이용한 Push 기반 CI/CD 구축
이제 GitHub Actions를 이용해 소스 코드가 main 브랜치에 push되면,
AWS EC2 서버로 소스 코드가 자동 전송되는 파이프라인을 만들어 보겠습니다.
1) 프로젝트 구조 준비
우선 아래와 같이 파이썬(FastAPI 또는 Flask) 프로젝트가 구성되어 있다고 가정합니다.
- main.py
- templates/index.html
- static/

GitHub Actions를 발동시키려면 프로젝트 루트 디렉토리에 .github/workflows/ 폴더를 만들고 YAML 파일(예: deploy.yml)을 작성해야 합니다.
2) 사전 작업: GitHub Secrets 환경 변수 등록
SSH 접속 정보와 비밀키를 소스 코드(YML)에 직접 하드코딩하면 보안상 치명적입니다. GitHub 저장소의 Settings ➔ Secrets and variables ➔ Actions로 이동하여 다음 비밀값들을 등록해 줍니다.
- HOST: AWS EC2 퍼블릭 IP 주소 (또는 도메인)
- USERNAME: EC2 OS 사용자 이름 (Ubuntu의 경우 기본값 ubuntu)
- EC2_KEY: EC2 인스턴스 생성 시 받은 .pem 파일의 전체 텍스트 내용
3) GitHub Actions 워크플로우 파일 작성 (.github/workflows/deploy.yml)
아래 코드를 작성하여 프로젝트에 포함한 뒤 GitHub에 Push합니다.
# 파이프라인 이름 지정
name: Push 기반 CI/CD 테스트
# 1. 트리거(Trigger) 정의
# main 브랜치에 push 이벤트가 발생하면 이 워크플로우가 자동으로 실행됩니다.
on:
push:
branches:
- main
# 2. 수행할 작업(Jobs) 정의
jobs:
ci:
# GitHub에서 제공하는 최신 Ubuntu 가상 환경(Runner)에서 작업 실행
runs-on: ubuntu-latest
steps:
# Step 1: GitHub 저장소에 등록된 최신 코드를 가상 환경으로 가져옴(Checkout)
- name: 코드 checkout
uses: actions/checkout@v4
# Step 2: 코드 전달 상태 및 테스트 검증
- name: 확인 검증
# 여러 줄의 Bash 명령어를 실행할 때는 '|' 부호를 사용합니다.
run: |
pwd
ls -al
cat main.py
shell: bash
# Step 3: SCP(Secure Copy)를 이용해 AWS EC2 서버로 소스 코드 전송
- name: source code copy to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.EC2_KEY }}
port: 22
# 복사할 대상 ('.' 은 현재 프로젝트의 모든 파일)
source: .
# EC2 서버 내부에서 파일이 복사되어 들어갈 경로
target: "/home/ubuntu/projects"
💡 한 걸음 더! (실무 팁: 코드 전송 후 서비스 자동 재시작)
현재 작성된 scp-action은 소스 코드를 서버로 '전송'하는 역할만 수행합니다. 실제 배포가 완료되려면 전송이 끝난 후 FastAPI/Flask 백엔드 서버 프로세스를 재시작해 주어야 새 코드가 반영됩니다.
이때는 appleboy/ssh-action을 파이프라인 마지막 스텝에 추가하여 EC2 명령어를 실행해 주는 것이 좋습니다.
# Step 4 (추가 권장): EC2 서버 접속 후 서비스 프로세스 재시작
- name: SSH로 EC2 접속 후 애플리케이션 재시작
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.EC2_KEY }}
port: 22
script: |
cd /home/ubuntu/projects
# 예시: 기존 uvicorn/python 프로세스 종료 후 재구동 (또는 systemctl restart / docker-compose restart 등)
sudo systemctl restart my_app.service
4. 마치며
GitHub Actions를 활용하면 복잡한 빌드 및 배포 과정을 손쉽게 자동화할 수 있습니다.
- main 브랜치에 코드 Push
- GitHub Actions가 이를 감지하여 최신 코드 검증
- AWS EC2 서버로 파일 전송 및 서비스 자동으로 재시작
이 파이프라인 구축을 통해 수동 배포로 인한 실수(Human Error)를 방지하고, 빠르고 안전하게 서비스를 업데이트할 수 있습니다. 실무 프로젝트에서도 차근차근 적용해 보세요!
오늘의 한 마디
업무 진행하면서 운영중인 서버에 파일을 직접 배포하고 재시작할 때면 얼마나 마음이 떨리는지 직접해보지 않으면 알지 못할겁니다. 이런 ci/cd 기술을 개발시 미리 만들어 놓고 진행하는 것이 백번 천번 좋습니다. 요즘은 ai의 발달로 ci/cd하는 것도 점점 쉬워지지 않을까 생각이 듭니다. 명령어만 잘 치면 말이죠.
확실히 ci/cd가 있는 프로젝트와 없는 프로젝트는 차이가 너무 납니다. 어떤 미친 프로젝트는 형상관리도 안되고 있어 제가 직접 svn을 설치하여 프로젝트 형상관리를 그제서야 진행한 것도 있습니다... 하 갑자기 생각하니 열받으니 여기까지만 하시죠 ㅎㅎ
'코딩 개발 > Git' 카테고리의 다른 글
| AWS EC2 에 GitHub Action으로 CI/CD 해보기 (0) | 2026.08.20 |
|---|---|
| [Git/GitHub] GitHub 원격 저장소 생성, 커밋·푸시 및 취소(Reset/Revert) (0) | 2026.08.17 |
| [Git/GitHub] 개발 필수 도구 Git 기초 개념부터 SSH 인증 및 초기 세팅 (0) | 2026.08.14 |