232 lines
8.7 KiB
Bash
232 lines
8.7 KiB
Bash
#!/bin/bash
|
|
|
|
# ==============================================================================
|
|
# BizVibe Multi-Domain Deployment & Setup Script
|
|
# ==============================================================================
|
|
# 이 스크립트는 멀티 도메인 Nginx 환경에 BizVibe 서비스를 안전하게 배포합니다.
|
|
# 기존 서비스와의 포트 충돌을 방지하며 Nginx 설정을 자동으로 생성합니다.
|
|
# ==============================================================================
|
|
|
|
# 색상 정의
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 1. 포트 자동 할당 (충돌 방지)
|
|
# ------------------------------------------------------------------------------
|
|
echo -e "${CYAN}[1] 사용 가능한 포트 확인 중...${NC}"
|
|
|
|
# 사용 중인 포트 목록 가져오기
|
|
USED_PORTS=$(netstat -tuln | grep LISTEN | awk '{print $4}' | awk -F: '{print $NF}' | sort -n | uniq)
|
|
|
|
# 추천 포트 범위 (3000번대 -> 4000번대 순으로 검색)
|
|
# nginx_analysis.txt에 따르면 3000번은 whitedonkey가 사용 중일 수 있으므로 3001부터 시작
|
|
START_PORT=3001
|
|
END_PORT=4000
|
|
TARGET_PORT=""
|
|
|
|
for port in $(seq $START_PORT $END_PORT); do
|
|
if ! echo "$USED_PORTS" | grep -q "^$port$"; then
|
|
TARGET_PORT=$port
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -z "$TARGET_PORT" ]; then
|
|
echo -e "${RED}❌ 사용 가능한 포트를 찾을 수 없습니다 (3001-4000). 수동으로 설정해주세요.${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "${GREEN}✅ BizVibe 백엔드 포트로 ${TARGET_PORT}번을 할당했습니다.${NC}"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 2. 필수 패키지 설치
|
|
# ------------------------------------------------------------------------------
|
|
echo -e "${CYAN}[2] 시스템 패키지 업데이트 및 필수 라이브러리 설치...${NC}"
|
|
|
|
# Node.js, FFmpeg, 한글 폰트 등 필수 패키지 설치
|
|
if [ -x "$(command -v apt-get)" ]; then
|
|
sudo apt-get update
|
|
sudo apt-get install -y ffmpeg fonts-noto-cjk nginx certbot python3-certbot-nginx \
|
|
ca-certificates fonts-liberation libasound2t64 libatk-bridge2.0-0 libatk1.0-0 \
|
|
libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 \
|
|
libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 \
|
|
libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 \
|
|
libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release \
|
|
wget xdg-utils
|
|
else
|
|
echo -e "${YELLOW}⚠️ apt-get을 찾을 수 없습니다. 패키지 설치를 건너뜁니다.${NC}"
|
|
fi
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 3. 프로젝트 빌드 및 설정
|
|
# ------------------------------------------------------------------------------
|
|
echo -e "${CYAN}[3] 프로젝트 의존성 설치 및 빌드...${NC}"
|
|
|
|
# 프론트엔드 의존성
|
|
npm install
|
|
|
|
# 백엔드 의존성
|
|
cd server
|
|
npm install --legacy-peer-deps
|
|
cd ..
|
|
|
|
# 포트 설정 적용 (vite.config.ts 및 server/index.js 수정 필요 시 환경 변수로 처리 권장)
|
|
# 여기서는 .env 파일 생성/수정으로 처리
|
|
if [ ! -f .env ]; then
|
|
echo "VITE_GEMINI_API_KEY=YOUR_GEMINI_KEY" > .env
|
|
echo "SUNO_API_KEY=YOUR_SUNO_KEY" >> .env
|
|
echo -e "${YELLOW}⚠️ .env 파일이 생성되었습니다. API 키를 입력해야 합니다.${NC}"
|
|
fi
|
|
|
|
# 프론트엔드 URL 설정 (배포 시 도메인 주소로 설정)
|
|
# 이 부분은 아래 도메인 입력 후에 업데이트하도록 이동하거나, 여기서 미리 placeholder로 설정
|
|
if ! grep -q "FRONTEND_URL=" .env; then
|
|
echo "FRONTEND_URL=http://localhost:3000" >> .env
|
|
fi
|
|
|
|
# 백엔드 포트 환경변수 추가
|
|
if grep -q "PORT=" .env; then
|
|
sed -i "s/^PORT=.*/PORT=$TARGET_PORT/" .env
|
|
else
|
|
echo "PORT=$TARGET_PORT" >> .env
|
|
fi
|
|
|
|
# 프론트엔드 빌드 (Vite가 .env의 설정을 참조함)
|
|
npm run build
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 4. PM2 프로세스 관리 (무중단 배포)
|
|
# ------------------------------------------------------------------------------
|
|
echo -e "${CYAN}[4] PM2로 서비스 실행...${NC}"
|
|
|
|
# PM2 설치 확인
|
|
if ! command -v pm2 &> /dev/null; then
|
|
npm install -g pm2
|
|
fi
|
|
|
|
# 기존 프로세스 정리 (이름 기준)
|
|
pm2 delete bizvibe-backend 2>/dev/null
|
|
|
|
# 백엔드 실행 (서버 사이드 렌더링 포함)
|
|
# 정적 파일(프론트엔드 dist)도 백엔드(Express)에서 서빙하도록 server/index.js가 수정되어야 함.
|
|
# 현재 server/index.js는 API만 제공하므로, Nginx가 프론트엔드를 서빙하고 API는 백엔드로 프록시하는 구조가 적합.
|
|
|
|
cd server
|
|
pm2 start index.js --name "bizvibe-backend" -- --port $TARGET_PORT
|
|
cd ..
|
|
pm2 save
|
|
|
|
echo -e "${GREEN}✅ PM2 서비스 시작 완료 (Port: $TARGET_PORT)${NC}"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# 5. Nginx 가상호스트 설정 (자동 생성)
|
|
# ------------------------------------------------------------------------------
|
|
echo -e "${CYAN}[5] Nginx 설정 파일 생성...${NC}"
|
|
|
|
# 사용자에게 도메인 입력 받기
|
|
read -p "배포할 도메인 주소를 입력하세요 (예: bizvibe.ktenterprise.net): " DOMAIN_NAME
|
|
|
|
if [ -z "$DOMAIN_NAME" ]; then
|
|
echo -e "${RED}❌ 도메인이 입력되지 않아 Nginx 설정을 건너뜁니다.${NC}"
|
|
else
|
|
# .env 파일에 FRONTEND_URL 업데이트 (https://도메인)
|
|
# 기존 값이 있으면 교체, 없으면 추가
|
|
if grep -q "FRONTEND_URL=" .env; then
|
|
sed -i "s|^FRONTEND_URL=.*|FRONTEND_URL=https://$DOMAIN_NAME|" .env
|
|
else
|
|
echo "FRONTEND_URL=https://$DOMAIN_NAME" >> .env
|
|
fi
|
|
echo -e "${GREEN}✅ .env 파일에 FRONTEND_URL=https://$DOMAIN_NAME 설정 완료${NC}"
|
|
|
|
# PM2 재시작하여 변경된 환경변수 적용
|
|
pm2 restart bizvibe-backend
|
|
|
|
NGINX_CONF="/etc/nginx/sites-available/$DOMAIN_NAME"
|
|
PROJECT_ROOT=$(pwd)
|
|
|
|
# Nginx 설정 파일 작성
|
|
sudo tee $NGINX_CONF > /dev/null <<EOF
|
|
server {
|
|
listen 80;
|
|
server_name $DOMAIN_NAME;
|
|
|
|
# 대용량 파일 업로드 허용 (영상 생성 요청 시 Base64 데이터 전송 때문)
|
|
client_max_body_size 500M;
|
|
|
|
# 프론트엔드 정적 파일 서빙
|
|
location / {
|
|
# 로컬(서버 내부) 및 공인 IP 접속은 인증 제외 (비활성화)
|
|
# satisfy any;
|
|
# allow 127.0.0.1;
|
|
# allow 116.125.140.86; # 서버 공인 IP 추가
|
|
# deny all;
|
|
|
|
# 기본 인증 설정 (외부 접속 시) - 비활성화
|
|
# auth_basic "Restricted Area";
|
|
# auth_basic_user_file /etc/nginx/.htpasswd;
|
|
|
|
root $PROJECT_ROOT/dist;
|
|
index index.html;
|
|
try_files \$uri \$uri/ /index.html;
|
|
}
|
|
|
|
# 백엔드 API 프록시
|
|
location /api {
|
|
proxy_pass http://127.0.0.1:$TARGET_PORT;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade \$http_upgrade;
|
|
proxy_set_header Connection 'upgrade';
|
|
proxy_set_header Host \$host;
|
|
proxy_cache_bypass \$http_upgrade;
|
|
proxy_set_header X-Real-IP \$remote_addr;
|
|
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
proxy_read_timeout 300s; # 긴 API 응답 시간 허용 (Suno 생성 등)
|
|
}
|
|
|
|
# 렌더링/업로드 엔드포인트 프록시
|
|
location /render {
|
|
proxy_pass http://127.0.0.1:$TARGET_PORT;
|
|
proxy_set_header Host \$host;
|
|
proxy_read_timeout 300s; # 긴 렌더링 시간 허용
|
|
}
|
|
|
|
location /auth {
|
|
proxy_pass http://127.0.0.1:$TARGET_PORT;
|
|
proxy_set_header Host \$host;
|
|
}
|
|
|
|
location /oauth2callback {
|
|
proxy_pass http://127.0.0.1:$TARGET_PORT;
|
|
proxy_set_header Host \$host;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# 심볼릭 링크 생성
|
|
sudo ln -sfn $NGINX_CONF /etc/nginx/sites-enabled/
|
|
|
|
# 설정 검증 및 재시작
|
|
if sudo nginx -t; then
|
|
sudo systemctl reload nginx
|
|
echo -e "${GREEN}✅ Nginx 설정 완료! http://$DOMAIN_NAME 에서 접속 가능합니다.${NC}"
|
|
|
|
# SSL 인증서 발급 여부 확인
|
|
read -p "SSL 인증서(Let's Encrypt)를 발급하시겠습니까? (y/n): " INSTALL_SSL
|
|
if [[ "$INSTALL_SSL" == "y" || "$INSTALL_SSL" == "Y" ]]; then
|
|
sudo certbot --nginx -d $DOMAIN_NAME
|
|
fi
|
|
else
|
|
echo -e "${RED}❌ Nginx 설정 오류 발생. 설정 파일을 확인하세요: $NGINX_CONF${NC}"
|
|
fi
|
|
fi
|
|
|
|
echo -e "${CYAN}======================================================${NC}"
|
|
echo -e "${GREEN}🎉 배포 완료!${NC}"
|
|
echo -e "Backend Port: $TARGET_PORT"
|
|
echo -e "Domain: http://$DOMAIN_NAME"
|
|
echo -e "${CYAN}======================================================${NC}"
|