#!/bin/bash # ========================================== # FITO PLM (Next.js) 시작/배포 스크립트 # 로컬 (docker dev): ./start.sh # 서버 운영 배포: ./start.sh prod # 로그: ./start.sh logs prod # 중지: ./start.sh stop prod # ========================================== SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$SCRIPT_DIR" ORIG_ARGS=("$@") GIT_URL='https://g.wace.me/hjjeong/fito-nextjs.git' COMPOSE_DEV="docker-compose.dev.yml" COMPOSE_PROD="docker-compose.prod.yml" DOMAIN_PROD="https://fito.wace.me" DEV_PORT=3643 # 모드 판단 MODE="dev" COMPOSE_FILE="$COMPOSE_DEV" CMD_ARG="" for arg in "$@"; do if [ "$arg" = "prod" ]; then MODE="prod" COMPOSE_FILE="$COMPOSE_PROD" else CMD_ARG="$arg" fi done echo "" echo "==========================================" echo " FITO PLM (Next.js) [$MODE]" echo "==========================================" echo "" # Docker 명령어 자동 감지 (docker compose v2 vs docker-compose v1) DC="docker compose" if ! docker compose version &>/dev/null; then if command -v docker-compose &>/dev/null; then DC="docker-compose" else echo "[ERROR] Docker Compose가 설치되어 있지 않습니다" exit 1 fi fi check_docker() { if ! command -v docker &>/dev/null; then echo "[ERROR] Docker가 설치되어 있지 않습니다" exit 1 fi if ! docker info &>/dev/null; then echo "[ERROR] Docker가 실행 중이 아닙니다" exit 1 fi } pull_latest() { echo "[1/4] Git 최신 소스 받기..." if [ -d .git ]; then git remote set-url origin "$GIT_URL" 2>/dev/null # 로컬 변경사항(.env.production 등) 임시 저장 git stash --include-untracked 2>/dev/null if ! git fetch origin; then echo "[WARN] git fetch 실패 — 현재 소스로 진행" git stash pop 2>/dev/null return fi # 현재 커밋 해시 저장 (start.sh 업데이트 감지용) OLD_HASH=$(git rev-parse HEAD 2>/dev/null) git reset --hard origin/main echo "[OK] 최신 소스 적용 완료" git log --oneline -3 # .env.production 등 stash 복원 git stash pop 2>/dev/null # sh 파일 실행 권한 부여 find "$SCRIPT_DIR" -name "*.sh" -exec chmod +x {} \; # start.sh 자체가 업데이트되었으면 새 버전으로 재실행 NEW_HASH=$(git rev-parse HEAD 2>/dev/null) if [ "$OLD_HASH" != "$NEW_HASH" ] && [ -z "$RESTARTED" ]; then echo "" echo "[INFO] start.sh 업데이트 감지 — 새 버전으로 재실행합니다" echo "────────────────────────────────────────" RESTARTED=1 exec "$SCRIPT_DIR/start.sh" "${ORIG_ARGS[@]}" fi else echo "[INFO] Git 저장소 아님 — 건너뜀" fi echo "" } check_env() { if [ "$MODE" = "prod" ]; then if [ ! -f .env.production ]; then echo "[ERROR] .env.production 파일이 없습니다" echo "" echo " cp .env.production.example .env.production" echo " vi .env.production # DATABASE_URL, NEXTAUTH_SECRET, AES_KEY 등 입력" echo "" exit 1 fi fi } prepare_dirs() { if [ "$MODE" = "prod" ]; then mkdir -p "${SCRIPT_DIR}/data_storage" fi } do_up() { check_docker check_env if [ "$MODE" = "prod" ]; then pull_latest fi prepare_dirs echo "[2/4] 이전 컨테이너 정리..." $DC -f "$COMPOSE_FILE" down 2>/dev/null docker image prune -f 2>/dev/null echo "" echo "[3/4] Docker 빌드..." $DC -f "$COMPOSE_FILE" build if [ $? -ne 0 ]; then echo "[ERROR] 빌드 실패" exit 1 fi echo "" echo "[4/4] 컨테이너 기동..." $DC -f "$COMPOSE_FILE" up -d echo "" sleep 3 if [ "$MODE" = "prod" ]; then echo "==========================================" echo " 운영 배포 완료!" echo "" echo " 사이트: $DOMAIN_PROD" echo " DB: 211.115.91.141:11140/fito" echo " 파일: $SCRIPT_DIR/data_storage/" echo "==========================================" else echo "==========================================" echo " 개발 컨테이너 시작 완료!" echo "" echo " 로컬: http://localhost:$DEV_PORT" echo " DB: 211.115.91.141:11140/fito" echo "==========================================" fi echo "" $DC -f "$COMPOSE_FILE" ps } CMD="${CMD_ARG:-up}" case "$CMD" in up|start) do_up ;; stop|down) $DC -f "$COMPOSE_FILE" down echo "중지 완료" ;; restart) do_up ;; logs) $DC -f "$COMPOSE_FILE" logs -f ;; status|ps) $DC -f "$COMPOSE_FILE" ps ;; pull) pull_latest ;; build) $DC -f "$COMPOSE_FILE" build --no-cache ;; clean) echo "컨테이너 + 이미지 + 볼륨 전체 삭제 (확인 필요)..." read -p "정말 삭제하시겠습니까? [y/N]: " confirm if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then $DC -f "$COMPOSE_FILE" down -v docker image prune -af echo "완료" else echo "취소" fi ;; *) echo "사용법: ./start.sh [명령] [prod]" echo "" echo "기본 기동:" echo " ./start.sh 로컬 개발 docker (localhost:$DEV_PORT)" echo " ./start.sh prod 운영 배포 ($DOMAIN_PROD)" echo "" echo "운영 명령:" echo " ./start.sh logs prod 서버 로그 tail" echo " ./start.sh stop prod 서버 중지" echo " ./start.sh restart prod 재시작 (git pull 포함)" echo " ./start.sh status prod 컨테이너 상태" echo " ./start.sh pull git 최신만 받기" echo " ./start.sh build prod 이미지 no-cache 재빌드" echo " ./start.sh clean prod 전체 삭제 (확인 필요)" echo "" echo "로컬 개발:" echo " npm run dev docker 없이 로컬 Node 실행 (또는 ./start-dev.sh)" ;; esac