Skip to content

feat: blue green 무중단 배포 스크립트 #24

feat: blue green 무중단 배포 스크립트

feat: blue green 무중단 배포 스크립트 #24

Workflow file for this run

name: backend-push
on:
push:
branches: [ "main", "feature/#745" ]
paths:
- 'server/**'
- '.github/workflows/**'
jobs:
# build:
# runs-on: ubuntu-latest
#
# defaults:
# run:
# shell: bash
# working-directory: ./server
#
# permissions:
# 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 .
deploy:
# needs: build
strategy:
matrix:
runner: [ prod-1 ] #, prod-2, prod-3 ]
runs-on: [ self-hosted, '${{ matrix.runner }}' ]
steps:
- 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 "Checking if any container is running on ports 8080 or 8081..."
CURRENT_PORT=$(sudo docker ps --format "{{.Names}} {{.Ports}}" | grep "***-backend" | grep -o '8080\|8081' || echo "")
# CURRENT_PORT가 빈 문자열이거나 8081인 경우
if [ -z "$CURRENT_PORT" ] || [ "$CURRENT_PORT" == "8081" ]; then
NEXT_PORT=8080
else
NEXT_PORT=8081
fi
echo "Next container will run on port $NEXT_PORT."
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 "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: |
echo "Waiting for the application to boot..."
for ((i=1;i<=30;i++)); do
echo -n "."
sleep 1
done
echo # 줄바꿈
- name: Health check the new container
id: health-check
run: |
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 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 exists..."
if sudo docker ps -a --filter "name=$NGINX_CONTAINER_NAME" --format "{{.Names}}" | grep -w $NGINX_CONTAINER_NAME; then
# Check if the 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."
else
echo "Nginx container exists but is not running. Starting Nginx container..."
sudo docker start $NGINX_CONTAINER_NAME
echo "Nginx container started."
fi
# Ensure nginx-conf directory and default.conf file exist
mkdir -p ./nginx-conf
if [ ! -f ./nginx-conf/default.conf ]; then
echo "Creating default.conf file..."
echo "
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:${{ steps.check-port.outputs.next_port }};
}
}
" > ./nginx-conf/default.conf
fi
# Update Nginx configuration file on host
echo "Updating Nginx configuration file on host..."
echo "
server {
listen 80;
location / {
proxy_pass http://127.0.0.1:${{ steps.check-port.outputs.next_port }};
}
}
" > ./nginx-conf/default.conf
# Test Nginx configuration inside a temporary container
echo "Testing Nginx configuration..."
sudo docker run --rm -v $(pwd)/nginx-conf:/etc/nginx/conf.d:ro nginx nginx -t
if [ $? -eq 0 ]; then
echo "Nginx configuration test passed."
else
echo "Nginx configuration test failed. Please check the configuration file."
exit 1
fi
# Restart the Nginx container to apply changes
echo "Restarting Nginx container..."
sudo docker restart $NGINX_CONTAINER_NAME
echo "Nginx container restarted."
else
echo "Nginx container not found. Creating a new Nginx container..."
# Create Nginx configuration directory
mkdir -p ./nginx-conf
# 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/default.conf
# Test Nginx configuration inside a temporary container
echo "Testing Nginx configuration..."
sudo docker run --rm -v $(pwd)/nginx-conf:/etc/nginx/conf.d:ro nginx nginx -t
if [ $? -eq 0 ]; then
echo "Nginx configuration test passed."
else
echo "Nginx configuration test failed. Please check the configuration file."
exit 1
fi
# 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/conf.d:ro nginx
echo "New Nginx container created and running."
fi
- 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