Docker 컨테이너 기반 GitHub Actions CI/CD 파이프라인 구축 방법
기존 서버 프로세스를 도커 컨테이너로 전환하는 과정입니다.
기존 서버 프로세스 도커 컨테이너 전환
도커 패키지 설치
sudo yum update -y
sudo yum install docker -y
도커 서비스 시작
sudo service docker start
시스템 부팅 시 도커 자동 시작 설정
sudo systemctl enable docker
현재 사용자를 docker 그룹에 추가
sudo usermod -a -G docker 사용자명
newgrp docker
sudo 없이 도커 명령어를 실행할 수 있도록 현재 사용자를 docker 그룹에 추가하고 쉘에 즉시 반영합니다.
도커 컨테이너 기반 CI/CD 구축
GitHub Actions 워크플로 파일 생성
name: Node.js CI/CD
on:
push:
branches: [ master ] # 마스터 브랜치에 push 이벤트 발생 시마다 워크플로 실행
jobs:
build-and-push: # 빌드 및 push Job (CI)
runs-on: ubuntu-latest
outputs: # 다른 Job에서도 사용할 수 있는 Job Output
image_tag: $
steps:
- uses: actions/checkout@v4 # 리포지토리 체크아웃
- name: Generate version # 현재 커밋의 Git SHA 앞 7자리를 version 값으로 저장
id: version # Step Output을 참조하기 위한 Step ID
run: |
echo "version=${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
- name: Configure AWS credentials # AWS 인증 정보 설정
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: $
aws-secret-access-key: $
aws-region: $ # ap-northeast-2 (아시아 태평양. 서울 리전)
- name: Login to Amazon ECR # GitHub Actions Runner가 Amazon ECR 로그인하는 Step
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Set up QEMU # 현재 Runner와 다른 CPU 아키텍처의 프로그램을 실행할 수 있도록 에뮬레이션하는 도구
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx # Docker Buildx 빌더 설정
uses: docker/setup-buildx-action@v3
- name: Build and push Docker image # 도커 이미지 빌드 및 AWS ECR Push
env:
ECR_REGISTRY: $
ECR_REPOSITORY: $
IMAGE_TAG: $
run: |
# 멀티 플랫폼 빌드 및 푸시 (Private 이미지 저장소 Amazon ECR에 빌드 결과물 도커이미지 업로드)
# 프로젝트 경로 Dockerfile 파일 기반으로 패키지 다운 및 애플리케이션 실행하는 도커 이미지 빌드
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
-t $ECR_REGISTRY/$ECR_REPOSITORY:latest \
--push .
# AMD64, ARM64용 이미지를 동시에 빌드
# 커밋 SHA 등으로 만든 버전 태그 지정
# 같은 이미지에 latest 태그도 추가
# 현재 디렉터리를 빌드 컨텍스트로 사용하고, 빌드 완료 후 ECR로 Push
deploy: # 배포 Job (CD)
needs: build-and-push
if: github.ref == 'refs/heads/master' # 마스터 브랜치인 경우에만 deploy가 실행되도록 설정
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials # AWS 인증 정보 설정
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: $
aws-secret-access-key: $
aws-region: $
- name: Login to Amazon ECR # GitHub Actions Runner가 Amazon ECR 로그인하는 Step
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Create SSH directory # Runner 홈 디렉터리에 SSH 설정용 폴더 생성
run: mkdir -p ~/.ssh
- name: Add SSH key # EC2 SSH 접속용 Private Key 파일 저장
run: |
echo "$" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
- name: Add EC2 host to known_hosts # EC2 서버 SSH 호스트 키를 known_hosts에 미리 등록
env:
EC2_HOST: $
run: |
ssh-keyscan -H $EC2_HOST >> ~/.ssh/known_hosts
- name: Deploy to EC2 # EC2 서버에 도커 컨테이너 배포
env:
ECR_REGISTRY: $
ECR_REPOSITORY: $
IMAGE_TAG: $
EC2_HOST: $ # EC2 서버 public IP
EC2_USERNAME: $ # ec2-user
run: |
# 디버깅을 위한 환경 변수 출력
echo "ECR_REGISTRY: ${ECR_REGISTRY}"
echo "ECR_REPOSITORY: ${ECR_REPOSITORY}"
echo "IMAGE_TAG: ${IMAGE_TAG}"
echo "전체 이미지 경로: ${ECR_REGISTRY}/${ECR_REPOSITORY}:${IMAGE_TAG}"
# EC2 서버에 SSH 접속하여 AWS 자격 증명 및 설정 파일 생성
# EC2 서버에서 Private Amazon ECR에 접근하기 위한 AWS 인증 정보 설정
# 실무에서는 EC2 IAM Role을 부여하여 Access Key를 서버에 직접 저장하지 않는 방식 권장
ssh -i ~/.ssh/id_rsa $EC2_USERNAME@$EC2_HOST "mkdir -p ~/.aws"
echo "[default]
aws_access_key_id=$
aws_secret_access_key=$
region=$" | ssh -i ~/.ssh/id_rsa $EC2_USERNAME@$EC2_HOST "cat > ~/.aws/credentials"
# 신규 도커 이미지를 Private 이미지 저장소 Amazon ECR에서 pull 받고,
# 기존 컨테이너 제거 후 신규 컨테이너 실행
ssh -i ~/.ssh/id_rsa $EC2_USERNAME@$EC2_HOST "\
source ~/.bashrc && \
aws ecr get-login-password --region $ | docker login --username AWS --password-stdin ${ECR_REGISTRY} && \
docker pull ${ECR_REGISTRY}/${ECR_REPOSITORY}:${IMAGE_TAG} && \
(docker rm -f 컨테이너명 || true) && \
docker run -d --name 컨테이너명 -p 3000:3000 ${ECR_REGISTRY}/${ECR_REPOSITORY}:${IMAGE_TAG} && \
docker image prune -a -f"
# 현재 어떤 컨테이너에서도 사용하지 않는 도커 이미지 전체 삭제
프로젝트폴더/.github/workflows 경로에 위와 같은 .yml 파일을 생성하고 커밋 후 Push 하면 자동 실행됩니다.
프로젝트 내부 코드를 변경하고 정상적으로 서버에 반영되었는지 확인하면 좋습니다.
Node.js, golang은 5분 내로 배포되는 경우가 많지만, 크기가 큰 모바일 앱은 1시간도 걸릴 수 있습니다.
프로젝트 크기가 커질수록 CI/CD 시간도 길어지고 작은 변경에도 전체를 다시 배포해야 합니다.
서비스별 독립적인 개발·배포·확장이 가능하도록 마이크로서비스 아키텍처(MSA)가 발전하게 되었습니다.
하나의 워크플로 내에서 각 Job은 독립된 Runner 환경에서 실행되며,
필요한 경우 Artifact를 통해 파일을 공유할 수 있습니다.
같은 Job에 포함된 Step들은 동일한 Runner에서 순차적으로 실행됩니다.
빌드 Job에서 빌드 결과물 Artifacts를 업로드하고, 배포 Job에서 다운로드하여 사용할 수도 있습니다.
AWS ECR 컨테이너 레포지토리 생성 방법
AWS > ECR 검색 > Amazon ECR 선택 > Private registry 메뉴 > Repositories 메뉴 > 우측 상단 Create repository 버튼 > Repository name : 네임스페이스명/레포지토리명 입력 > Create
AWS IAM Users 인증 정보 확인 방법
AWS > IAM 검색 > IAM 선택 > Access management 메뉴 > Users 메뉴 > Administrator 유저 선택 > Security credentials 탭 선택 > Access Keys > Create access key 버튼 > Use case : Command Line Interface (CLI) 선택 > Confirmation 체크 > Next > Create access key > 생성된 Access key, secret access key 복사 및 저장 > Done