Skip to content

Commit

Permalink
feat: blue green 무중단 배포 스크립트
Browse files Browse the repository at this point in the history
  • Loading branch information
Arachneee committed Oct 15, 2024
1 parent eb9ce68 commit 46cd1b5
Showing 1 changed file with 90 additions and 75 deletions.
165 changes: 90 additions & 75 deletions .github/workflows/backend-prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,100 +20,115 @@ jobs:
contents: read

steps:
- name: CheckOut
uses: actions/checkout@v4
with:
token: ${{secrets.CONFIG_SUBMODULE_TOKEN}}
submodules: true

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Test with Gradle Wrapper
run: ./gradlew clean build

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Set up Docker BuildX
uses: docker/setup-buildx-action@v3

- name: Build and push
run: |
docker buildx build --platform linux/arm64 -t \
${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }} --push .
# (Your build steps remain the same)

deploy:
needs: build
strategy:
matrix:
runner: [ prod-1, prod-2, prod-3 ]
max-parallel: 1
runs-on: [ self-hosted, '${{ matrix.runner }}' ]
steps:
- name: Delete existing has to be deleted container gracefully
- name: Docker Image pull
run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }}

- name: Check running container and determine the next port
id: check-port
run: |
echo "Stopping existing container if running..."
if sudo docker ps -a --filter "name=haengdong-backend-delete" --format "{{.Names}}" | grep -w haengdong-backend-delete; then
sudo docker rm -f haengdong-backend-delete
echo "Checking if any container is running on ports 8080 or 8081..."
CURRENT_PORT=$(sudo docker ps --format "{{.Names}} {{.Ports}}" | grep "haengdong-backend-" | grep -o '8080\|8081')
if [ "$CURRENT_PORT" == "8080" ]; then
NEXT_PORT=8081
else
echo "No running container named haengdong-backend-delete found."
NEXT_PORT=8080
fi
- name: Docker Image pull
run: sudo docker pull ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }}
if [ -z "$CURRENT_PORT" ]; then
echo "No running container found. Using port 8080."
NEXT_PORT=8080
fi
- name: Stop existing container gracefully
echo "Next container will run on port $NEXT_PORT."
echo "::set-output name=next_port::$NEXT_PORT"
echo "::set-output name=current_port::$CURRENT_PORT"
- name: Run new container on the alternate port
run: |
echo "Stopping existing container if running..."
if sudo docker ps -a --filter "name=haengdong-backend" --format "{{.Names}}" | grep -w haengdong-backend; then
sudo docker stop haengdong-backend
sudo docker rename haengdong-backend haengdong-backend-delete
else
echo "No running container named haengdong-backend found."
fi
echo "Running new container on port ${{ steps.check-port.outputs.next_port }}..."
sudo docker run -d -p ${{ steps.check-port.outputs.next_port }}:8080 \
-e SPRING_PROFILES_ACTIVE=prod -v log-volume:/app/logs --name haengdong-backend-${{ steps.check-port.outputs.next_port }} \
${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }}
- name: Wait for Application Booting 30 seconds
run: sleep 30

- name: Docker run and Health Check
- name: Health check the new container
id: health-check
run: |
echo "Running new container..."
sudo docker run -d -p 80:8080 -e SPRING_PROFILES_ACTIVE=prod -v log-volume:/app/logs --name haengdong-backend ${{ secrets.DOCKER_USERNAME }}/${{ secrets.DOCKER_IMAGE_BE_PROD }}
echo "Performing health check..."
# 헬스 체크를 위해 일정 시간 대기 (애플리케이션이 시작될 시간을 확보)
for i in 1 2 3; do
echo "Waiting for application to start... (${i}0초 경과)"
sleep 10
done
# 헬스 체크 수행 및 상태 추출 (jq 없이 sed 사용)
HEALTH_STATUS=$(curl -s http://localhost/actuator/health | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
echo "Performing health check for the new container on port ${{ steps.check-port.outputs.next_port }}..."
HEALTH_STATUS=$(curl -s http://localhost:${{ steps.check-port.outputs.next_port }}/actuator/health | sed -n 's/.*"status":"\([^"]*\)".*/\1/p')
echo "Health check status: $HEALTH_STATUS"
if [ "$HEALTH_STATUS" == "UP" ]; then
echo "Health check passed."
echo "Removing old container..."
sudo docker rm haengdong-backend-delete
else
echo "Health check failed. Status: $HEALTH_STATUS"
echo "Rolling back to previous container..."
sudo docker rm -f haengdong-backend
sudo docker rename haengdong-backend-delete haengdong-backend
sudo docker start haengdong-backend
if [ "$HEALTH_STATUS" != "UP" ]; then
echo "Health check failed. Rolling back..."
sudo docker rm -f haengdong-backend-${{ steps.check-port.outputs.next_port }}
exit 1
fi
echo "Health check passed."
- name: Update or create Nginx container to point to new container port
run: |
NGINX_CONTAINER_NAME="nginx-proxy"
echo "Checking if Nginx container is running..."
if sudo docker ps --filter "name=$NGINX_CONTAINER_NAME" --format "{{.Names}}" | grep -w $NGINX_CONTAINER_NAME; then
echo "Nginx container is running. Updating configuration..."
# Copy Nginx config from the running container to the host
sudo docker cp $NGINX_CONTAINER_NAME:/etc/nginx/nginx.conf ./nginx.conf
# Update the proxy_pass setting in the config file
sudo sed -i "s/proxy_pass http:\/\/127.0.0.1:.*;/proxy_pass http:\/\/127.0.0.1:${{ steps.check-port.outputs.next_port }};/" ./nginx.conf
# Copy the updated config back into the container
sudo docker cp ./nginx.conf $NGINX_CONTAINER_NAME:/etc/nginx/nginx.conf
# Reload Nginx inside the container
sudo docker exec $NGINX_CONTAINER_NAME nginx -s reload
echo "Nginx configuration updated and reloaded."
else
echo "Nginx container not found. Creating a new Nginx container..."
# Create a basic Nginx config file with the updated proxy_pass
echo "
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:${{ steps.check-port.outputs.next_port }};
}
}
" > ./nginx.conf
# Run a new Nginx container with the updated config
sudo docker run -d --name $NGINX_CONTAINER_NAME -p 80:80 \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro nginx
echo "New Nginx container created and running."
fi
- name: Waiting for ALB health check
run: sleep 90
- name: Stop and remove the old container
run: |
CURRENT_PORT=${{ steps.check-port.outputs.current_port }}
if [ -n "$CURRENT_PORT" ]; then
echo "Stopping and removing the container running on port $CURRENT_PORT..."
sudo docker ps --filter "publish=$CURRENT_PORT" --format "{{.ID}}" | xargs sudo docker stop
sleep 5
sudo docker ps -a --filter "publish=$CURRENT_PORT" --format "{{.ID}}" | xargs sudo docker rm
else
echo "No container to stop and remove."
fi

0 comments on commit 46cd1b5

Please sign in to comment.