From 8594411db3650238ef1bb312402a7df1ac706db7 Mon Sep 17 00:00:00 2001 From: Yoonseo Han Date: Tue, 21 Jan 2025 22:05:35 +0900 Subject: [PATCH] =?UTF-8?q?env:=20=EB=A1=9C=EC=BB=AC=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=8F=84=EC=BB=A4=20=ED=99=98=EA=B2=BD=20=EA=B5=AC=EC=84=B1?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=85=8B=EC=97=85=20=EC=A7=84?= =?UTF-8?q?=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/docker-image.yml | 8 +- .github/workflows/scripts/backend-deploy.sh | 114 +++++++++++++++++++ .github/workflows/scripts/deploy.sh | 91 --------------- .github/workflows/scripts/frontend-deploy.sh | 58 ++++++++++ .gitignore | 2 + docker-compose-blue.yml | 21 ++++ docker-compose-green.yml | 21 ++++ docker-compose-nginx.yml | 17 +++ nginx/Dockerfile | 26 ++++- nginx/conf.d/default.conf | 12 +- 10 files changed, 268 insertions(+), 102 deletions(-) create mode 100755 .github/workflows/scripts/backend-deploy.sh delete mode 100644 .github/workflows/scripts/deploy.sh create mode 100755 .github/workflows/scripts/frontend-deploy.sh create mode 100644 docker-compose-blue.yml create mode 100644 docker-compose-green.yml create mode 100644 docker-compose-nginx.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 5bb8bb0..b420bd9 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -2,7 +2,7 @@ name: Docker Image CD on: push: - branches: [ 'dev' ] + branches: ['dev'] jobs: build: @@ -34,10 +34,10 @@ jobs: - name: Check file changes run: | - + CLIENT_FILE_CHANGED=$(git diff --quiet ${{ github.event.before }} HEAD client && echo 'false' || echo 'true') SERVER_FILE_CHANGED=$(git diff --quiet ${{ github.event.before }} HEAD server && echo 'false' || echo 'true') - + if [ "$CLIENT_FILE_CHANGED" == 'false' ] && [ "$SERVER_FILE_CHANGED" == 'false' ]; then echo "CLIENT_FILE_CHANGED=true" > $GITHUB_ENV echo "SERVER_FILE_CHANGED=true" >> $GITHUB_ENV @@ -53,7 +53,7 @@ jobs: docker build -f server/Dockerfile -t ${{ secrets.DOCKER_USERNAME }}/inear-server:${{ github.sha }} ./ docker tag ${{ secrets.DOCKER_USERNAME }}/inear-server:${{ github.sha }} ${{ secrets.DOCKER_USERNAME }}/inear-server:latest fi - + # 서버 이미지 푸시 (Docker Hub 또는 다른 레지스트리) - name: Push server image to Docker Hub run: | diff --git a/.github/workflows/scripts/backend-deploy.sh b/.github/workflows/scripts/backend-deploy.sh new file mode 100755 index 0000000..0aa0c55 --- /dev/null +++ b/.github/workflows/scripts/backend-deploy.sh @@ -0,0 +1,114 @@ +#!/bin/bash + +# healthy 상태 대기 +waiting() { + while true; do + health_status_server=$(docker inspect --format '{{.State.Health.Status}}' server-$1) + + if [ "$health_status_server" != "starting" ]; then + echo "$health_status_server" + return 0 + fi + + sleep 5 + done +} + +# nginx 설정 업데이트 및 리로드 함수 +update_and_reload_nginx() { + local target=$1 + NGINX_CONFIG="nginx/conf.d/default.conf" + + BACK_END_BLUE="server-blue:3000" + BACK_END_GREEN="server-green:3000" + echo "Updating nginx configuration for $target environment..." + + # 파일 업데이트 + echo $target + # 리눅스 방식 + # if [ "$target" == "green" ]; then + # docker exec nginx sh -c "sed -i 's|server server-.*;|server $BACK_END_GREEN;|g' /etc/nginx/conf.d/default.conf" + # else + # docker exec nginx sh -c "sed -i 's|server server-.*;|server $BACK_END_BLUE;|g' /etc/nginx/conf.d/default.conf" + # fi + + if [ "$target" == "green" ]; then + # MacOS 방식 + sed -i '' "s|server server-.*;|server $BACK_END_GREEN;|g" "$NGINX_CONFIG" + else + sed -i '' "s|server server-.*;|server $BACK_END_BLUE;|g" "$NGINX_CONFIG" + fi + + # nginx 컨테이너 재시작 + echo "Restarting nginx to apply new configuration..." + docker exec nginx nginx -s reload + + # 설정이 제대로 적용되었는지 확인 + sleep 2 + docker exec nginx nginx -t +} + +# Blue에서 Green으로 전환 +switch_to_green() { + echo "Deploying Green environment..." + + cd ../../../ + + # Green 환경 시작 + docker compose -f docker-compose-green.yml up -d + + health_status_server=$(waiting "green") + echo $health_status_server + if [ "$health_status_server" == "healthy" ]; then + echo "Green server is healthy. Stopping and removing..." + # nginx 설정 업데이트 및 리로드 + update_and_reload_nginx "green" + + echo "Stopping Blue server..." + if docker ps -q --filter name=server-blue > /dev/null; then + docker stop server-blue + docker rm server-blue + fi + else + echo "Green server is not Healthy" + docker stop server-green + docker rm server-green + fi +} +# Green에서 Blue로 전환 +switch_to_blue() { + echo "Deploying Blue environment..." + + cd ../../../ + + # Blue 환경 시작 + docker compose -f docker-compose-blue.yml up -d + + health_status_server=$(waiting "blue") + echo $health_status_server + if [ "$health_status_server" == "healthy" ]; then + echo "Blue server is healthy. Stopping and removing..." + + # nginx 설정 업데이트 및 리로드 + update_and_reload_nginx "blue" + + echo "Stopping Green server..." + if docker ps -q --filter name=server-green > /dev/null; then + docker stop server-green + docker rm server-green + fi + else + echo "Blue server is not Healthy" + docker stop server-blue + docker rm server-blue + fi +} + +# 현재 실행 중인 환경 확인 및 전환 +if [ -n "$(docker ps -q --filter name=blue)" ]; then + switch_to_green + echo "switch_to_green 실행" +else + switch_to_blue + echo "switch_to_blue 실행" +fi \ No newline at end of file diff --git a/.github/workflows/scripts/deploy.sh b/.github/workflows/scripts/deploy.sh deleted file mode 100644 index 0caf87b..0000000 --- a/.github/workflows/scripts/deploy.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash - -# nginx 설정 업데이트 및 리로드 함수 -update_and_reload_nginx() { - local target=$1 - echo "Updating nginx configuration for $target environment..." - - # 임시 설정 파일 생성 - cat > nginx/conf.d/default.conf << EOF -upstream backend { - server server-$target:3000; -} - -server { - listen 80; - server_name localhost; - - location / { - proxy_pass http://client:5173; - proxy_http_version 1.1; - proxy_set_header Upgrade \$http_upgrade; - proxy_set_header Connection 'upgrade'; - proxy_set_header Host \$host; - } - - location /api { - proxy_pass http://backend; - proxy_http_version 1.1; - proxy_set_header Host \$host; - proxy_set_header Upgrade \$http_upgrade; - proxy_set_header Connection 'upgrade'; - } -} -EOF - - # nginx 컨테이너 재시작 - echo "Restarting nginx to apply new configuration..." - docker restart nginx - - # 설정이 제대로 적용되었는지 확인 - sleep 2 - docker exec nginx nginx -t -} - -# Blue에서 Green으로 전환 -switch_to_green() { - echo "Deploying Green environment..." - - cd - cd web18-inear - - # Green 환경 시작 - docker compose -f docker-compose-green.yml up -d - - # nginx 설정 업데이트 및 리로드 - update_and_reload_nginx "green" - - echo "Stopping Blue server..." - if docker ps -q --filter name=server-blue > /dev/null; then - docker compose -f docker-compose-blue.yml stop server-blue - docker compose -f docker-compose-blue.yml rm -f server-blue - fi -} -# Green에서 Blue로 전환 -switch_to_blue() { - echo "Deploying Blue environment..." - - cd - cd web18-inear - - # Blue 환경 시작 - docker compose -f docker-compose-blue.yml up -d - - # nginx 설정 업데이트 및 리로드 - update_and_reload_nginx "blue" - - echo "Stopping Green server..." - if docker ps -q --filter name=server-green > /dev/null; then - docker compose -f docker-compose-green.yml stop server-green - docker compose -f docker-compose-green.yml rm -f server-green - fi -} - -# 현재 실행 중인 환경 확인 및 전환 -if [ -n "$(docker ps -q --filter name=blue)" ]; then - switch_to_green - echo "switch_to_green 실행" -else - switch_to_blue - echo "switch_to_blue 실행" -fi \ No newline at end of file diff --git a/.github/workflows/scripts/frontend-deploy.sh b/.github/workflows/scripts/frontend-deploy.sh new file mode 100755 index 0000000..834c755 --- /dev/null +++ b/.github/workflows/scripts/frontend-deploy.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +NGINX_CONFIG="nginx/conf.d/default.conf" + +# nginx 설정 업데이트 및 리로드 함수 +update_and_reload_nginx() { + local target=$1 + + echo "Updating nginx configuration for $target environment..." + + # 파일 업데이트 + echo $target + if [ "$target" == "green" ]; then + rm -rf nginx/html/dist-green + cp -r nginx/html/dist nginx/html/dist-green + sed -i "s|root /usr/share/nginx/html.*;|root /usr/share/nginx/html/dist-green;|g" $NGINX_CONFIG + else + rm -rf nginx/html/dist-blue + cp -r nginx/html/dist nginx/html/dist-blue + sed -i "s|root /usr/share/nginx/html.*;|root /usr/share/nginx/html/dist-blue;|g" $NGINX_CONFIG + fi + + # nginx 컨테이너 재시작 + echo "Restarting nginx to apply new configuration..." + docker exec nginx nginx -s reload + + # 설정이 제대로 적용되었는지 확인 + sleep 2 + docker exec nginx nginx -t +} + +# Blue에서 Green으로 전환 +switch_to_green() { + echo "Deploying Green environment..." + + cd ../../../ + # nginx 설정 업데이트 및 리로드 + update_and_reload_nginx "green" + +} +# Green에서 Blue로 전환 +switch_to_blue() { + echo "Deploying Blue environment..." + + cd ../../../ + + # nginx 설정 업데이트 및 리로드 + update_and_reload_nginx "blue" +} + +# 현재 실행 중인 환경 확인 및 전환 +if [ -n "$(cat $NGINX_CONFIG | grep html/dist-blue)" ]; then + switch_to_green + echo "switch_to_green 실행" +else + switch_to_blue + echo "switch_to_blue 실행" +fi \ No newline at end of file diff --git a/.gitignore b/.gitignore index cde57ce..b89ff48 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ yarn-error.log* lerna-debug.log* .pnpm-debug.log* +env + # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/docker-compose-blue.yml b/docker-compose-blue.yml new file mode 100644 index 0000000..b656127 --- /dev/null +++ b/docker-compose-blue.yml @@ -0,0 +1,21 @@ +networks: + webapp: + external: true + +services: + server-blue: + image: "inear-server:latest" + container_name: server-blue + env_file: + - ./env/server.env + environment: + - NODE_ENV=development + - TZ=Asia/Seoul + networks: + - webapp + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "wget -q --spider http://server-blue:3000/api/health || exit 1"] + interval: 7s + timeout: 10s + retries: 5 \ No newline at end of file diff --git a/docker-compose-green.yml b/docker-compose-green.yml new file mode 100644 index 0000000..3f871e6 --- /dev/null +++ b/docker-compose-green.yml @@ -0,0 +1,21 @@ +networks: + webapp: + external: true + +services: + server-green: + image: "inear-server:latest" + container_name: server-green + env_file: + - ./env/server.env + environment: + - NODE_ENV=development + - TZ=Asia/Seoul + networks: + - webapp + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "wget -q --spider http://server-green:3000/api/health || exit 1"] + interval: 7s + timeout: 10s + retries: 5 diff --git a/docker-compose-nginx.yml b/docker-compose-nginx.yml new file mode 100644 index 0000000..2ca1c94 --- /dev/null +++ b/docker-compose-nginx.yml @@ -0,0 +1,17 @@ +networks: + webapp: + name: webapp + +services: + nginx: + image: "inear-nginx:latest" + container_name: nginx + env_file: + - ./env/client.env + volumes: + - ./nginx/conf.d:/etc/nginx/conf.d:ro + ports: + - '80:80' + networks: + - webapp + restart: unless-stopped \ No newline at end of file diff --git a/nginx/Dockerfile b/nginx/Dockerfile index 55934d2..1ffd189 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -1,3 +1,27 @@ +# Build stage +FROM node:22-alpine AS builder + +WORKDIR /app + +COPY package.json yarn.lock .yarnrc.yml ./ +COPY .yarn .yarn +COPY client/ client/ + +RUN corepack enable && \ + yarn install + +WORKDIR /app/client +RUN yarn build + +# Production stage FROM nginx:alpine -COPY nginx/nginx.conf /etc/nginx/nginx.conf \ No newline at end of file +COPY nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +COPY --from=builder /app/client/dist /usr/share/nginx/html/dist +COPY --from=builder /app/client/dist /usr/share/nginx/html/dist-blue +COPY --from=builder /app/client/dist /usr/share/nginx/html/dist-green + +RUN sed -i "s|root /usr/share/nginx/html.*;|root /usr/share/nginx/html/dist-blue;|g" /etc/nginx/conf.d/default.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx/conf.d/default.conf b/nginx/conf.d/default.conf index d77d681..6ecc96c 100644 --- a/nginx/conf.d/default.conf +++ b/nginx/conf.d/default.conf @@ -1,8 +1,5 @@ -upstream frontend { - server client:5173; -} upstream backend { - server server:3000; + server server-green:3000; } server { @@ -13,10 +10,13 @@ server { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; - client_max_body_size 100M; + + client_max_body_size 200M; location / { - proxy_pass http://frontend; + root /usr/share/nginx/html/dist-blue; + index index.html index.htm; + try_files $uri $uri/ /index.html; } location /api {