
CI/CD란 지속적 통합(Continuous Integration)과 지속적 배포(Continuous Deployment)라는 의미를 가지고 있다. 쉽게 표현하자면 CI/CD는 테스트(Test), 통합(Merge), 배포(Deploy)의 과정 즉, 소프트웨어 개발 및 배포 프로세스를 자동화하는 방법론 의미한다.
📍 [ CI (Continuous Integration, 지속적 통합) ]
• 개발자가 코드를 중앙 저장소(GitHub, GitLab 등)에 자주 푸시함
• 푸시된 코드가 자동으로 빌드되고, 유닛 테스트를 수행함
• 코드 충돌을 빠르게 감지하여 품질을 유지함
📍 [ CD (Continuous Delivery/Deployment, 지속적 배포/전달) ]
• CI 후, 테스트를 통과한 코드가 운영 환경(Production)에 배포될 준비가 완료됨
• Continuous Delivery: 배포는 수동으로 진행 (운영팀이 최종 승인)
• Continuous Deployment: 테스트를 통과하면 자동으로 운영 환경에 배포됨
빠르고 안정적인 배포
코드 변경 사항이 자동으로 빌드, 테스트, 배포되어 배포 주기가 단축됨 → 개발 속도 증가
자동화된 테스트로 품질 유지
코드 변경 시마다 자동으로 테스트하여 버그를 조기에 발견 → 코드 품질 유지 및 안정성 향상
팀 협업 강화
여러 개발자가 동시에 작업해도 코드 충돌을 빠르게 해결할 수 있음
인프라 운영 부담 감소
수작업 배포 대신 자동화를 통해 효율적인 운영 가능 → 배포 자동화로 실수 감소
1. 개발자가 코드 변경 & Push
GitHub/GitLab 등 중앙 저장소에 코드가 푸시됨
2. CI(지속적 통합) 실행
빌드 & 유닛 테스트 자동 실행
3. 테스트 결과 확인 & 코드 병합
테스트 성공 시, main 브랜치로 병합 (PR 기반)
4. CD(지속적 배포) 실행
Docker 이미지 빌드 후 컨테이너 레지스트리에 업로드
Kubernetes, AWS ECS/Fargate, Vercel, Netlify 등의 환경에 자동 배포
5. 서비스 배포 완료 & 모니터링
배포된 서비스의 상태를 확인하고 모니터링 (로그 분석, 에러 감지)
Jenkins의 단점으로는 별도의 서버에 구축을 해야 한다는 단점이 있다. 이 때문에 서버를 빌리는 비용이 발생하게 된다. 하지만 Github Actions는 별도의 서버 구축 없이 Github에 내장되어 있는 Github Actions 기능을 사용할 수 있다. 비용적인 측면도 유리하고 셋팅하는 데 시간을 쓸 필요도 없다.
Github Actions를 로직을 실행시킬 수 있는 일종의 컴퓨터라고 생각하면 된다. CI/CD 자동화 도구로, 코드 변경이 있을 때 “빌드, 테스트, 배포”에 대한 로직을 자동으로 실행시키는 역할을 하게 된다.

git init
git add . // 전체 파일
git commit -m "커밋내용"
git branch -M main
git remote add origin [깃주소]
git push -u origin main
해당 프로젝트 파일 가장 상단에 폴더 생성
.github - 폴더 생성 (고정값)
workflows - 폴더 생성 (고정값)
deploy.yml - [원하는파일명].yml
✨ 해당 파일은 들여쓰기 중요
[1] Action 실행 여부 확인
name: Github Actions 실행시켜보기
on:
push:
branches:
-main
main 이라는 branch 가 push 될 때마다 동작하는 코드
위 코드 작성 및 commit 후에 github 해당 레포지토리 Actions 탭 확인해보면, 아래처럼 인식이 된다.
✨ 5.. 이라는 커밋이 액션에 남아있다
해당 코드의 오류는 추가적인 액션 코드를 미작성 하였기 때문
[2] 추가코드작성
# Workflow의 이름
# Workflow : 하나의 yml 파일을 하나의 Workflow라고 부른다.
name: Github Actions 실행시켜보기
# Event : 실행되는 시점을 설정
# main이라는 브랜치에 push 될 때 아래 Workflow를 실행
on:
push:
branches:
- main
# 하나의 Workflow는 1개 이상의 Job으로 구성된다.
# 여러 Job은 기본적으로 병렬적으로 수행된다.
jobs:
# Job을 식별하기 위한 id
My-Deploy-Job:
# Github Actions를 실행시킬 서버 종류 선택
runs-on: ubuntu-latest
# Step : 특정 작업을 수행하는 가장 작은 단위
# Job은 여러 Step들로 구성되어 있다.
steps:
- name: Hello World 찍기 # Step에 이름 붙이는 기능
run: echo "Hello World" # 실행시킬 명령어 작성
- name: 여러 명령어 문장 작성하기
run: |
echo "Good"
echo "Morning"
pwd
# 참고: https://docs.github.com/en/actions/learn-github-actions/variables
- name: Github Actions 자체에 저장되어 있는 변수 사용해보기
run: |
echo $GITHUB_SHA
echo $GITHUB_REPOSITORY
- name: Github Actions Secret 변수 사용해보기
run: |
echo ${{ secrets.MY_NAME }}
echo ${{ secrets.MY_HOBBY }}

🎱 steps - [name: Hello World 찍기 # Step에 이름 붙이는 기능]
echo : JavaScript 에서 console.log 와 동일한 역할 → "Hello World" 를 출력해줌shell: /usr/bin/bash -e {0} : GitHub Actions가 실행 환경을 로그에 출력🎱 steps - [name: 여러 명령어 문장 작성하기]
🎱 steps - [name: Github Actions 자체에 저장되어 있는 변수 사용해보기]
🎱 steps - [name: Github Actions Secret 변수 사용해보기]
▶︎ [ Secret 변수를 설정 ]
settings > Secrets and variables > Actions > New repository secret
Name : secret 변수명Seceret : 해당 변수에 대한 값
*** 으로 출력. secrets 값을 로그에서 직접 노출되지 않도록 자동으로 마스킹 처리깃허브는 S3 외부서비스 이기 때문에 AWS 서비스에 접근할 때 암호키 필요 아무나 외부에서 접근할 수 있게 하면 안 됨 인증된 사용자만 출입 가능하게 하는 출입증 같은 느낌
users 에서 Create User
원하는 액세스 키 이름으로 설정
정책 직접 연결 ( Attach policies directly ) 선택

[정책 1] AmazonS3FullAccess
: S3 에 대한 권한 부여
[정책 2] CloudFrontFullAccess
: 캐시 무효화 및 최신 업데이트 된 파일로 업데이트
[정책 1, 2] 설정 후 사용자 생성
해당 액세스 키 이름 클릭 후 Security credentials > Create access key 접속
[완료]
IAM 에서 발급받은 Access key / Secret access key 둘 다 모두 Actions secret 키 생성
name: Deploy To S3
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Github Repository 파일 불러오기
uses: actions/checkout@v4
- name: Github Repository 파일 출력하기 (확인하기)
run: ls
uses: actions/checkout@v4 : github 에 있는 checkout 이라는 라이브러리를 실행 (이는 레포지토리에 있는 코드가 저장되어있다고 생각하면 됨)ls : 현재 추가된 파일명을 나열해줌 (파일이 맞게 올라갔는 지 확인)name: Deploy To S3
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Github Repository 파일 불러오기
uses: actions/checkout@v4
- name: AWS Resource에 접근할 수 있게 AWS credentials 설정
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-2
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
- name: S3 기존 파일들 전체 삭제 후 새로 업로드
run: |
aws s3 rm s3://insta-web-neul --recursive || echo "S3 삭제 실패 또는 버킷 없음"
aws s3 cp ./ s3://insta-web-neul/ --recursive
- name: Cloudfront 캐시 무효화
run: |
aws cloudfront create-invalidation --distribution-id ED5O7HAB3C1QS --paths "/*" || echo "CloudFront 캐시 무효화 실패"
목표: main 브랜치에 push할 때마다
→ S3 버킷에 정적 파일 전체 업로드
→ CloudFront 캐시 무효화해서 최신 파일이 반영되도록 처리