From 078eb4a9bf17ceaab8aca26a9546911595f0eccc Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 22:18:06 +0900 Subject: [PATCH 01/14] =?UTF-8?q?feat:=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=EC=84=9C=EB=B2=84=20=EB=B0=B0=ED=8F=AC=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/deploy.sh | 109 ++++++++++++++++++++++++++++++ deploy/prod/scripts/rollback.sh | 116 ++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+) create mode 100755 deploy/prod/scripts/deploy.sh create mode 100755 deploy/prod/scripts/rollback.sh diff --git a/deploy/prod/scripts/deploy.sh b/deploy/prod/scripts/deploy.sh new file mode 100755 index 00000000..c62175b5 --- /dev/null +++ b/deploy/prod/scripts/deploy.sh @@ -0,0 +1,109 @@ +#!/bin/bash +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +REGISTRY="asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api" +WORK_DIR="/home/kgb581818/souzip" +DEPLOY_DIR="$WORK_DIR/deploy/prod" + +BLUE_COMPOSE="docker-compose.blue.yaml" +GREEN_COMPOSE="docker-compose.green.yaml" + +NGINX_UPSTREAM_FILE="/etc/nginx/conf.d/upstream-souzip.conf" + +BLUE_PORT=8081 +GREEN_PORT=8082 + +MAX_RETRY=6 +RETRY_INTERVAL=10 + +cd "$WORK_DIR" || exit 1 + +echo -e "${YELLOW}[1/7] 최신 이미지 다운로드${NC}" +docker pull ${REGISTRY}:latest +NEW_IMAGE=$(docker images ${REGISTRY}:latest -q) + +if [ -z "${NEW_IMAGE:-}" ]; then + echo -e "${RED}[ERROR] 이미지 다운로드 실패${NC}" + exit 1 +fi + +echo -e "${GREEN}[SUCCESS] 새 이미지: ${NEW_IMAGE}${NC}" + +cd "$DEPLOY_DIR" || exit 1 + +[ -f "$NGINX_UPSTREAM_FILE" ] || { echo -e "${RED}[ERROR] upstream 파일 없음${NC}"; exit 1; } + +echo -e "${YELLOW}[2/7] 현재 active 포트 확인${NC}" + +CURRENT_PORT=$(grep -oE 'server[[:space:]]+127\.0\.0\.1:([0-9]+)' "$NGINX_UPSTREAM_FILE" | grep -oE '[0-9]+' | head -n 1 || true) + +if [ "$CURRENT_PORT" == "$BLUE_PORT" ]; then + TARGET="green" + TARGET_PORT=$GREEN_PORT + STOP="blue" + COMPOSE_FILE=$GREEN_COMPOSE +else + TARGET="blue" + TARGET_PORT=$BLUE_PORT + STOP="green" + COMPOSE_FILE=$BLUE_COMPOSE +fi + +echo -e "${GREEN}[INFO] 현재:$CURRENT_PORT → 배포:$TARGET($TARGET_PORT)${NC}" + +echo -e "${YELLOW}[3/7] $TARGET 컨테이너 실행${NC}" +docker-compose -f "$COMPOSE_FILE" up -d --pull always + +echo -e "${YELLOW}[4/7] 헬스체크 시작${NC}" + +RETRY_COUNT=0 +HEALTH_OK=false + +while [ $RETRY_COUNT -lt $MAX_RETRY ]; do + if curl -f -s --max-time 5 "http://localhost:${TARGET_PORT}/actuator/health" > /dev/null; then + echo -e "${GREEN}[SUCCESS] 헬스체크 성공${NC}" + HEALTH_OK=true + break + else + RETRY_COUNT=$((RETRY_COUNT + 1)) + echo -e "${YELLOW}[RETRY] ${RETRY_COUNT}/${MAX_RETRY}${NC}" + sleep $RETRY_INTERVAL + fi +done + +if [ "$HEALTH_OK" = false ]; then + echo -e "${RED}[ERROR] 헬스체크 실패${NC}" + docker-compose -f "$COMPOSE_FILE" down + exit 1 +fi + +echo -e "${YELLOW}[5/7] nginx upstream 전환${NC}" + +sudo tee $NGINX_UPSTREAM_FILE > /dev/null < /dev/null 2>&1 +} + +container_logs_hint() { + local name="$1" + if docker ps -a --format '{{.Names}}' | grep -q "^${name}$"; then + docker logs --tail 50 "$name" || true + fi +} + +cd "$DEPLOY_DIR" || exit 1 + +echo -e "${YELLOW}[1/7] 현재 active 포트 확인${NC}" + +CURRENT_PORT=$(grep -oE 'server[[:space:]]+127\.0\.0\.1:([0-9]+)' "$NGINX_UPSTREAM_FILE" | grep -oE '[0-9]+' | head -n 1 || true) + +if [[ "$CURRENT_PORT" == "$BLUE_PORT" ]]; then + ACTIVE="blue" + ACTIVE_PORT="$BLUE_PORT" + ACTIVE_COMPOSE="$BLUE_COMPOSE" + + PREV="green" + PREV_PORT="$GREEN_PORT" + PREV_COMPOSE="$GREEN_COMPOSE" +elif [[ "$CURRENT_PORT" == "$GREEN_PORT" ]]; then + ACTIVE="green" + ACTIVE_PORT="$GREEN_PORT" + ACTIVE_COMPOSE="$GREEN_COMPOSE" + + PREV="blue" + PREV_PORT="$BLUE_PORT" + PREV_COMPOSE="$BLUE_COMPOSE" +else + if health_check "$BLUE_PORT"; then + ACTIVE="blue"; ACTIVE_PORT="$BLUE_PORT"; ACTIVE_COMPOSE="$BLUE_COMPOSE" + PREV="green"; PREV_PORT="$GREEN_PORT"; PREV_COMPOSE="$GREEN_COMPOSE" + else + ACTIVE="green"; ACTIVE_PORT="$GREEN_PORT"; ACTIVE_COMPOSE="$GREEN_COMPOSE" + PREV="blue"; PREV_PORT="$BLUE_PORT"; PREV_COMPOSE="$BLUE_COMPOSE" + fi +fi + +echo -e "${GREEN}[INFO] active=${ACTIVE} → rollback=${PREV}${NC}" + +echo -e "${YELLOW}[2/7] 롤백 대상 컨테이너 실행${NC}" +docker-compose -f "$PREV_COMPOSE" up -d + +echo -e "${YELLOW}[3/7] 헬스체크${NC}" + +RETRY_COUNT=0 +HEALTH_OK=false + +while [[ $RETRY_COUNT -lt $MAX_RETRY ]]; do + if health_check "$PREV_PORT"; then + HEALTH_OK=true + break + else + RETRY_COUNT=$((RETRY_COUNT + 1)) + sleep $RETRY_INTERVAL + fi +done + +if [[ "$HEALTH_OK" != "true" ]]; then + echo -e "${RED}[ERROR] 롤백 실패${NC}" + docker-compose -f "$PREV_COMPOSE" down || true + exit 1 +fi + +echo -e "${YELLOW}[4/7] nginx 전환${NC}" + +sudo tee "$NGINX_UPSTREAM_FILE" > /dev/null < Date: Tue, 3 Mar 2026 22:20:11 +0900 Subject: [PATCH 02/14] =?UTF-8?q?ci:=20=EB=B0=B0=ED=8F=AC=20=ED=8A=B8?= =?UTF-8?q?=EB=A6=AC=EA=B1=B0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/prod-cicd.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/prod-cicd.yaml b/.github/workflows/prod-cicd.yaml index c0cc53e1..a1653b03 100644 --- a/.github/workflows/prod-cicd.yaml +++ b/.github/workflows/prod-cicd.yaml @@ -1,7 +1,9 @@ name: prod on: - workflow_dispatch: + push: + branches: + - feat/SOU-421-prod-script env: IMAGE_NAME: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest From 76965c661b469a4b0645f51dba6cf51e92ce9ebb Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 22:49:18 +0900 Subject: [PATCH 03/14] =?UTF-8?q?fix:=20compose=20v2=20=EB=AC=B8=EB=B2=95?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/deploy.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deploy/prod/scripts/deploy.sh b/deploy/prod/scripts/deploy.sh index c62175b5..c014ddac 100755 --- a/deploy/prod/scripts/deploy.sh +++ b/deploy/prod/scripts/deploy.sh @@ -57,7 +57,8 @@ fi echo -e "${GREEN}[INFO] 현재:$CURRENT_PORT → 배포:$TARGET($TARGET_PORT)${NC}" echo -e "${YELLOW}[3/7] $TARGET 컨테이너 실행${NC}" -docker-compose -f "$COMPOSE_FILE" up -d --pull always +docker-compose -f "$COMPOSE_FILE" pull +docker-compose -f "$COMPOSE_FILE" up -d echo -e "${YELLOW}[4/7] 헬스체크 시작${NC}" From 88b5f0a6ecb4b3572d3f1b6a41edf72ff9c86475 Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 23:01:05 +0900 Subject: [PATCH 04/14] =?UTF-8?q?chore:=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=ED=99=98=EA=B2=BD=EC=97=90=EC=84=9C=20=EB=8F=84?= =?UTF-8?q?=EC=BB=A4=20=EC=BB=B4=ED=8F=AC=EC=A6=88=20=EB=B9=84=ED=99=9C?= =?UTF-8?q?=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-prod.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/resources/application-prod.yaml b/src/main/resources/application-prod.yaml index 0a7d021a..41b7619a 100644 --- a/src/main/resources/application-prod.yaml +++ b/src/main/resources/application-prod.yaml @@ -1,4 +1,8 @@ spring: + docker: + compose: + enabled: false + datasource: url: ${PROD_DB_URL} username: ${PROD_POSTGRES_USER} From 4aca85363c7c59cc672bbb8532bb667918b1bd47 Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 23:23:41 +0900 Subject: [PATCH 05/14] =?UTF-8?q?chore:=20docker=20compose=20v2=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/deploy.sh | 10 +++++----- deploy/prod/scripts/rollback.sh | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/deploy/prod/scripts/deploy.sh b/deploy/prod/scripts/deploy.sh index c014ddac..d533ed20 100755 --- a/deploy/prod/scripts/deploy.sh +++ b/deploy/prod/scripts/deploy.sh @@ -57,8 +57,8 @@ fi echo -e "${GREEN}[INFO] 현재:$CURRENT_PORT → 배포:$TARGET($TARGET_PORT)${NC}" echo -e "${YELLOW}[3/7] $TARGET 컨테이너 실행${NC}" -docker-compose -f "$COMPOSE_FILE" pull -docker-compose -f "$COMPOSE_FILE" up -d +docker compose -f "$COMPOSE_FILE" pull +docker compose -f "$COMPOSE_FILE" up -d echo -e "${YELLOW}[4/7] 헬스체크 시작${NC}" @@ -79,7 +79,7 @@ done if [ "$HEALTH_OK" = false ]; then echo -e "${RED}[ERROR] 헬스체크 실패${NC}" - docker-compose -f "$COMPOSE_FILE" down + docker compose -f "$COMPOSE_FILE" down exit 1 fi @@ -99,9 +99,9 @@ echo -e "${GREEN}[SUCCESS] nginx 전환 완료${NC}" echo -e "${YELLOW}[6/7] 이전 컨테이너 종료 ($STOP)${NC}" if [ "$STOP" == "blue" ]; then - docker-compose -f "$BLUE_COMPOSE" down + docker compose -f "$BLUE_COMPOSE" down else - docker-compose -f "$GREEN_COMPOSE" down + docker compose -f "$GREEN_COMPOSE" down fi echo -e "${YELLOW}[7/7] 이미지 정리${NC}" diff --git a/deploy/prod/scripts/rollback.sh b/deploy/prod/scripts/rollback.sh index 573f1c7b..157cd57d 100755 --- a/deploy/prod/scripts/rollback.sh +++ b/deploy/prod/scripts/rollback.sh @@ -70,7 +70,7 @@ fi echo -e "${GREEN}[INFO] active=${ACTIVE} → rollback=${PREV}${NC}" echo -e "${YELLOW}[2/7] 롤백 대상 컨테이너 실행${NC}" -docker-compose -f "$PREV_COMPOSE" up -d +docker compose -f "$PREV_COMPOSE" up -d echo -e "${YELLOW}[3/7] 헬스체크${NC}" @@ -89,7 +89,7 @@ done if [[ "$HEALTH_OK" != "true" ]]; then echo -e "${RED}[ERROR] 롤백 실패${NC}" - docker-compose -f "$PREV_COMPOSE" down || true + docker compose -f "$PREV_COMPOSE" down || true exit 1 fi @@ -105,7 +105,7 @@ sudo nginx -t sudo nginx -s reload echo -e "${YELLOW}[5/7] 기존 컨테이너 종료${NC}" -docker-compose -f "$ACTIVE_COMPOSE" down || true +docker compose -f "$ACTIVE_COMPOSE" down || true echo -e "${YELLOW}[6/7] 상태 확인${NC}" docker ps | grep souzip || true From d2205c617600ea720c683005baf2f3751c341bce Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 23:32:16 +0900 Subject: [PATCH 06/14] =?UTF-8?q?feat:=20prod=20=EB=B0=B0=ED=8F=AC=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/deploy.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/deploy/prod/scripts/deploy.sh b/deploy/prod/scripts/deploy.sh index d533ed20..6861dc40 100755 --- a/deploy/prod/scripts/deploy.sh +++ b/deploy/prod/scripts/deploy.sh @@ -40,7 +40,12 @@ cd "$DEPLOY_DIR" || exit 1 echo -e "${YELLOW}[2/7] 현재 active 포트 확인${NC}" -CURRENT_PORT=$(grep -oE 'server[[:space:]]+127\.0\.0\.1:([0-9]+)' "$NGINX_UPSTREAM_FILE" | grep -oE '[0-9]+' | head -n 1 || true) +CURRENT_PORT=$(grep -oE '127\.0\.0\.1:[0-9]+' "$NGINX_UPSTREAM_FILE" | cut -d: -f2 | head -n 1 || true) + +if [ -z "$CURRENT_PORT" ]; then + echo -e "${YELLOW}[WARN] upstream 없음 → 최초 배포 (blue=8081)${NC}" + CURRENT_PORT="none" +fi if [ "$CURRENT_PORT" == "$BLUE_PORT" ]; then TARGET="green" @@ -57,6 +62,8 @@ fi echo -e "${GREEN}[INFO] 현재:$CURRENT_PORT → 배포:$TARGET($TARGET_PORT)${NC}" echo -e "${YELLOW}[3/7] $TARGET 컨테이너 실행${NC}" + +docker compose -f "$COMPOSE_FILE" down || true docker compose -f "$COMPOSE_FILE" pull docker compose -f "$COMPOSE_FILE" up -d @@ -99,12 +106,12 @@ echo -e "${GREEN}[SUCCESS] nginx 전환 완료${NC}" echo -e "${YELLOW}[6/7] 이전 컨테이너 종료 ($STOP)${NC}" if [ "$STOP" == "blue" ]; then - docker compose -f "$BLUE_COMPOSE" down + docker compose -f "$BLUE_COMPOSE" down || true else - docker compose -f "$GREEN_COMPOSE" down + docker compose -f "$GREEN_COMPOSE" down || true fi echo -e "${YELLOW}[7/7] 이미지 정리${NC}" -docker image prune -f +docker image prune -f || true echo -e "${GREEN}[DEPLOY SUCCESS] 완료${NC}" \ No newline at end of file From 48e5dd8ed1d5dbc324baec3ad8f441ac9192644d Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 23:33:06 +0900 Subject: [PATCH 07/14] =?UTF-8?q?chore:=20=EB=A1=A4=EB=B0=B1=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/rollback.sh | 116 -------------------------------- 1 file changed, 116 deletions(-) delete mode 100755 deploy/prod/scripts/rollback.sh diff --git a/deploy/prod/scripts/rollback.sh b/deploy/prod/scripts/rollback.sh deleted file mode 100755 index 157cd57d..00000000 --- a/deploy/prod/scripts/rollback.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/bin/bash -set -euo pipefail - -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' - -WORK_DIR="/home/kgb581818/souzip" -DEPLOY_DIR="$WORK_DIR/deploy/prod" - -BLUE_COMPOSE="docker-compose.blue.yaml" -GREEN_COMPOSE="docker-compose.green.yaml" - -NGINX_UPSTREAM_FILE="/etc/nginx/conf.d/upstream-souzip.conf" - -BLUE_PORT=8081 -GREEN_PORT=8082 - -MAX_RETRY=6 -RETRY_INTERVAL=10 - -BLUE_CONTAINER_NAME="${BLUE_CONTAINER_NAME:-souzip-api-blue}" -GREEN_CONTAINER_NAME="${GREEN_CONTAINER_NAME:-souzip-api-green}" - -health_check() { - local port="$1" - curl -f -s --max-time 5 "http://localhost:${port}/actuator/health" > /dev/null 2>&1 -} - -container_logs_hint() { - local name="$1" - if docker ps -a --format '{{.Names}}' | grep -q "^${name}$"; then - docker logs --tail 50 "$name" || true - fi -} - -cd "$DEPLOY_DIR" || exit 1 - -echo -e "${YELLOW}[1/7] 현재 active 포트 확인${NC}" - -CURRENT_PORT=$(grep -oE 'server[[:space:]]+127\.0\.0\.1:([0-9]+)' "$NGINX_UPSTREAM_FILE" | grep -oE '[0-9]+' | head -n 1 || true) - -if [[ "$CURRENT_PORT" == "$BLUE_PORT" ]]; then - ACTIVE="blue" - ACTIVE_PORT="$BLUE_PORT" - ACTIVE_COMPOSE="$BLUE_COMPOSE" - - PREV="green" - PREV_PORT="$GREEN_PORT" - PREV_COMPOSE="$GREEN_COMPOSE" -elif [[ "$CURRENT_PORT" == "$GREEN_PORT" ]]; then - ACTIVE="green" - ACTIVE_PORT="$GREEN_PORT" - ACTIVE_COMPOSE="$GREEN_COMPOSE" - - PREV="blue" - PREV_PORT="$BLUE_PORT" - PREV_COMPOSE="$BLUE_COMPOSE" -else - if health_check "$BLUE_PORT"; then - ACTIVE="blue"; ACTIVE_PORT="$BLUE_PORT"; ACTIVE_COMPOSE="$BLUE_COMPOSE" - PREV="green"; PREV_PORT="$GREEN_PORT"; PREV_COMPOSE="$GREEN_COMPOSE" - else - ACTIVE="green"; ACTIVE_PORT="$GREEN_PORT"; ACTIVE_COMPOSE="$GREEN_COMPOSE" - PREV="blue"; PREV_PORT="$BLUE_PORT"; PREV_COMPOSE="$BLUE_COMPOSE" - fi -fi - -echo -e "${GREEN}[INFO] active=${ACTIVE} → rollback=${PREV}${NC}" - -echo -e "${YELLOW}[2/7] 롤백 대상 컨테이너 실행${NC}" -docker compose -f "$PREV_COMPOSE" up -d - -echo -e "${YELLOW}[3/7] 헬스체크${NC}" - -RETRY_COUNT=0 -HEALTH_OK=false - -while [[ $RETRY_COUNT -lt $MAX_RETRY ]]; do - if health_check "$PREV_PORT"; then - HEALTH_OK=true - break - else - RETRY_COUNT=$((RETRY_COUNT + 1)) - sleep $RETRY_INTERVAL - fi -done - -if [[ "$HEALTH_OK" != "true" ]]; then - echo -e "${RED}[ERROR] 롤백 실패${NC}" - docker compose -f "$PREV_COMPOSE" down || true - exit 1 -fi - -echo -e "${YELLOW}[4/7] nginx 전환${NC}" - -sudo tee "$NGINX_UPSTREAM_FILE" > /dev/null < Date: Tue, 3 Mar 2026 23:50:10 +0900 Subject: [PATCH 08/14] =?UTF-8?q?fix:=20Flyway=20schema=20init=20idempoten?= =?UTF-8?q?cy=20=EB=B0=8F=20=EA=B6=8C=ED=95=9C=20=EC=9D=B4=EC=8A=88=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/db/migration/V1__init_schema.sql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/resources/db/migration/V1__init_schema.sql b/src/main/resources/db/migration/V1__init_schema.sql index 0dbf5bb3..66fd1145 100644 --- a/src/main/resources/db/migration/V1__init_schema.sql +++ b/src/main/resources/db/migration/V1__init_schema.sql @@ -11,10 +11,10 @@ -- Name: cdb_admin; Type: SCHEMA; Schema: -; Owner: postgres -- -CREATE SCHEMA cdb_admin; +CREATE SCHEMA IF NOT EXISTS cdb_admin; -ALTER SCHEMA cdb_admin OWNER TO postgres; +-- ALTER SCHEMA cdb_admin OWNER TO postgres; -- -- Name: public; Type: SCHEMA; Schema: -; Owner: postgres @@ -23,7 +23,7 @@ ALTER SCHEMA cdb_admin OWNER TO postgres; -- *not* creating schema, since initdb creates it -ALTER SCHEMA public OWNER TO postgres; +-- ALTER SCHEMA public OWNER TO postgres; -- -- Name: postgis; Type: EXTENSION; Schema: -; Owner: - From 2039f38285be27463919a86818e24943fb2a0bc3 Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Tue, 3 Mar 2026 23:56:27 +0900 Subject: [PATCH 09/14] =?UTF-8?q?fix:=20Flyway=20migration=EC=97=90?= =?UTF-8?q?=EC=84=9C=20postgis=20extension=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EA=B5=AC=EB=AC=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/db/migration/V1__init_schema.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V1__init_schema.sql b/src/main/resources/db/migration/V1__init_schema.sql index 66fd1145..1799d52f 100644 --- a/src/main/resources/db/migration/V1__init_schema.sql +++ b/src/main/resources/db/migration/V1__init_schema.sql @@ -29,7 +29,7 @@ CREATE SCHEMA IF NOT EXISTS cdb_admin; -- Name: postgis; Type: EXTENSION; Schema: -; Owner: - -- -CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA cdb_admin; +-- CREATE EXTENSION IF NOT EXISTS postgis WITH SCHEMA cdb_admin; -- From 955263b03515706ad563186dcdc9fd9a8be12e6f Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Wed, 4 Mar 2026 00:19:29 +0900 Subject: [PATCH 10/14] =?UTF-8?q?fix:=20Flyway=20PostGIS=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/db/migration/V1__init_schema.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/db/migration/V1__init_schema.sql b/src/main/resources/db/migration/V1__init_schema.sql index 1799d52f..245380f1 100644 --- a/src/main/resources/db/migration/V1__init_schema.sql +++ b/src/main/resources/db/migration/V1__init_schema.sql @@ -36,7 +36,7 @@ CREATE SCHEMA IF NOT EXISTS cdb_admin; -- Name: EXTENSION postgis; Type: COMMENT; Schema: -; Owner: -- -COMMENT ON EXTENSION postgis IS 'PostGIS geometry and geography spatial types and functions'; +-- COMMENT ON EXTENSION postgis IS 'PostGIS geometry and geography spatial types and functions'; From 8c9774e0273e9acce22aad294d85edc14ab609df Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Wed, 4 Mar 2026 00:30:53 +0900 Subject: [PATCH 11/14] =?UTF-8?q?fix:=20CI/CD=EC=97=90=20=EB=88=84?= =?UTF-8?q?=EB=9D=BD=EB=90=9C=20NCP=20Object=20Storage=20=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/prod-cicd.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/prod-cicd.yaml b/.github/workflows/prod-cicd.yaml index a1653b03..48255e71 100644 --- a/.github/workflows/prod-cicd.yaml +++ b/.github/workflows/prod-cicd.yaml @@ -121,6 +121,11 @@ jobs: PROD_API_DOCS_URL=${{ secrets.PROD_API_DOCS_URL }} ADMIN_INITIAL_USERNAME=${{ secrets.ADMIN_INITIAL_USERNAME }} ADMIN_INITIAL_PASSWORD=${{ secrets.ADMIN_INITIAL_PASSWORD }} + NCP_ENDPOINT=${{ secrets.NCP_ENDPOINT }} + NCP_REGION=${{ secrets.NCP_REGION }} + NCP_BUCKET=${{ secrets.NCP_BUCKET }} + NCP_ACCESS_KEY=${{ secrets.NCP_ACCESS_KEY }} + NCP_SECRET_KEY=${{ secrets.NCP_SECRET_KEY }} EOF echo "DEPLOYER=${{ github.actor }}" >> deploy/prod/.env From 53e86ab7fee5681b1cd52b4eda8f70d74d5f52e4 Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Wed, 4 Mar 2026 21:47:56 +0900 Subject: [PATCH 12/14] =?UTF-8?q?fix:=20=EB=B8=94=EB=A3=A8/=EA=B7=B8?= =?UTF-8?q?=EB=A6=B0=20=EB=B0=B0=ED=8F=AC=20=EC=8B=9C=20=EB=8F=84=EC=BB=A4?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EC=A6=88=20=EC=B6=A9=EB=8F=8C=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/deploy.sh | 46 +++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/deploy/prod/scripts/deploy.sh b/deploy/prod/scripts/deploy.sh index 6861dc40..3204bb9d 100755 --- a/deploy/prod/scripts/deploy.sh +++ b/deploy/prod/scripts/deploy.sh @@ -7,12 +7,16 @@ YELLOW='\033[1;33m' NC='\033[0m' REGISTRY="asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api" + WORK_DIR="/home/kgb581818/souzip" DEPLOY_DIR="$WORK_DIR/deploy/prod" BLUE_COMPOSE="docker-compose.blue.yaml" GREEN_COMPOSE="docker-compose.green.yaml" +BLUE_PROJECT="souzip-blue" +GREEN_PROJECT="souzip-green" + NGINX_UPSTREAM_FILE="/etc/nginx/conf.d/upstream-souzip.conf" BLUE_PORT=8081 @@ -24,7 +28,9 @@ RETRY_INTERVAL=10 cd "$WORK_DIR" || exit 1 echo -e "${YELLOW}[1/7] 최신 이미지 다운로드${NC}" + docker pull ${REGISTRY}:latest + NEW_IMAGE=$(docker images ${REGISTRY}:latest -q) if [ -z "${NEW_IMAGE:-}" ]; then @@ -36,7 +42,10 @@ echo -e "${GREEN}[SUCCESS] 새 이미지: ${NEW_IMAGE}${NC}" cd "$DEPLOY_DIR" || exit 1 -[ -f "$NGINX_UPSTREAM_FILE" ] || { echo -e "${RED}[ERROR] upstream 파일 없음${NC}"; exit 1; } +[ -f "$NGINX_UPSTREAM_FILE" ] || { + echo -e "${RED}[ERROR] upstream 파일 없음${NC}" + exit 1 +} echo -e "${YELLOW}[2/7] 현재 active 포트 확인${NC}" @@ -50,22 +59,28 @@ fi if [ "$CURRENT_PORT" == "$BLUE_PORT" ]; then TARGET="green" TARGET_PORT=$GREEN_PORT - STOP="blue" - COMPOSE_FILE=$GREEN_COMPOSE + TARGET_PROJECT=$GREEN_PROJECT + TARGET_COMPOSE=$GREEN_COMPOSE + + STOP_PROJECT=$BLUE_PROJECT + STOP_COMPOSE=$BLUE_COMPOSE + else TARGET="blue" TARGET_PORT=$BLUE_PORT - STOP="green" - COMPOSE_FILE=$BLUE_COMPOSE + TARGET_PROJECT=$BLUE_PROJECT + TARGET_COMPOSE=$BLUE_COMPOSE + + STOP_PROJECT=$GREEN_PROJECT + STOP_COMPOSE=$GREEN_COMPOSE fi echo -e "${GREEN}[INFO] 현재:$CURRENT_PORT → 배포:$TARGET($TARGET_PORT)${NC}" echo -e "${YELLOW}[3/7] $TARGET 컨테이너 실행${NC}" -docker compose -f "$COMPOSE_FILE" down || true -docker compose -f "$COMPOSE_FILE" pull -docker compose -f "$COMPOSE_FILE" up -d +docker compose -p "$TARGET_PROJECT" -f "$TARGET_COMPOSE" pull +docker compose -p "$TARGET_PROJECT" -f "$TARGET_COMPOSE" up -d echo -e "${YELLOW}[4/7] 헬스체크 시작${NC}" @@ -73,6 +88,7 @@ RETRY_COUNT=0 HEALTH_OK=false while [ $RETRY_COUNT -lt $MAX_RETRY ]; do + if curl -f -s --max-time 5 "http://localhost:${TARGET_PORT}/actuator/health" > /dev/null; then echo -e "${GREEN}[SUCCESS] 헬스체크 성공${NC}" HEALTH_OK=true @@ -82,17 +98,18 @@ while [ $RETRY_COUNT -lt $MAX_RETRY ]; do echo -e "${YELLOW}[RETRY] ${RETRY_COUNT}/${MAX_RETRY}${NC}" sleep $RETRY_INTERVAL fi + done if [ "$HEALTH_OK" = false ]; then echo -e "${RED}[ERROR] 헬스체크 실패${NC}" - docker compose -f "$COMPOSE_FILE" down + docker compose -p "$TARGET_PROJECT" -f "$TARGET_COMPOSE" down exit 1 fi echo -e "${YELLOW}[5/7] nginx upstream 전환${NC}" -sudo tee $NGINX_UPSTREAM_FILE > /dev/null < /dev/null < Date: Wed, 4 Mar 2026 23:48:46 +0900 Subject: [PATCH 13/14] =?UTF-8?q?chore:=20=EB=B0=B0=ED=8F=AC=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=20souzip-prod=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deploy/prod/scripts/deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/prod/scripts/deploy.sh b/deploy/prod/scripts/deploy.sh index 3204bb9d..370af3d1 100755 --- a/deploy/prod/scripts/deploy.sh +++ b/deploy/prod/scripts/deploy.sh @@ -8,7 +8,7 @@ NC='\033[0m' REGISTRY="asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api" -WORK_DIR="/home/kgb581818/souzip" +WORK_DIR="/home/souzip-prod/souzip" DEPLOY_DIR="$WORK_DIR/deploy/prod" BLUE_COMPOSE="docker-compose.blue.yaml" From 8ec3d6eb87db72a400fa57e78260f41969ee6262 Mon Sep 17 00:00:00 2001 From: bum0w0 Date: Wed, 4 Mar 2026 23:58:19 +0900 Subject: [PATCH 14/14] =?UTF-8?q?ci:=20=ED=94=84=EB=A1=9C=EB=8D=95?= =?UTF-8?q?=EC=85=98=20=EB=B0=B0=ED=8F=AC=20=ED=8A=B8=EB=A6=AC=EA=B1=B0=20?= =?UTF-8?q?=EB=B8=8C=EB=9E=9C=EC=B9=98=EB=A5=BC=20main=EC=9C=BC=EB=A1=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/prod-cicd.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/prod-cicd.yaml b/.github/workflows/prod-cicd.yaml index 48255e71..bbedbd43 100644 --- a/.github/workflows/prod-cicd.yaml +++ b/.github/workflows/prod-cicd.yaml @@ -1,9 +1,12 @@ name: prod on: + pull_request: + branches: + - main push: branches: - - feat/SOU-421-prod-script + - main env: IMAGE_NAME: asia-northeast3-docker.pkg.dev/souzip-488211/souzip-prod-repo/souzip-api:latest