Deploy: GitHub submodule sync 2026-07-23 12:46:52
This commit is contained in:
@@ -5,6 +5,9 @@
|
||||
# ./server-dev/start-all-server.sh --no-build
|
||||
# ./server-dev/start-all-server.sh --skip-java
|
||||
# ./server-dev/start-all-server.sh --skip-legacy-stop
|
||||
# ./server-dev/start-all-server.sh --no-pull # git 동기화 생략
|
||||
# ./server-dev/start-all-server.sh --no-push # Gitea push 생략
|
||||
# ./server-dev/start-all-server.sh --local # 로컬 Mac 개발 모드 (local-dev 위임)
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
@@ -12,6 +15,10 @@ SERVER_DEV_DIR="${ROOT_DIR}/server-dev"
|
||||
RUN_DIR="${SERVER_DEV_DIR}/run"
|
||||
LOG_DIR="${SERVER_DEV_DIR}/logs"
|
||||
|
||||
GIT_DIR="${GIT_DIR:-/Volumes/ADATA/gitea/data/gitea-repositories/aidev/exaichatbot_agent.git}"
|
||||
WORK_TREE="${WORK_TREE:-/Users/aidev/dev/exAichatbot_agent}"
|
||||
GIT_BRANCH="${GIT_BRANCH:-main}"
|
||||
|
||||
RAG_DIR="${ROOT_DIR}/exAiChatBot-chatbot2.0-agent"
|
||||
API_DIR="${ROOT_DIR}/chatbotApi-chatbot2.0-agent"
|
||||
SKILL_DIR="${ROOT_DIR}/kakaoChatbotSkill-chatbot2.0-agent"
|
||||
@@ -40,6 +47,10 @@ NO_BUILD=false
|
||||
SKIP_JAVA=false
|
||||
SKIP_LEGACY_STOP=false
|
||||
SKIP_CADDY=false
|
||||
NO_PULL=false
|
||||
NO_PUSH=false
|
||||
LOCAL_DEV=false
|
||||
EXDEV_SSH="${EXDEV_SSH:-aidev@chatbot.exdev.co.kr}"
|
||||
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
@@ -47,8 +58,11 @@ for arg in "$@"; do
|
||||
--skip-java) SKIP_JAVA=true ;;
|
||||
--skip-legacy-stop) SKIP_LEGACY_STOP=true ;;
|
||||
--skip-caddy) SKIP_CADDY=true ;;
|
||||
--no-pull) NO_PULL=true ;;
|
||||
--no-push) NO_PUSH=true ;;
|
||||
--local) LOCAL_DEV=true ;;
|
||||
-h|--help)
|
||||
sed -n '2,10p' "$0"
|
||||
sed -n '2,12p' "$0"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
@@ -62,6 +76,133 @@ export PATH="/opt/homebrew/bin:/usr/local/bin:/Applications/Docker.app/Contents/
|
||||
|
||||
log() { echo "[$(date '+%H:%M:%S')] $*"; }
|
||||
fail() { log "ERROR: $*"; exit 1; }
|
||||
warn() { log "⚠️ $*"; }
|
||||
|
||||
sync_github_submodules() {
|
||||
local tree="$1"
|
||||
local fetch_script="${tree}/git_fetch_all.sh"
|
||||
local -a fetch_args=()
|
||||
if is_exdev_server; then
|
||||
fetch_args+=(--init)
|
||||
fi
|
||||
if [[ ! -x "${fetch_script}" ]]; then
|
||||
log "git_fetch_all.sh 없음 — submodule GitHub 동기화 생략"
|
||||
return 0
|
||||
fi
|
||||
log "GitHub submodule 최신 동기화 (git_fetch_all.sh)..."
|
||||
if [[ ${#fetch_args[@]} -gt 0 ]]; then
|
||||
if ! "${fetch_script}" "${fetch_args[@]}"; then
|
||||
warn "GitHub submodule 동기화 실패 — ./git_fetch_all.sh 수동 실행"
|
||||
return 1
|
||||
fi
|
||||
elif ! "${fetch_script}"; then
|
||||
warn "GitHub submodule 동기화 실패 — ./git_fetch_all.sh 수동 실행"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
push_source_to_gitea() {
|
||||
if $NO_PUSH; then
|
||||
log "Gitea push 생략 (--no-push)"
|
||||
return 0
|
||||
fi
|
||||
if is_exdev_server; then
|
||||
log "exdev 서버 — Gitea push 생략 (post-receive/deploy 경로 사용)"
|
||||
return 0
|
||||
fi
|
||||
local push_script="${SERVER_DEV_DIR}/push-to-gitea.sh"
|
||||
[[ -x "${push_script}" ]] || fail "push-to-gitea.sh 없음: ${push_script}"
|
||||
log "현재 소스 → Gitea (${GIT_BRANCH}) 반영..."
|
||||
"${push_script}"
|
||||
}
|
||||
|
||||
wait_remote_deploy() {
|
||||
if $NO_PUSH; then
|
||||
return 0
|
||||
fi
|
||||
local wait_script="${SERVER_DEV_DIR}/wait-remote-deploy.sh"
|
||||
if [[ -x "${wait_script}" ]]; then
|
||||
EXDEV_SSH="${EXDEV_SSH}" PUBLIC_BASE_URL="${PUBLIC_BASE_URL}" "${wait_script}" || \
|
||||
warn "원격 배포 대기 실패 — ssh ${EXDEV_SSH} tail /Volumes/ADATA/logs/deploy/exAichatbot_agent.log"
|
||||
else
|
||||
warn "wait-remote-deploy.sh 없음 — https://chatbot.exdev.co.kr/chatbot/app/ 수동 확인"
|
||||
fi
|
||||
}
|
||||
|
||||
deploy_from_local_mac() {
|
||||
log "로컬 Mac → Gitea push → chatbot.exdev.co.kr 배포"
|
||||
if ! $NO_PULL; then
|
||||
sync_github_submodules "${ROOT_DIR}" || true
|
||||
fi
|
||||
push_source_to_gitea
|
||||
wait_remote_deploy
|
||||
log "=========================================="
|
||||
log "원격 배포 요청 완료"
|
||||
log " UI ${PUBLIC_BASE_URL}/chatbot/app/"
|
||||
log " 로그 ssh ${EXDEV_SSH} tail -f /Volumes/ADATA/logs/deploy/exAichatbot_agent.log"
|
||||
log "=========================================="
|
||||
exit 0
|
||||
}
|
||||
|
||||
sync_source_from_git() {
|
||||
if $NO_PULL; then
|
||||
log "git 동기화 생략 (--no-pull)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
local tree="${WORK_TREE}"
|
||||
local branch="${GIT_BRANCH}"
|
||||
|
||||
if [[ -d "${GIT_DIR}" ]]; then
|
||||
mkdir -p "${tree}"
|
||||
log "Gitea 최신 소스 동기화 (${branch})..."
|
||||
if ! git --git-dir="${GIT_DIR}" show-ref --verify --quiet "refs/heads/${branch}" 2>/dev/null; then
|
||||
fail "브랜치 없음: ${branch} (GIT_DIR=${GIT_DIR})"
|
||||
fi
|
||||
git --work-tree="${tree}" --git-dir="${GIT_DIR}" checkout -f "${branch}"
|
||||
sync_github_submodules "${tree}" || true
|
||||
local commit
|
||||
commit="$(git --git-dir="${GIT_DIR}" rev-parse --short HEAD)"
|
||||
log "✅ 소스 동기화: ${commit} (${branch})"
|
||||
elif [[ -d "${ROOT_DIR}/.git" ]]; then
|
||||
log "git pull origin ${branch}..."
|
||||
(
|
||||
cd "${ROOT_DIR}"
|
||||
git fetch origin "${branch}"
|
||||
git checkout "${branch}"
|
||||
git pull --ff-only origin "${branch}"
|
||||
)
|
||||
sync_github_submodules "${ROOT_DIR}" || true
|
||||
log "✅ git pull 완료: $(git -C "${ROOT_DIR}" rev-parse --short HEAD)"
|
||||
tree="${ROOT_DIR}"
|
||||
else
|
||||
log "Git 저장소 없음 — 현재 디렉터리 소스 사용 (${ROOT_DIR})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
chmod +x "${tree}/server-dev/"*.sh 2>/dev/null || true
|
||||
chmod +x "${tree}/git_fetch_all.sh" 2>/dev/null || true
|
||||
chmod +x "${tree}/chatbotApp-chatbot2.0-agent/build.sh" 2>/dev/null || true
|
||||
chmod +x "${tree}/start-all-server.sh" "${tree}/stop-all-server.sh" 2>/dev/null || true
|
||||
}
|
||||
|
||||
is_exdev_server() {
|
||||
[[ -d "${GIT_DIR}" ]] \
|
||||
&& [[ -f "${LEGACY_STACK_DIR}/scripts/exdev/start-host-ai.sh" ]]
|
||||
}
|
||||
|
||||
run_local_dev() {
|
||||
log "로컬 Mac — local-dev/start-all.sh 로 위임 (exdev AI SSH 터널 사용)"
|
||||
local -a args=()
|
||||
$NO_BUILD && args+=(--no-build)
|
||||
$SKIP_JAVA && args+=(--skip-java)
|
||||
if ((${#args[@]} > 0)); then
|
||||
exec "${ROOT_DIR}/local-dev/start-all.sh" "${args[@]}"
|
||||
else
|
||||
exec "${ROOT_DIR}/local-dev/start-all.sh"
|
||||
fi
|
||||
}
|
||||
|
||||
wait_http() {
|
||||
local url="$1" label="$2" max="${3:-90}"
|
||||
@@ -136,7 +277,7 @@ ensure_rag_env() {
|
||||
}
|
||||
|
||||
ensure_mongo() {
|
||||
if docker ps --format '{{.Names}}' | grep -qx "${MONGO_CONTAINER}"; then
|
||||
if docker ps -a --format '{{.Names}}' | grep -qx "${MONGO_CONTAINER}"; then
|
||||
docker start "${MONGO_CONTAINER}" >/dev/null 2>&1 || true
|
||||
log "MongoDB 재사용: ${MONGO_CONTAINER}"
|
||||
wait_port 27017 "MongoDB" 20 || true
|
||||
@@ -152,8 +293,14 @@ ensure_mongo() {
|
||||
}
|
||||
|
||||
bootstrap_qdrant_if_empty() {
|
||||
local collection="${QDRANT_COLLECTION:-qa_vectors_v2}"
|
||||
if [[ -f "${RAG_ENV}" ]]; then
|
||||
local from_env
|
||||
from_env="$(grep -E '^QDRANT_COLLECTION=' "${RAG_ENV}" 2>/dev/null | tail -1 | cut -d= -f2- | tr -d ' "\r' || true)"
|
||||
[[ -n "${from_env}" ]] && collection="${from_env}"
|
||||
fi
|
||||
local vc
|
||||
vc="$(curl -sf "http://127.0.0.1:6333/collections/qa_vectors" 2>/dev/null \
|
||||
vc="$(curl -sf "http://127.0.0.1:6333/collections/${collection}" 2>/dev/null \
|
||||
| python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('result',{}).get('points_count',0))" 2>/dev/null || echo 0)"
|
||||
if [[ "${vc}" -gt 0 ]]; then
|
||||
log "Qdrant 기존 데이터 ${vc} points"
|
||||
@@ -166,17 +313,26 @@ bootstrap_qdrant_if_empty() {
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_rag_compose() {
|
||||
local template="${SERVER_DEV_DIR}/docker-compose.rag.server.yml"
|
||||
[[ -f "${template}" ]] || fail "server-dev/docker-compose.rag.server.yml 없음"
|
||||
cp "${template}" "${COMPOSE_SERVER}"
|
||||
}
|
||||
|
||||
start_rag() {
|
||||
ensure_rag_env
|
||||
ensure_rag_compose
|
||||
[[ -f "${COMPOSE_SERVER}" ]] || fail "docker-compose.server.yml 없음"
|
||||
cd "${RAG_DIR}"
|
||||
docker compose -f "${COMPOSE_SERVER}" down --remove-orphans 2>/dev/null || true
|
||||
local -a up_flags=(-d)
|
||||
if $NO_BUILD; then up_flags+=(--no-build); else up_flags+=(--build); fi
|
||||
log "RAG 스택 기동..."
|
||||
log "RAG 스택 기동 (docker-compose.server.yml)..."
|
||||
docker compose -f "${COMPOSE_SERVER}" up "${up_flags[@]}"
|
||||
wait_http "http://127.0.0.1:6333/collections" "Qdrant" 30 || true
|
||||
bootstrap_qdrant_if_empty
|
||||
wait_http "http://127.0.0.1:${RAG_PORT}/health" "RAG API" 120
|
||||
(cd "${RAG_DIR}" && docker compose -f "${COMPOSE_SERVER}" up -d) || true
|
||||
wait_http "http://127.0.0.1:${RAG_PORT}/health" "RAG API" 180 || true
|
||||
wait_port "${ADMIN_PORT}" "Vector Admin" 30 || true
|
||||
}
|
||||
|
||||
@@ -278,12 +434,26 @@ verify_stack() {
|
||||
}
|
||||
|
||||
mkdir -p "${RUN_DIR}" "${LOG_DIR}"
|
||||
docker info >/dev/null 2>&1 || fail "Docker Engine 미기동"
|
||||
|
||||
log "=========================================="
|
||||
log "exAichatbot Agent 2.0 — exdev 서버 기동"
|
||||
log "exAichatbot Agent 2.0 기동"
|
||||
log "=========================================="
|
||||
|
||||
if ! is_exdev_server; then
|
||||
if $LOCAL_DEV; then
|
||||
sync_source_from_git
|
||||
run_local_dev
|
||||
else
|
||||
deploy_from_local_mac
|
||||
fi
|
||||
fi
|
||||
|
||||
sync_source_from_git
|
||||
|
||||
docker info >/dev/null 2>&1 || fail "Docker Engine 미기동"
|
||||
|
||||
log "exdev 서버 모드"
|
||||
|
||||
stop_legacy_stack
|
||||
ensure_host_ai
|
||||
ensure_mongo
|
||||
|
||||
Reference in New Issue
Block a user