저번 포스팅까지 한 것을 간단하게 정리하면, 아래와 같은 흐름으로 진행됩니다.
1. main
브랜치에 푸쉬를 한다.
2. Github Actions Workflow가 작동한다. 여기서는 세 가지 작업이 진행됩니다.
Nest 애플리케이션이 zip 파일로 변환된다 -> zip 파일이 S3에 업로드된다 -> CodeDeploy Agent에 deployment가 생성되었다고 알린다.
3. CodeDeploy Agent가 S3에 업로드된 zip 파일을 다운받고 압축을 풀어둔다.
4. 특정 스크립트가 실행되어 Docker 이미지를 만들고, 그 이미지를 기반으로 한 Docker 컨테이너를 생성한다.
5. Nest 애플리케이션이 돌아간다.
이번 포스팅에서는 푸쉬를 날릴 때마다 업데이트된 코드가 실행될 컨테이너가 켜지고, 오래된 코드가 실행되는 컨테이너를 끄는 과정을 구현해보겠습니다. 즉, 하나의 EC2 인스턴스 안에서 docker container를 가지고 그린 블루 배포를 구현하겠습니다.
⚠️ 만약 이전 포스팅을 진행하면서 켜져 있는 docker container가 있다면 꺼주세요!
먼저 그린, 블루 컨테이너를 위한 docker-compose.yml
파일을 작성해주겠습니다. 프로젝트 루트 경로에 생성하면 됩니다.
# docker-compose.green.yml
version: '3'
services:
nestapp:
build: .
container_name: nestapp-green
restart: always
ports:
- '3001:3000'
# docker-compose.blue.yml
version: '3'
services:
nestapp:
build: .
container_name: nestapp-blue
restart: always
ports:
- '3002:3000'
이제 CodeDeploy Agent가 S3에서 zip 파일 가져올 때마다 두 컨테이너를 스위칭하면 됩니다. 기존의 execute.sh
에서 실행할 스크립트 이름을 수정하고, switch-container.sh
를 새로 추가하겠습니다.
# scripts/execute.sh
#!/bin/bash
cd /home/ubuntu/my-nest-app
# 여기를 수정해주세요.
# vvvvvvvvvvvvvvv
sh scripts/switch-container.sh
#!/bin/bash
DOCKER_APP_NAME=nestapp
EXIST_GREEN=$(docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml ps | grep running)
# 이번 배포에서 켜질 포트 번호
TARGET_PORT=0
# 이번 배포에서 꺼질 컨테이너 색상 ("green" or "blue")
TARGET_COLOR=""
# Green Container가 존재하지 않으면 True
if [ -z "$EXIST_GREEN" ]; then
echo "> Start Green Container..."
TARGET_PORT=3001
TARGET_COLOR="blue"
docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d
else
echo "> Start Blue Container..."
TARGET_PORT=3002
TARGET_COLOR="green"
docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d
fi
echo "> Start health check of Nest App at 'http://127.0.0.1:${TARGET_PORT}'..."
for RETRY_COUNT in `seq 1 10`
do
echo "> Retrying... (${RETRY_COUNT})"
RESPONSE_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:${TARGET_PORT})
if [ ${RESPONSE_CODE} -eq 200 ]; then
echo "> New Nest App successfully running"
echo "> Close Old Nest App"
docker-compose -p ${DOCKER_APP_NAME}-${TARGET_COLOR} -f docker-compose.${TARGET_COLOR}.yml down
break
elif [ ${RETRY_COUNT} -eq 10 ]; then
echo "> Health check failed."
exit 1
fi
sleep 10
done
echo "Prune Docker System"
docker system prune -af
exit 0
해당 스크립트를 올린 후 수동으로 배포를 진행해보세요. 배포를 진행할 때마다 접속 가능한 포트가 3001 <-> 3002 포트로 스위칭되는 것을 확인할 수 있습니다.