CI/CD와 GitHub Actions, Docker- 자동화된 배포 파이프라인 구축하기
1. CI/CD란?
- CI/CD(Continuous Integration and Continuous Deployment)는 애플리케이션 개발에서 빌드, 테스트, 배포를 자동화하는 프로세스를 말한다.
- CI(Continuous Integration, 지속적 통합)
- 개발자들이 작성한 코드를 정기적으로 병합하고, 병합된 코드에 대해 자동 빌드와 테스트를 수행한다.
- 코드 충돌을 조기에 발견하고, 안정적인 소프트웨어를 유지하는 데 도움을 준다.
- CD(Continuous Deployment/Delivery, 지속적 배포)
- CI로 검증된 코드를 운영 환경으로 자동 배포하거나 테스트 환경으로 배포한다.
- 배포 과정을 자동화해 개발-운영 속도를 높이고, 수동 배포의 위험성을 줄인다.
2. GitHub Actions: CI/CD를 구현하는 도구
GitHub Actions는 GitHub에서 제공하는 자동화 도구로, 코드 저장소에서 직접 CI/CD 워크플로를 정의하고 실행할 수 있다.
워크플로를 작성하면, 코드가 업데이트될 때마다 빌드, 테스트, 배포를 자동으로 실행할 수 있다.
GitHub Actions의 주요 구성 요소
- 워크플로(Workflow)
- 자동화 작업의 정의를 담은 파일.
.github/workflows
디렉토리 아래에 YAML 파일로 작성한다.
- 자동화 작업의 정의를 담은 파일.
- 이벤트(Event)
- 워크플로가 실행되는 조건(예:
push
,pull_request
,schedule
등).
- 워크플로가 실행되는 조건(예:
- 잡(Job)
- 작업의 단위이며, 여러 작업으로 구성될 수 있다.
- 스텝(Step)
- 각 작업 내에서 실행되는 개별 명령어나 스크립트.
- 액션(Action)
- 재사용 가능한 작업 단위로, GitHub Actions에서 제공하는 플러그인이다.
3. Docker: 컨테이너 기반 애플리케이션 배포
Docker는 애플리케이션 실행 환경을 컨테이너로 패키징하여, CI/CD 과정에서 안정적이고 일관된 환경을 제공한다.
CI/CD와 Docker를 결합하면, 다음과 같은 이점이 있다:
- 테스트와 배포 환경이 항상 동일하게 유지된다.
- 애플리케이션과 의존성을 분리하여 경량화된 빌드 및 배포가 가능하다.
- 컨테이너 이미지를 생성하고, 이를 CI/CD 파이프라인에서 쉽게 재사용할 수 있다.
4. GitHub Actions와 Docker로 CI/CD 구축
4.1 기본 워크플로 구성
다음은 Node.js 애플리케이션을 Docker 컨테이너로 빌드하고, 테스트 후 배포하는 GitHub Actions 워크플로 예제이다.
파일 경로: .github/workflows/ci-cd.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
yaml
코드 복사
name: CI/CD Pipeline
on:
push:
branches:
- main # main 브랜치에 푸시될 때 워크플로 실행
jobs:
build:
runs-on: ubuntu-latest
steps:
# 1. 코드 체크아웃
- name: Check out the repository
uses: actions/checkout@v3
# 2. Docker 환경 설정
- name: Set up Docker
run: |
docker --version
# 3. Docker 이미지를 빌드
- name: Build Docker Image
run: |
docker build -t my-app .
# 4. 애플리케이션 테스트
- name: Run Tests
run: |
docker run my-app npm test
# 5. Docker Hub로 푸시 (선택)
- name: Push Docker Image to Docker Hub
env:
DOCKER_USERNAME: $
DOCKER_PASSWORD: $
run: |
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker tag my-app my-dockerhub-account/my-app:latest
docker push my-dockerhub-account/my-app:latest
deploy:
runs-on: ubuntu-latest
needs: build
steps:
# 1. 서버로 배포 (예: SSH를 통해 Docker 컨테이너 실행)
- name: Deploy to Server
env:
SERVER_HOST: $
SERVER_USER: $
SERVER_KEY: $
run: |
ssh -i "${SERVER_KEY}" "${SERVER_USER}@${SERVER_HOST}" \
'docker pull my-dockerhub-account/my-app:latest && \
docker stop my-app || true && \
docker run -d --name my-app -p 3000:3000 my-dockerhub-account/my-app:latest'
4.2 구성 요소 설명
코드 체크아웃
actions/checkout@v3
를 사용해 GitHub 저장소의 코드를 가져온다.Docker 이미지 빌드
docker build
명령어로 Docker 이미지를 생성한다.테스트 실행
빌드된 Docker 이미지를 실행해 애플리케이션의 테스트를 수행한다.
Docker Hub로 푸시
CI 과정에서 생성한 Docker 이미지를 Docker Hub에 업로드한다.
- GitHub Secrets에 Docker Hub 계정 정보를 저장(
DOCKER_USERNAME
,DOCKER_PASSWORD
).
- GitHub Secrets에 Docker Hub 계정 정보를 저장(
배포 단계
SSH를 통해 원격 서버에서 Docker 컨테이너를 실행하여 애플리케이션을 배포한다.
5. Docker Compose를 활용한 CI/CD
Docker Compose를 활용하면 여러 컨테이너를 동시에 실행할 수 있다.
다음은 Docker Compose를 사용하여 애플리케이션과 데이터베이스를 함께 배포하는 구성 예제이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// docker-compose.yml
version: '3.8'
services:
app:
image: my-dockerhub-account/my-app:latest
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
ports:
- "5432:5432"
배포 명령어 (GitHub Actions의 deploy 단계에서 실행)
1
2
docker-compose pull
docker-compose up -d
6. CI/CD 도입의 장점
- 자동화된 빌드와 배포
- 수동 배포 시간을 줄이고, 더 빠르게 새로운 기능을 제공할 수 있다.
- 품질 보장
- CI로 코드를 병합하기 전에 테스트를 자동으로 실행해 코드 품질을 유지한다.
- 일관성
- Docker 컨테이너를 사용해 모든 환경에서 동일한 실행 환경을 제공한다.
- 확장성
- GitHub Actions는 다양한 플러그인과 유연한 설정을 제공하므로 확장 가능한 파이프라인을 구축할 수 있다.
7. 정리
Docker와 GitHub Actions는 현대적인 CI/CD 워크플로를 구축하기에 이상적인 조합이다.
Docker를 통해 환경을 컨테이너화하고, GitHub Actions로 이를 자동화하면 코드 병합부터 배포까지의 모든 과정을 매끄럽게 처리할 수 있다.