Ops 404 be fix 검색 시 정렬 기준 변경 (#186) #127
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: Spring CD (Test Server) | |
| on: | |
| push: | |
| branches: | |
| - develop | |
| jobs: | |
| cd-test: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Deploy to Test Environment | |
| uses: appleboy/[email protected] | |
| with: | |
| host: ${{ secrets.TEST_SERVER_HOST }} | |
| username: ec2-user | |
| key: ${{ secrets.SSH_PRIVATE_KEY }} | |
| script: | | |
| # GHCR 로그인 | |
| echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.repository_owner }}" --password-stdin | |
| docker pull ghcr.io/${{ github.repository }}/zoopzoop:latest | |
| NPM_HOST="localhost:81" | |
| NPM_EMAIL="${{ secrets.NPM_ADMIN_EMAIL }}" | |
| NPM_PASSWORD="${{ secrets.NPM_ADMIN_PASSWORD }}" | |
| PROXY_HOST_ID="${{ secrets.NPM_PROXY_HOST_ID }}" | |
| # NPM 토큰 | |
| TOKEN=$(curl -s -X POST "http://${NPM_HOST}/api/tokens" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{\"identity\":\"${NPM_EMAIL}\",\"secret\":\"${NPM_PASSWORD}\"}" | jq -r '.token') | |
| if [ -z "$TOKEN" ] || [ "$TOKEN" == "null" ]; then | |
| echo "❌ Failed to get NPM API token" | |
| exit 1 | |
| fi | |
| CURRENT_CONFIG=$(curl -s -H "Authorization: Bearer $TOKEN" \ | |
| "http://${NPM_HOST}/api/nginx/proxy-hosts/${PROXY_HOST_ID}") | |
| CURRENT_TARGET=$(echo $CURRENT_CONFIG | jq -r '.[0].forward_host // .forward_host') | |
| CURRENT_PORT=$(echo $CURRENT_CONFIG | jq -r '.[0].forward_port // .forward_port') | |
| echo "Current NPM target: $CURRENT_TARGET:$CURRENT_PORT" | |
| if [ "$(docker ps -q -f name=zoopzoop-blue)" ]; then | |
| NEW_CONTAINER=zoopzoop-green | |
| OLD_CONTAINER=zoopzoop-blue | |
| NEW_PORT=8082 | |
| else | |
| NEW_CONTAINER=zoopzoop-blue | |
| OLD_CONTAINER=zoopzoop-green | |
| NEW_PORT=8081 | |
| fi | |
| docker run -d --restart unless-stopped \ | |
| -p $NEW_PORT:8080 \ | |
| --name $NEW_CONTAINER \ | |
| --network common \ | |
| -e SPRING_PROFILES_ACTIVE=server \ | |
| -e SPRING_DATASOURCE_URL="${{secrets.TEST_DB_URL}}" \ | |
| -e SPRING_DATASOURCE_USERNAME="${{secrets.TEST_DB_USERNAME}}" \ | |
| -e SPRING_DATASOURCE_PASSWORD="${{secrets.TEST_DB_PASSWORD}}" \ | |
| -e AWS_S3_BUCKET_NAME="${{secrets.AWS_S3_BUCKET_NAME}}" \ | |
| -e AWS_S3_PREFIX="${{secrets.TEST_AWS_S3_PREFIX}}" \ | |
| -e SPRING_RABBITMQ_HOST="${{secrets.TEST_RABBITMQ_HOST}}" \ | |
| -e SPRING_RABBITMQ_PORT="${{secrets.TEST_RABBITMQ_PORT}}" \ | |
| -e SPRING_RABBITMQ_USERNAME="${{secrets.TEST_RABBITMQ_USERNAME}}" \ | |
| -e SPRING_RABBITMQ_PASSWORD="${{secrets.TEST_RABBITMQ_PASSWORD}}" \ | |
| -e REDIS_HOST="${{secrets.TEST_REDIS_HOST}}" \ | |
| -e REDIS_PASSWORD="${{secrets.TEST_REDIS_PASSWORD}}" \ | |
| -e KAKAO_CLIENT_ID="${{secrets.OAUTH_KAKAO_CLIENT_ID}}" \ | |
| -e GOOGLE_CLIENT_ID="${{secrets.OAUTH_GOOGLE_CLIENT_ID}}" \ | |
| -e GOOGLE_CLIENT_SECRET="${{secrets.OAUTH_GOOGLE_CLIENT_SECRET}}" \ | |
| -e KAKAO_REDIRECT_URI="${{secrets.TEST_OAUTH_KAKAO_REDIRECT_URI}}" \ | |
| -e GOOGLE_REDIRECT_URI="${{secrets.TEST_OAUTH_GOOGLE_REDIRECT_URI}}" \ | |
| -e SENTRY_DSN="${{secrets.SENTRY_DSN}}" \ | |
| -e OPENAI_API_KEY="${{secrets.OPENAI_API_KEY}}" \ | |
| -e LIVEBLOCKS_SECRET_KEY="${{secrets.LIVEBLOCKS_SECRET_KEY}}" \ | |
| -e NAVER_CLIENT_ID="${{secrets.NAVER_CLIENT_ID}}" \ | |
| -e NAVER_CLIENT_SECRET="${{secrets.NAVER_CLIENT_SECRET}}" \ | |
| -e JWT_SECRET_KEY="${{secrets.JWT_SECRET_KEY}}" \ | |
| -e JWT_ACCESS_TOKEN_VALIDITY="${{secrets.JWT_ACCESS_TOKEN_VALIDITY}}" \ | |
| -e JWT_REFRESH_TOKEN_VALIDITY="${{secrets.JWT_REFRESH_TOKEN_VALIDITY}}" \ | |
| -e FRONT_REDIRECT_DOMAIN="${{secrets.TEST_REDIRECT_DOMAIN}}" \ | |
| -e FRONT_MAIN_DOMAIN="${{secrets.MAIN_DOMAIN}}" \ | |
| -e ELASTIC_HOST="${{secrets.TEST_ELASTIC_HOST}}" \ | |
| ghcr.io/${{ github.repository }}/zoopzoop:latest | |
| # 헬스체크 | |
| for i in {1..30}; do | |
| if curl -s http://localhost:$NEW_PORT/actuator/health | grep -q '"status":"UP"'; then | |
| echo "✅ New container is healthy!" | |
| break | |
| else | |
| echo "Waiting for new container to be healthy..." | |
| sleep 5 | |
| fi | |
| if [ $i -eq 30 ]; then | |
| echo "❌ Health check failed. Rolling back..." | |
| docker stop $NEW_CONTAINER || true | |
| docker rm $NEW_CONTAINER || true | |
| exit 1 | |
| fi | |
| done | |
| # NPM 트래픽 스위칭 | |
| DOMAIN_NAME=$(echo $CURRENT_CONFIG | jq -r '.domain_names[0]') | |
| CERT_ID=$(echo "$CURRENT_CONFIG" | jq -r '.certificate_id') | |
| SWITCH_RESPONSE=$(curl -s -w "%{http_code}" -X PUT "http://${NPM_HOST}/api/nginx/proxy-hosts/${PROXY_HOST_ID}" \ | |
| -H "Authorization: Bearer $TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d "{ | |
| \"domain_names\": [\"$DOMAIN_NAME\"], | |
| \"forward_scheme\": \"http\", | |
| \"forward_host\": \"$NEW_CONTAINER\", | |
| \"forward_port\": 8080, | |
| \"caching_enabled\": false, | |
| \"block_exploits\": true, | |
| \"advanced_config\": \"\", | |
| \"locations\": [], | |
| \"certificate_id\": $CERT_ID, | |
| \"ssl_forced\": 1, | |
| \"hsts_enabled\": 1, | |
| \"hsts_subdomains\": 1 | |
| }") | |
| HTTP_CODE=${SWITCH_RESPONSE: -3} | |
| if [ "$HTTP_CODE" -ne 200 ] && [ "$HTTP_CODE" -ne 201 ]; then | |
| echo "❌ Traffic switching failed! HTTP Code: $HTTP_CODE" | |
| echo "Response: ${SWITCH_RESPONSE%???}" | |
| docker stop $NEW_CONTAINER || true | |
| docker rm $NEW_CONTAINER || true | |
| exit 1 | |
| fi | |
| docker stop $OLD_CONTAINER || true | |
| docker rm $OLD_CONTAINER || true |