name: Production Server Deploy
on:
workflow_dispatch:
push:
branches: [ "main" ]
permissions:
contents: read
env:
JAR_NAME: vingle-0.0.1-SNAPSHOT.jar
JAR_DIRECTORY: /home/ubuntu/vingle-prod
APPLICATION_PORT_A: 8082
APPLICATION_PORT_B: 8083
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Get token from Submodule Reader
uses: actions/create-github-app-token@v1
id: app_token
with:
app-id: ${{ secrets.SUBMODULE_APP_ID }}
private-key: ${{ secrets.SUBMODULE_APP_PEM }}
owner: ${{ github.repository_owner }}
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
token: ${{ steps.app_token.outputs.token }}
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build
run: |
chmod +x ./gradlew
./gradlew bootjar
- name: Upload Jar
uses: actions/upload-artifact@v4
with:
name: Jar
path: ./build/libs/${{ env.JAR_NAME }}
deploy:
needs: build
runs-on: dev
steps:
- name: Set build DateTime
run: |
echo "BUILD_DATETIME=$(date +'%Y-%m-%d-%H-%M')" >> "$GITHUB_ENV"
- name: Download Jar
uses: actions/download-artifact@v4
with:
name: Jar
- name: Copy jar
shell: bash {0}
run: |
mkdir $JAR_DIRECTORY
cp ./$JAR_NAME $JAR_DIRECTORY/$BUILD_DATETIME-$JAR_NAME
- name: Download Datadog Java Agent
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
wget -O dd-java-agent.jar 'https://dtdg.co/latest-java-tracer'
- name: 현재 사용중인 어플리케이션 포트 확인
shell: bash {0}
run: |
if [ -n "$(lsof -ti:$APPLICATION_PORT_A)" ]; then
echo "BLUE_PORT=$APPLICATION_PORT_A" >> "$GITHUB_ENV"
echo "GREEN_PORT=$APPLICATION_PORT_B" >> "$GITHUB_ENV"
else
echo "BLUE_PORT=$APPLICATION_PORT_B" >> "$GITHUB_ENV"
echo "GREEN_PORT=$APPLICATION_PORT_A" >> "$GITHUB_ENV"
fi
- name: 그린 어플리케이션 실행
env:
RUNNER_TRACKING_ID: ""
shell: bash
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
nohup java -javaagent:dd-java-agent.jar \
-Dspring.profiles.active=prod \
-Dserver.port=$GREEN_PORT \
-Ddd.profiling.enabled=true \
-XX:FlightRecorderOptions=stackdepth=256 \
-Ddd.logs.injection=true \
-Ddd.appsec.enabled=true \
-Ddd.iast.enabled=true \
-Ddd.service=vingle \
-Ddd.env=production \
-jar $BUILD_DATETIME-$JAR_NAME > ~/prod-server.log &
- name: 그린 어플리케이션이 접속 가능할 때까지 기다린다
shell: bash {0}
run: |
PROCESS_ID="$(lsof -i:$GREEN_PORT -t)"
while [ "$(curl -o /dev/null -s -w %{http_code} localhost:$GREEN_PORT/v2/products?zeroBasedPageNumber=0\&pageSize=10)" != 200 ]
do
if [ -n "$PROCESS_ID" ]; then
echo "::error title=배포 실패::블루 어플리케이션으로 롤백합니다.";
exit 1;
fi
echo "새로운 어플리케이션을 띄우는 중입니다.";
sleep 10;
done
- name: 리버스 프록시 설정 변경
shell: bash {0}
working-directory: ${{ env.JAR_DIRECTORY }}
run: |
echo "proxy_pass http://localhost:$GREEN_PORT;" > port.inc;
sudo nginx -s reload;
- name: 블루 어플리케이션 종료
shell: bash {0}
run: |
PROCESS_ID="$(lsof -i:$BLUE_PORT -t)"
if [ -n "$PROCESS_ID" ]; then
sudo kill -15 $PROCESS_ID
echo "구동중인 애플리케이션을 종료했습니다. (pid : $PROCESS_ID)\n"
fi