Skip to content

CD

CD #37

Workflow file for this run

name: CD
on:
workflow_run:
workflows: ["CI"]
types:
- completed
jobs:
deploy:
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest
name: Deploy to EC2 (blue/green)
steps:
- name: Checkout code
uses: actions/checkout@v3
# CD 배포
- name: Deploy to remote EC2 Server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.AWS_EC2_IP }}
username: ${{ secrets.AWS_EC2_USERNAME }}
key: ${{ secrets.AWS_EC2_KEY }}
port: ${{ secrets.AWS_EC2_PORT }}
script: |
cd /home/ubuntu
APP_NAME=${{ secrets.DOCKER_REPO }}
IMAGE=${{ secrets.DOCKER_USERNAME }}/${{secrets.DOCKER_REPO}}
COLOR_FILE=/home/ubuntu/deploy_color
# ν˜„μž¬ 색 / λ‹€μŒ 색/ 포트 κ²°μ •
if [ -f "$COLOR_FILE" ] && [ "$(cat $COLOR_FILE)" = "blue" ]; then
CURRENT_COLOR=blue
NEW_COLOR=green
CURRENT_PORT=8080
NEW_PORT=8081
else
CURRENT_COLOR=green
NEW_COLOR=blue
CURRENT_PORT=8081
NEW_PORT=8080
fi
echo "Current color: $CURRENT_COLOR"
echo "New color: $NEW_COLOR"
docker pull $IMAGE
NEW_CONTAINER_NAME=${APP_NAME}-${NEW_COLOR}
OLD_CONTAINER_NAME=${APP_NAME}-${CURRENT_COLOR}
# μƒˆ μ»¨ν…Œμ΄λ„ˆ μžλ¦¬μ— κΈ°μ‘΄ 게 있으면 정리
if [ "$(docker ps -aq -f name=$NEW_CONTAINER_NAME)" ]; then
docker stop $NEW_CONTAINER_NAME || true
docker rm $NEW_CONTAINER_NAME || true
fi
# μƒˆ μ»¨ν…Œμ΄λ„ˆ λ¨Όμ € μ‹€ν–‰
docker run -d \
--name $NEW_CONTAINER_NAME \
--env SPRING_PROFILES_ACTIVE=prod \
--env JAVA_TOOL_OPTIONS="-Duser.timezone=Asia/Seoul" \
--env 'MYSQL_URL=${{ secrets.MYSQL_URL }}' \
--env MYSQL_USERNAME=${{ secrets.MYSQL_USERNAME }} \
--env MYSQL_PASSWORD=${{ secrets.MYSQL_PASSWORD }} \
--env JWT_SECRET=${{ secrets.JWT_SECRET }} \
--env KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }} \
--env KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }} \
--env KAKAO_REDIRECT_URI=${{ secrets.KAKAO_REDIRECT_URI }} \
--env KAKAO_CLIENT_REDIRECT_URI=${{ secrets.KAKAO_CLIENT_REDIRECT_URI }} \
--env GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }} \
--env GEMINI_MODEL=${{ secrets.GEMINI_MODEL }} \
--env AWS_ACCESS_KEY=${{secrets.AWS_ACCESS_KEY}}\
--env AWS_SECRET_KEY=${{secrets.AWS_SECRET_KEY}}\
--env AWS_REGION=${{secrets.AWS_REGION}}\
--env S3_BUCKET=${{secrets.S3_BUCKET}}\
-p ${NEW_PORT}:8080 \
$IMAGE
HEALTH_PATH="/api/test/jwt"
# μƒˆ μ»¨ν…Œμ΄λ„ˆ μƒνƒœ 확인
echo "Health check for new container..."
for i in {1..20}; do
sleep 5
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${NEW_PORT}${HEALTH_PATH}" || echo "000")
echo "Health check status: $STATUS_CODE"
if [ "$STATUS_CODE" = "200" ]; then
echo "New version is healthy!"
break
fi
if [ "$i" -eq 20 ]; then
echo "New version did not become healthy in time. Aborting."
docker logs $NEW_CONTAINER_NAME || true
exit 1
fi
done
# 캐디 포트 μ „ν™˜
echo "Switching traffic to new container..."
sudo sed -i "s/reverse_proxy localhost:[0-9]\\+/reverse_proxy localhost:${NEW_PORT}/" /etc/caddy/Caddyfile
sudo systemctl reload caddy
if [ "$(docker ps -q -f name=$OLD_CONTAINER_NAME)" ]; then
echo "Stopping old container..."
docker stop $OLD_CONTAINER_NAME || true
docker rm $OLD_CONTAINER_NAME || true
fi
docker image prune -f
echo $NEW_COLOR > $COLOR_FILE