Skip to content

News Intelligent CD - Deploy to AWS EC2 #2

News Intelligent CD - Deploy to AWS EC2

News Intelligent CD - Deploy to AWS EC2 #2

Workflow file for this run

name: News Intelligent CD - Deploy to AWS EC2
on:
workflow_run:
# CI 성공 시 수행
workflows:
- "News Intelligent CI"
types:
- completed
jobs:
deploy:
if: ${{github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-22.04
steps:
# CI한 커밋 체크아웃
- name: Checkout repository at CI commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha }}
fetch-depth: 1
# compose 파일 확인
- name: Check compose files
run: |
echo "HEAD SHA: ${{ github.event.workflow_run.head_sha }}"
test -f docker-compose-prod.yml || (echo "compose file missing" && exit 1)
# 원격 디렉토리 준비
- name: Prepare remote dir
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_SERVER_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
script: |
mkdir -p ~/${{ secrets.REPOSITORY_PATH }}
# 서버에 compose 파일 업로드
- name: Upload compose file
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_SERVER_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
source: "docker-compose-prod.yml"
target: "~/${{ secrets.REPOSITORY_PATH }}/"
# Blue/Green 배포
- name: Blue/Green deploy to EC2
uses: appleboy/[email protected]
env:
IMAGE_TAG: ${{ github.event.workflow_run.head_sha }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_REPOSITORY: ${{ secrets.DOCKERHUB_REPOSITORY }}
NGINX_API_CONF_TPL: ${{ secrets.NGINX_API_CONF_TPL }}
with:
host: ${{ secrets.EC2_SERVER_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_PRIVATE_KEY }}
envs: IMAGE_TAG,DOCKERHUB_USERNAME,DOCKERHUB_REPOSITORY,NGINX_API_CONF_TPL
script: |
set -eo pipefail
cd ~/${{ secrets.REPOSITORY_PATH }}
ACTIVE_PORT=$(grep -oE '127\.0\.0\.1:([0-9]+)' /etc/nginx/conf.d/api.newsintelligent.site.conf 2>/dev/null | tail -1 | cut -d: -f2 || echo 8081)
if [ "$ACTIVE_PORT" = "8081" ]; then NEW_PORT=8082; else NEW_PORT=8081; fi
if [ "$NEW_PORT" = "8081" ]; then NEW_COLOR=blue; OLD_COLOR=green; else NEW_COLOR=green; OLD_COLOR=blue; fi
echo "ACTIVE_PORT=$ACTIVE_PORT, NEW_PORT=$NEW_PORT"
echo "NEW_COLOR=$NEW_COLOR, OLD_COLOR=$OLD_COLOR"
export IMAGE_TAG=$IMAGE_TAG
export DOCKERHUB_USERNAME=$DOCKERHUB_USERNAME
export DOCKERHUB_REPOSITORY=$DOCKERHUB_REPOSITORY
APP_PORT=$NEW_PORT APP_COLOR=$NEW_COLOR \
DOCKERHUB_USERNAME=$DOCKERHUB_USERNAME DOCKERHUB_REPOSITORY=$DOCKERHUB_REPOSITORY IMAGE_TAG=$IMAGE_TAG \
docker-compose -p app_${NEW_COLOR} -f docker-compose-prod.yml pull
APP_PORT=$NEW_PORT APP_COLOR=$NEW_COLOR \
DOCKERHUB_USERNAME=$DOCKERHUB_USERNAME DOCKERHUB_REPOSITORY=$DOCKERHUB_REPOSITORY IMAGE_TAG=$IMAGE_TAG \
docker-compose -p app_${NEW_COLOR} -f docker-compose-prod.yml up -d --force-recreate
for i in $(seq 1 30); do
if curl -fsS "http://127.0.0.1:${NEW_PORT}/actuator/health/readiness" | grep -q '"status":"UP"'; then
echo "New ${NEW_COLOR} healthy"; break
fi
echo "waiting health... ($i)"
sleep 2
done
if ! curl -fsS "http://127.0.0.1:${NEW_PORT}/actuator/health/readiness" | grep -q '"status":"UP"'; then
echo "New ${NEW_COLOR} failed to become healthy"
APP_PORT=$NEW_PORT APP_COLOR=$NEW_COLOR docker-compose -p app_${NEW_COLOR} -f docker-compose-prod.yml logs --tail=200 || true
exit 1
fi
sudo mkdir -p /etc/nginx/templates
printf '%s' "$NGINX_API_CONF_TPL" | sudo tee /etc/nginx/templates/api.conf.tpl >/dev/null
sudo sh -c "sed 's/\\${APP_PORT}/${NEW_PORT}/g' /etc/nginx/templates/api.conf.tpl > /etc/nginx/conf.d/api.newsintelligent.site.conf"
sudo nginx -t
sudo systemctl reload nginx
APP_PORT=$ACTIVE_PORT APP_COLOR=$OLD_COLOR \
docker-compose -p app_${OLD_COLOR} -f docker-compose-prod.yml down || true
docker image prune -f