feat : login redirect url 변경 #80
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Deploy Spring Boot Application | |
on: | |
push: | |
branches: [ develop ] | |
env: | |
PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} | |
GCR_REGION: asia.gcr.io | |
DOCKER_IMAGE: asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/spring-app | |
VERSION: ${{ github.sha }} | |
BLUE_PORT: 8081 | |
GREEN_PORT: 8082 | |
jobs: | |
build: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v2 | |
- name: Set up JDK 17 | |
uses: actions/setup-java@v2 | |
with: | |
java-version: '17' | |
distribution: 'adopt' | |
- name: Authenticate to Google Cloud | |
uses: google-github-actions/auth@v1 | |
with: | |
credentials_json: ${{ secrets.GCP_SA_KEY }} | |
- name: Setup Google Cloud CLI | |
uses: google-github-actions/setup-gcloud@v1 | |
with: | |
service_account_key: ${{ secrets.GCP_SA_KEY }} | |
project_id: ${{ secrets.GCP_PROJECT_ID }} | |
export_default_credentials: true | |
- name: Configure Docker | |
run: | | |
gcloud auth configure-docker asia.gcr.io --quiet | |
- name: Build with Gradle | |
run: ./gradlew build -x test | |
- name: Docker build & push | |
run: | | |
docker build -t ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }} . | |
docker push ${{ env.DOCKER_IMAGE }}:${{ env.VERSION }} | |
deploy: | |
needs: build | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v2 | |
- name: Copy configuration files | |
uses: appleboy/[email protected] | |
with: | |
host: ${{ secrets.HOST }} | |
username: ${{ secrets.USERNAME }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
source: "docker-compose.yml,nginx/" | |
target: "/home/${{ secrets.USERNAME }}/app" | |
debug: 'true' | |
- name: Deploy | |
uses: appleboy/ssh-action@master | |
with: | |
host: ${{ secrets.HOST }} | |
username: ${{ secrets.USERNAME }} | |
key: ${{ secrets.SSH_PRIVATE_KEY }} | |
script: | | |
cd /home/${{ secrets.USERNAME }}/app | |
# Docker 권한 설정 | |
sudo usermod -aG docker $USER | |
sudo chmod 666 /var/run/docker.sock | |
# GCP 인증 | |
echo '${{ secrets.GCP_SA_KEY }}' > /tmp/gcp-key.json | |
cat /tmp/gcp-key.json | docker login -u _json_key --password-stdin asia.gcr.io | |
# 현재 실행 중인 컨테이너의 포트 확인 | |
RUNNING_PORT=$(docker ps --filter name=spring-app --format '{{.Ports}}' | grep -oP '0.0.0.0:\K\d+' || echo "") | |
# 새로 배포할 포트 결정 | |
if [ "$RUNNING_PORT" = "${{ env.BLUE_PORT }}" ]; then | |
TARGET_PORT=${{ env.GREEN_PORT }} | |
COLOR="green" | |
else | |
TARGET_PORT=${{ env.BLUE_PORT }} | |
COLOR="blue" | |
fi | |
OLD_COLOR=$([ "$COLOR" = "blue" ] && echo "green" || echo "blue") | |
echo "Current running port: $RUNNING_PORT" | |
echo "Target deployment port: $TARGET_PORT" | |
echo "Deploying to $COLOR environment" | |
# 기존 .env 파일 삭제 및 새로 생성 | |
rm -f .env | |
cat << EOF > .env | |
SPRING_PROFILES_ACTIVE=${{ secrets.SPRING_PROFILES_ACTIVE }} | |
DATABASE_IP=${{ secrets.DATABASE_IP }} | |
DATABASE_NAME=${{ secrets.DATABASE_NAME }} | |
DATABASE_USER=${{ secrets.DATABASE_USER }} | |
DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }} | |
GH_CLIENT_ID=${{ secrets.GH_CLIENT_ID }} | |
GH_CLIENT_SECRET=${{ secrets.GH_CLIENT_SECRET }} | |
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }} | |
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }} | |
JWT_SECRET=${{ secrets.JWT_SECRET }} | |
KAKAO_CLIENT_ID=${{ secrets.KAKAO_CLIENT_ID }} | |
KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }} | |
BACKEND_URL=${{ secrets.BACKEND_URL }} | |
REDIS_HOST=${{ secrets.REDIS_HOST }} | |
GCP_CDN_DOMAIN=${{ secrets.GCP_CDN_DOMAIN }} | |
GCS_KEY=${{ secrets.GCS_KEY }} | |
GCP_PROJECT_ID=${{ secrets.GCP_PROJECT_ID }} | |
BUCKET_NAME=${{ secrets.BUCKET_NAME }} | |
DOCKER_IMAGE=${{ env.DOCKER_IMAGE }} | |
VERSION=${{ env.VERSION }} | |
BLUE_PORT=${{ env.BLUE_PORT }} | |
GREEN_PORT=${{ env.GREEN_PORT }} | |
USERNAME=${{ secrets.USERNAME }} | |
ES_HOST=${{ secrets.ES_HOST }} | |
EOF | |
# JWT_SECRET에서 백슬래시 제거 | |
sed -i '/^JWT_SECRET=/ s/\\//g' .env | |
sed -i '/^GCS_KEY=/ s/\\//g' .env | |
# 기존 컨테이너 정리 (동일한 색상의 컨테이너만) | |
docker ps -aq --filter name=spring-app-${COLOR} | xargs -r docker rm -f | |
# 새 버전 배포 | |
echo "Deploying new version..." | |
docker-compose pull | |
TARGET_PORT=$TARGET_PORT COLOR=$COLOR docker-compose -f docker-compose.yml up -d spring-app-${COLOR} | |
# 헬스체크 | |
echo "Performing health check..." | |
HEALTH_CHECK_PASSED=false | |
for i in {1..30}; do | |
echo "Health check attempt $i of 30..." | |
if curl -s http://localhost:${TARGET_PORT}/actuator/health | grep -q "UP"; then | |
HEALTH_CHECK_PASSED=true | |
echo "Health check passed" | |
break | |
fi | |
sleep 3 | |
done | |
if [ "$HEALTH_CHECK_PASSED" = true ]; then | |
echo "Deployment successful. Updating Nginx configuration..." | |
# (2) Nginx 설정 업데이트 로직 수정 | |
NGINX_HOME="/home/${{ secrets.USERNAME }}/app/nginx" | |
# default.conf 제거 | |
rm -f ${NGINX_HOME}/conf.d/default.conf | |
# 새 active conf => default.conf | |
cp ${NGINX_HOME}/config/${COLOR}.conf ${NGINX_HOME}/conf.d/default.conf | |
# Nginx 재시작 (이미 컨테이너가 있으면 up -d 하면 recreate or no changes) | |
docker-compose up -d nginx | |
# Nginx 설정 테스트 | |
if docker exec nginx nginx -t; then | |
docker exec nginx nginx -s reload | |
echo "Nginx configuration updated successfully" | |
# 이전 버전 종료 | |
if [ ! -z "$RUNNING_PORT" ]; then | |
echo "Stopping old $OLD_COLOR deployment on port $RUNNING_PORT" | |
docker ps -aq --filter name=spring-app-${OLD_COLOR} | xargs -r docker rm -f | |
fi | |
# 배포 성공 후 사용하지 않는 Docker 이미지 삭제 | |
echo "Cleaning up unused Docker images..." | |
# 사용되지 않는 이미지를 삭제 (dangling 이미지) | |
docker image prune -f | |
# 이전 버전 이미지 삭제 | |
docker images --format '{{.Repository}}:{{.Tag}} {{.ID}}' | grep "${{ env.DOCKER_IMAGE }}" | awk '{print $2}' | while read -r IMAGE_ID; do | |
if [ "$IMAGE_ID" != "${{ env.VERSION }}" ]; then | |
echo "Removing old Docker image: $IMAGE_ID" | |
docker rmi -f "$IMAGE_ID" || echo "Failed to remove image $IMAGE_ID" | |
fi | |
done | |
echo "Docker image cleanup completed." | |
rm -f /tmp/gcp-key.json | |
echo "Deployment completed successfully" | |
exit 0 | |
else | |
echo "Nginx configuration test failed. Rolling back..." | |
# 롤백: 다시 old_color로 default.conf 복구 | |
rm -f ${NGINX_HOME}/conf.d/default.conf | |
cp ${NGINX_HOME}/config/${OLD_COLOR}.conf ${NGINX_HOME}/conf.d/default.conf | |
docker-compose up -d nginx | |
docker exec nginx nginx -s reload | |
# 신규 버전 종료 | |
docker ps -aq --filter name=spring-app-${COLOR} | xargs -r docker rm -f | |
rm -f /tmp/gcp-key.json | |
echo "Deployment failed" | |
exit 1 | |
fi | |
else | |
echo "Health check failed. Rolling back..." | |
docker ps -aq --filter name=spring-app-${COLOR} | xargs -r docker rm -f | |
rm -f /tmp/gcp-key.json | |
echo "Deployment failed" | |
exit 1 | |
fi |