Skip to content

Merge pull request #276 from Coffect/feat/jun-follower-following-list-up #239

Merge pull request #276 from Coffect/feat/jun-follower-following-list-up

Merge pull request #276 from Coffect/feat/jun-follower-following-list-up #239

Workflow file for this run

name: deploy-main
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Configure SSH
run: |
mkdir -p ~/.ssh
echo "${{ secrets.EC2_SSH_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
cat > ~/.ssh/config << EOF
Host playground-umc-8th
HostName ${{ secrets.EC2_HOST }}
User ubuntu
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
LogLevel ERROR
EOF
- name: Test SSH Connection
run: |
echo "🔍 SSH 연결 테스트 중..."
# SSH 연결 테스트 (여러 번 시도)
for i in {1..3}; do
echo "SSH 연결 시도 $i/3..."
if ssh -o ConnectTimeout=10 playground-umc-8th "echo '✅ SSH Connection Successful ($i/3)'"; then
echo "✅ SSH 연결 성공"
break
else
if [ $i -eq 3 ]; then
echo "❌ SSH 연결 실패 - 연결 정보 확인 필요"
echo "디버깅 정보:"
echo "- SSH 키 권한 확인: $(ls -la ~/.ssh/id_rsa)"
echo "- SSH 설정 확인:"
cat ~/.ssh/config
exit 1
else
echo "⚠️ 연결 실패, 재시도 중..."
sleep 2
fi
fi
done
- name: Clean Old Logs and Backups
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "🧹 이전 로그 및 백업 파일 정리 중..."
# nohup.out 백업 파일들 모두 삭제
rm -f nohup.out.backup.* 2>/dev/null || true
echo "✅ 이전 백업 파일들 삭제 완료"
# 현재 nohup.out 파일도 삭제 (새로 시작하기 위해)
if [ -f nohup.out ]; then
echo "📄 기존 nohup.out 파일 삭제 중..."
rm -f nohup.out
echo "✅ 기존 nohup.out 삭제 완료"
fi
# logs 디렉토리가 있다면 오래된 로그 정리 (선택사항)
if [ -d logs ]; then
echo "📁 logs 디렉토리 정리 중..."
# 7일 이상 된 로그 파일 삭제
find logs -type f -mtime +7 -delete 2>/dev/null || true
echo "✅ 오래된 로그 파일 정리 완료"
fi
# 디스크 공간 확인
echo "💾 현재 디스크 사용량:"
df -h . | head -2
# 정리 후 파일 목록 확인
echo "📋 정리 후 파일 목록:"
ls -la | grep -E "(nohup|log)" || echo "로그 관련 파일 없음"
'
- name: Analyze Changes and Dependencies
id: analyze
run: |
# 변경된 파일들 분석 (안전한 방식)
CHANGED_FILES=$(git diff HEAD^1 --name-only | tr '\n' ' ')
echo "changed-files=${CHANGED_FILES}" >> $GITHUB_OUTPUT
# package.json/package-lock.json 변경 확인 (수정된 부분)
PACKAGE_CHANGED=$(git diff HEAD^1 --name-only | grep -E "(package\.json|package-lock\.json)" | tr '\n' ' ' | sed 's/[[:space:]]*$//')
if [ ! -z "$PACKAGE_CHANGED" ]; then
echo "package-changed=true" >> $GITHUB_OUTPUT
else
echo "package-changed=false" >> $GITHUB_OUTPUT
fi
# 소스 코드 변경 확인
SOURCE_CHANGED=$(git diff HEAD^1 --name-only | grep -E "\.(ts|js)$" || echo "")
if [ ! -z "$SOURCE_CHANGED" ]; then
echo "source-changed=true" >> $GITHUB_OUTPUT
else
echo "source-changed=false" >> $GITHUB_OUTPUT
fi
# Prisma 스키마 변경 확인
PRISMA_CHANGED=$(git diff HEAD^1 --name-only | grep "prisma/" || echo "")
if [ ! -z "$PRISMA_CHANGED" ]; then
echo "prisma-changed=true" >> $GITHUB_OUTPUT
else
echo "prisma-changed=false" >> $GITHUB_OUTPUT
fi
# 원격 dependencies 상태 확인
REMOTE_DEPS_EXISTS=$(ssh playground-umc-8th "test -d /home/ubuntu/coffect-BE/node_modules && echo 'true' || echo 'false'")
echo "remote-deps-exists=${REMOTE_DEPS_EXISTS}" >> $GITHUB_OUTPUT
# package-lock.json 해시 비교
DEPS_INSTALL_NEEDED="false"
if [ "$REMOTE_DEPS_EXISTS" = "false" ] || [ "$PACKAGE_CHANGED" = "true" ]; then
DEPS_INSTALL_NEEDED="true"
else
REMOTE_LOCK_HASH=$(ssh playground-umc-8th "test -f /home/ubuntu/coffect-BE/package-lock.json && md5sum /home/ubuntu/coffect-BE/package-lock.json | cut -d' ' -f1 || echo 'none'")
LOCAL_LOCK_HASH=$(md5sum package-lock.json | cut -d' ' -f1)
if [ "$REMOTE_LOCK_HASH" != "$LOCAL_LOCK_HASH" ]; then
DEPS_INSTALL_NEEDED="true"
fi
fi
echo "deps-install-needed=${DEPS_INSTALL_NEEDED}" >> $GITHUB_OUTPUT
echo "=== 변경 분석 결과 ==="
echo "Dependencies 설치 필요: ${DEPS_INSTALL_NEEDED}"
echo "Package 변경: ${PACKAGE_CHANGED}"
echo "소스 변경: $([ ! -z "$SOURCE_CHANGED" ] && echo '있음' || echo '없음')"
echo "Prisma 변경: $([ ! -z "$PRISMA_CHANGED" ] && echo '있음' || echo '없음')"
echo "Prisma Client 생성 조건: $([ "$PRISMA_CHANGED" != "" ] || [ "$DEPS_INSTALL_NEEDED" = "true" ] || [ "$SOURCE_CHANGED" != "" ] && echo '실행됨' || echo '건너뜀')"
- name: Efficient File Sync
run: |
ssh playground-umc-8th '
# 백업 및 디렉토리 준비
mkdir -p /home/ubuntu/coffect-BE-backup /home/ubuntu/coffect-BE
# 빠른 백업 (중요 파일만)
if [ -d /home/ubuntu/coffect-BE ]; then
cp /home/ubuntu/coffect-BE/.env /home/ubuntu/coffect-BE-backup/ 2>/dev/null || true
cp /home/ubuntu/coffect-BE/package-lock.json /home/ubuntu/coffect-BE-backup/ 2>/dev/null || true
fi
'
# 변경된 파일이 있는지 확인
CHANGED_COUNT=$(git diff HEAD^1 --name-only | wc -l)
if [ "$CHANGED_COUNT" -gt 0 ]; then
echo "📁 변경된 파일들을 효율적으로 동기화 중... (${CHANGED_COUNT}개 파일)"
rsync -avz --progress \
--exclude 'node_modules' \
--exclude '.git' \
--exclude 'logs' \
--exclude 'dist' \
--exclude '.env' \
--exclude 'nohup.out*' \
./ playground-umc-8th:/home/ubuntu/coffect-BE/
else
echo "📁 변경된 파일이 없어 동기화를 건너뜁니다."
fi
- name: Smart Dependencies Installation
if: steps.analyze.outputs.deps-install-needed == 'true'
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "📦 Dependencies 효율적 설치 중..."
# package.json 파일 무결성 확인 및 복구
echo "🔍 package.json 파일 확인 중..."
if [ -f package.json ]; then
# JSON 유효성 검사
if node -e "JSON.parse(require(\"fs\").readFileSync(\"package.json\", \"utf8\"))" 2>/dev/null; then
echo "✅ package.json 파일이 유효합니다"
else
echo "❌ package.json 파일이 손상되었습니다. 백업에서 복구 시도..."
# 백업에서 복구 시도
if [ -f /home/ubuntu/coffect-BE-backup/package.json ]; then
cp /home/ubuntu/coffect-BE-backup/package.json .
echo "✅ 백업에서 package.json 복구 완료"
else
echo "❌ 백업 파일도 없습니다. 배포 중단"
exit 1
fi
fi
fi
# CPU 과부하 방지를 위한 설정
export NODE_OPTIONS="--max-old-space-size=768"
export NPM_CONFIG_AUDIT=false
export NPM_CONFIG_FUND=false
export NPM_CONFIG_PROGRESS=false
export NPM_CONFIG_PREFER_OFFLINE=true
# 기존 node_modules 및 package-lock.json 정리
echo "🧹 기존 dependencies 정리 중..."
rm -rf node_modules package-lock.json 2>/dev/null || true
# npm 설치 최적화
echo "🆕 Dependencies 클린 설치..."
npm ci --no-audit --no-fund --prefer-offline --no-optional
echo "✅ Dependencies 설치 완료"
'
- name: Generate Prisma Client
if: steps.analyze.outputs.prisma-changed == 'true' || steps.analyze.outputs.deps-install-needed == 'true' || steps.analyze.outputs.source-changed == 'true'
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "🔧 Prisma 클라이언트 생성 중..."
export NODE_OPTIONS="--max-old-space-size=512"
# MySQL Prisma 클라이언트 생성
echo "📋 MySQL Prisma 클라이언트 생성..."
npx prisma generate --schema=prisma/mysql/schema.prisma
# MongoDB Prisma 클라이언트 생성
echo "📋 MongoDB Prisma 클라이언트 생성..."
npx prisma generate --schema=prisma/mongodb/schema.prisma
echo "✅ Prisma 클라이언트 생성 완료"
'
- name: Fix Source Code Imports
if: steps.analyze.outputs.source-changed == 'true' || steps.analyze.outputs.deps-install-needed == 'true'
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "🔍 Prisma import 경로 수정 중..."
# 효율적인 파일 수정 (안전한 sed 패턴 사용)
find src/ -name "*.ts" -type f | while read file; do
if grep -q "generated/prisma" "$file" 2>/dev/null; then
echo "수정: $file"
# from import 수정
sed -i "s|from [\"'\''].*generated/prisma[\"'\'']|from '\''@prisma/client'\''|g" "$file"
# require 수정 (안전한 패턴)
sed -i "s|require([\"'\''].*generated/prisma[\"'\''])|require('\''@prisma/client'\'')|g" "$file"
fi
done
echo "✅ Import 경로 수정 완료"
'
- name: Create Environment File
run: |
ssh playground-umc-8th "
# 기본 환경 변수들 생성
cat > /home/ubuntu/coffect-BE/.env << 'EOF'
DATABASE_NAME=${{ secrets.DATABASE_NAME }}
DATABASE_Endpoint=${{ secrets.DATABASE_Endpoint }}
DATABASE_HOST=${{ secrets.DATABASE_HOST }}
DATABASE_PORT=${{ secrets.DATABASE_PORT }}
DATABASE_USERNAME=${{ secrets.DATABASE_USERNAME }}
DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }}
EC2_PORT=${{ secrets.EC2_PORT }}
JWT_SECRET=${{ secrets.JWT_SECRET }}
JWT_REFRESH=${{ secrets.JWT_REFRESH }}
S3_ACCESS_KEY=${{ secrets.S3_ACCESS_KEY }}
S3_SECRET_KEY=${{ secrets.S3_SECRET_KEY }}
S3_NAME=${{ secrets.S3_NAME }}
ENV=${{ secrets.ENV }}
FIREBASE_PROJECT_ID=${{ secrets.FIREBASE_PROJECT_ID }}
FIREBASE_CLIENT_EMAIL=${{ secrets.FIREBASE_CLIENT_EMAIL }}
FIREBASE_PRIVATE_KEY=${{ secrets.FIREBASE_PRIVATE_KEY }}
MONGODB_URL=${{ secrets.MONGODB_URL }}
EOF
"
- name: Fix Prisma Configuration
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "🔧 Prisma 설정 확인 및 수정 중..."
# package.json에서 start 스크립트 확인
echo "📋 package.json start 스크립트:"
cat package.json | grep -A 5 -B 5 "scripts"
# package.json start 스크립트 수정
echo "🔧 package.json start 스크립트 수정 중..."
# 백업
cp package.json package.json.backup
# start 스크립트를 수정하여 스키마 경로를 명시적으로 지정
cat package.json | jq '\''.scripts.start = "npm run prisma && npm run build && node ./dist/index.js"'\'' > package.json.tmp && mv package.json.tmp package.json
# 수정된 내용 확인
echo "📋 수정된 start 스크립트:"
cat package.json | grep -A 5 -B 5 "scripts"
echo "✅ Prisma 설정 수정 완료"
'
- name: Smart Build Process
if: steps.analyze.outputs.source-changed == 'true' || steps.analyze.outputs.deps-install-needed == 'true'
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "🏗️ 효율적 빌드 프로세스 시작..."
export NODE_OPTIONS="--max-old-space-size=1024"
# 기존 dist 제거 (필요시에만)
if [ -d dist ]; then
rm -rf dist
fi
# 빌드 실행 (package.json의 build 스크립트 사용)
echo "📋 빌드 시작..."
if npm run build; then
echo "✅ 빌드 성공"
ls -la dist/ | head -3
else
echo "❌ 빌드 실패"
exit 1
fi
'
- name: Stop Existing Application
run: |
ssh playground-umc-8th '
set -e # 에러 시 즉시 종료하지 않도록 제거
cd /home/ubuntu/coffect-BE || { echo "디렉토리 이동 실패"; mkdir -p /home/ubuntu/coffect-BE; cd /home/ubuntu/coffect-BE; }
echo "🛑 기존 애플리케이션 정리 중..."
# SSH 연결 상태 확인
echo "SSH 연결 상태: OK"
echo "현재 디렉토리: $(pwd)"
echo "사용자: $(whoami)"
# PID 파일 기반 종료 (안전한 방식)
if [ -f app.pid ]; then
PID=$(cat app.pid)
echo "PID 파일 발견: $PID"
if ps -p $PID > /dev/null 2>&1; then
echo "애플리케이션 종료 중 (PID: $PID)..."
kill -TERM $PID 2>/dev/null || echo "TERM 신호 전송 실패"
sleep 3
if ps -p $PID > /dev/null 2>&1; then
echo "강제 종료 실행..."
kill -KILL $PID 2>/dev/null || echo "KILL 신호 전송 실패"
fi
else
echo "PID $PID 프로세스가 이미 종료됨"
fi
rm -f app.pid
else
echo "PID 파일 없음"
fi
# 포트 기반 프로세스 정리 (더 안전한 방식)
if [ ! -z "${{ secrets.EC2_PORT }}" ]; then
echo "포트 ${{ secrets.EC2_PORT }} 프로세스 확인 중..."
# lsof가 있는 경우에만 실행
if command -v lsof >/dev/null 2>&1; then
PORT_PIDS=$(lsof -ti:${{ secrets.EC2_PORT }} 2>/dev/null || echo "")
if [ ! -z "$PORT_PIDS" ]; then
echo "포트 프로세스 발견: $PORT_PIDS"
for pid in $PORT_PIDS; do
echo "프로세스 $pid 종료 중..."
kill -TERM $pid 2>/dev/null || echo "TERM 신호 실패: $pid"
done
sleep 2
for pid in $PORT_PIDS; do
if ps -p $pid > /dev/null 2>&1; then
echo "강제 종료: $pid"
kill -KILL $pid 2>/dev/null || echo "KILL 신호 실패: $pid"
fi
done
else
echo "포트 사용 중인 프로세스 없음"
fi
else
echo "lsof 명령어 없음 - 포트 정리 건너뜀"
fi
fi
# Node.js 프로세스 정리 (더 안전한 방식)
echo "Node.js 프로세스 정리 중..."
# pkill 대신 더 안전한 방식 사용
ps aux | grep -E "(coffect-BE|npm.*dev|node.*dist)" | grep -v grep | awk "{print \$2}" | while read pid; do
if [ ! -z "$pid" ]; then
echo "Node.js 프로세스 종료: $pid"
kill -TERM $pid 2>/dev/null || echo "프로세스 $pid 종료 실패"
fi
done
sleep 2
echo "✅ 정리 완료"
' || { echo "프로세스 정리 중 일부 오류 발생했지만 계속 진행"; exit 0; }
- name: Install Required Tools
run: |
ssh playground-umc-8th '
echo "🔧 필수 도구 설치 확인 중..."
# nohup 설치 확인 및 설치
if ! command -v nohup &> /dev/null; then
echo "📦 nohup이 설치되지 않았습니다. 설치 중..."
sudo apt-get update -qq
sudo apt-get install -y coreutils
echo "✅ nohup 설치 완료"
else
echo "✅ nohup이 이미 설치되어 있습니다"
fi
# netstat 설치 확인 및 설치
if ! command -v netstat &> /dev/null; then
echo "📦 netstat이 설치되지 않았습니다. 설치 중..."
sudo apt-get install -y net-tools
echo "✅ netstat 설치 완료"
else
echo "✅ netstat이 이미 설치되어 있습니다"
fi
# lsof 설치 확인 및 설치
if ! command -v lsof &> /dev/null; then
echo "📦 lsof가 설치되지 않았습니다. 설치 중..."
sudo apt-get install -y lsof
echo "✅ lsof 설치 완료"
else
echo "✅ lsof가 이미 설치되어 있습니다"
fi
echo "✅ 모든 필수 도구 설치 완료"
'
- name: Start Application with nohup
run: |
ssh -o ConnectTimeout=30 playground-umc-8th '
set +e
cd /home/ubuntu/coffect-BE || { echo "디렉토리 이동 실패"; exit 1; }
mkdir -p logs
echo "🚀 애플리케이션 시작 중..."
echo "=== 환경 변수 확인 ==="
echo "NODE_ENV: production"
echo "PORT: ${{ secrets.EC2_PORT }}"
echo "현재 사용자: $(whoami)"
echo "현재 디렉토리: $(pwd)"
# 기존 nohup.out 파일 완전 삭제 (백업하지 않음)
if [ -f nohup.out ]; then
echo "🗑️ 기존 nohup.out 파일 삭제 중..."
rm -f nohup.out
echo "✅ 기존 nohup.out 삭제 완료"
fi
# 백업 파일들도 모두 삭제
echo "🗑️ 모든 nohup 백업 파일 삭제 중..."
rm -f nohup.out.backup.* 2>/dev/null || true
echo "✅ 백업 파일 삭제 완료"
echo "📋 시작 전 확인사항:"
echo "- package.json 존재: $([ -f package.json ] && echo "✅" || echo "❌")"
echo "- node_modules 존재: $([ -d node_modules ] && echo "✅" || echo "❌")"
echo "- dist 디렉토리 존재: $([ -d dist ] && echo "✅" || echo "❌")"
# Prisma 스키마 파일 확인
echo "📋 Prisma 스키마 파일 확인:"
if [ -f prisma/mysql/schema.prisma ]; then
echo "✅ MySQL 스키마 존재"
else
echo "❌ MySQL 스키마 없음"
fi
if [ -f prisma/mongodb/schema.prisma ]; then
echo "✅ MongoDB 스키마 존재"
else
echo "❌ MongoDB 스키마 없음"
fi
echo "🚀 nohup으로 애플리케이션 시작..."
# Prisma 클라이언트를 먼저 생성하고 애플리케이션 시작
echo "🔧 Prisma 클라이언트 생성 중..."
# 환경 변수를 직접 설정하여 nohup 실행 (수정된 방식)
NODE_ENV=production \
PORT=${{ secrets.EC2_PORT }} \
DATABASE_HOST=${{ secrets.DATABASE_HOST }} \
DATABASE_PORT=${{ secrets.DATABASE_PORT }} \
DATABASE_NAME=${{ secrets.DATABASE_NAME }} \
DATABASE_USERNAME=${{ secrets.DATABASE_USERNAME }} \
DATABASE_PASSWORD="${{ secrets.DATABASE_PASSWORD }}" \
JWT_SECRET="${{ secrets.JWT_SECRET }}" \
JWT_REFRESH="${{ secrets.JWT_REFRESH }}" \
S3_ACCESS_KEY="${{ secrets.S3_ACCESS_KEY }}" \
S3_SECRET_KEY="${{ secrets.S3_SECRET_KEY }}" \
S3_NAME="${{ secrets.S3_NAME }}" \
ENV="${{ secrets.ENV }}" \
FIREBASE_PROJECT_ID="${{ secrets.FIREBASE_PROJECT_ID }}" \
FIREBASE_CLIENT_EMAIL="${{ secrets.FIREBASE_CLIENT_EMAIL }}" \
FIREBASE_PRIVATE_KEY="${{ secrets.FIREBASE_PRIVATE_KEY }}" \
MONGODB_URL="${{ secrets.MONGODB_URL }}" \
nohup sh -c "
echo \"=== 애플리케이션 시작 \$(date) ===\"
echo \"Prisma 클라이언트 생성 중...\"
# MySQL Prisma 클라이언트 생성
if [ -f prisma/mysql/schema.prisma ]; then
echo \"MySQL Prisma 클라이언트 생성 중...\"
npx prisma generate --schema=prisma/mysql/schema.prisma || echo \"MySQL Prisma 생성 실패\"
fi
# MongoDB Prisma 클라이언트 생성
if [ -f prisma/mongodb/schema.prisma ]; then
echo \"MongoDB Prisma 클라이언트 생성 중...\"
npx prisma generate --schema=prisma/mongodb/schema.prisma || echo \"MongoDB Prisma 생성 실패\"
fi
echo \"빌드 시작...\"
npm run build || { echo \"빌드 실패\"; exit 1; }
echo \"애플리케이션 시작...\"
node ./dist/index.js
" > nohup.out 2>&1 &
APP_PID=$!
echo $APP_PID > app.pid
echo "✅ 애플리케이션 시작됨 (PID: $APP_PID)"
echo "⏳ nohup.out 파일 생성 대기 중..."
for j in {1..10}; do
if [ -f nohup.out ]; then
echo "✅ nohup.out 파일 생성 확인됨 (시도 $j/10)"
echo "📄 nohup.out 초기 내용:"
head -10 nohup.out 2>/dev/null || echo "아직 내용 없음"
break
else
echo "⏳ nohup.out 생성 대기... ($j/10)"
sleep 1
fi
done
if [ ! -f nohup.out ]; then
echo "⚠️ nohup.out 파일이 생성되지 않았습니다"
echo "현재 디렉토리 파일 목록:"
ls -la | grep -E "(nohup|log)" || echo "로그 파일 없음"
fi
echo "⏳ 프로세스 상태 확인 중..."
for i in {1..25}; do
if ps -p $APP_PID > /dev/null 2>&1; then
echo "✅ 프로세스 정상 실행 중 (확인 $i/25)"
if [ -f nohup.out ] && [ -s nohup.out ]; then
echo "📄 nohup.out 최신 내용:"
tail -5 nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
fi
# 더 긴 시간 기다리기 (Prisma 생성 + 빌드 시간 고려)
if [ ! -z "${{ secrets.EC2_PORT }}" ] && command -v netstat >/dev/null 2>&1; then
if netstat -ln 2>/dev/null | grep -q ":${{ secrets.EC2_PORT }}"; then
echo "✅ 포트 ${{ secrets.EC2_PORT }} 바인딩 확인"
break
else
echo "⏳ 포트 바인딩 대기 중... (확인 $i/25)"
fi
else
if [ $i -ge 15 ]; then
echo "✅ 프로세스 실행 확인 완료"
break
fi
fi
else
echo "❌ 프로세스 실행 실패 (확인 $i/25)"
echo "=== 상세 에러 분석 ==="
if [ -f nohup.out ]; then
echo "📄 nohup.out 전체 내용:"
cat nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
else
echo "❌ nohup.out 파일이 존재하지 않습니다"
echo "📁 현재 디렉토리 내용:"
ls -la | head -10
fi
echo "=== 시스템 상태 ==="
echo "💾 메모리 사용량:"
free -h 2>/dev/null || echo "메모리 정보 없음"
echo "💾 디스크 사용량:"
df -h . 2>/dev/null || echo "디스크 정보 없음"
echo "❌ 프로세스 시작 실패 - 종료"
exit 1
fi
sleep 3
done
if ps -p $APP_PID > /dev/null 2>&1; then
echo "✅ 애플리케이션 성공적으로 시작됨"
echo "📊 프로세스 정보:"
ps -p $APP_PID -o pid,ppid,cmd,etime 2>/dev/null || echo "프로세스 정보 조회 실패"
if [ -f nohup.out ]; then
echo "📄 nohup.out 파일 상태:"
ls -lh nohup.out
if [ -s nohup.out ]; then
echo "📄 nohup.out 최신 내용 (마지막 10줄):"
tail -10 nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
else
echo "⚠️ nohup.out 파일이 비어있습니다"
fi
else
echo "⚠️ nohup.out 파일이 존재하지 않습니다"
fi
else
echo "❌ 애플리케이션 시작 최종 실패"
echo "=== 최종 디버깅 정보 ==="
echo "📁 현재 디렉토리 내용:"
ls -la 2>/dev/null || echo "디렉토리 내용 확인 불가"
if [ -f nohup.out ]; then
echo "📄 nohup.out 최종 내용:"
cat nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
fi
exit 1
fi
'
- name: Quick Health Check
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "🏥 상세한 헬스 체크..."
# 프로세스 상태 확인
if [ -f app.pid ]; then
PID=$(cat app.pid)
if kill -0 $PID 2>/dev/null; then
echo "✅ 프로세스 실행 중 (PID: $PID)"
# 프로세스 상세 정보
echo "📊 프로세스 정보:"
ps -p $PID -o pid,ppid,cmd,etime,pcpu,pmem
# nohup.out 파일 확인
if [ -f nohup.out ]; then
echo "📄 nohup.out 파일 상태:"
ls -lh nohup.out
echo "📄 nohup.out 최신 내용:"
tail -5 nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
else
echo "⚠️ nohup.out 파일이 존재하지 않습니다"
fi
# 포트 바인딩 확인
if [ ! -z "${{ secrets.EC2_PORT }}" ]; then
echo "🔍 포트 ${{ secrets.EC2_PORT }} 바인딩 확인:"
netstat -ln 2>/dev/null | grep ":${{ secrets.EC2_PORT }}" || echo "포트 바인딩 없음"
# HTTP 응답 테스트 (더 긴 시간)
echo "🌐 HTTP 응답 테스트..."
for i in {1..5}; do
echo "시도 $i/5:"
# 외부 IP 테스트
if curl -f -s -m 10 http://${{ secrets.EC2_HOST }}:${{ secrets.EC2_PORT }}/ > /dev/null 2>&1; then
echo "✅ 외부 IP 응답 성공"
break
else
echo "❌ 외부 IP 응답 실패"
fi
if [ $i -lt 5 ]; then
echo "⏳ 3초 대기 후 재시도..."
sleep 3
fi
done
# 최종 상태 확인
if curl -f -s -m 5 http://localhost:${{ secrets.EC2_PORT }}/ > /dev/null 2>&1; then
echo "✅ 서버 정상 응답 확인"
else
echo "⚠️ 서버 응답 없음 - 로그 확인"
if [ -f nohup.out ]; then
echo "📄 nohup.out 최신 내용:"
tail -10 nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
fi
# 프로세스는 살아있지만 응답이 없는 경우
if kill -0 $PID 2>/dev/null; then
echo "⚠️ 프로세스는 실행 중이지만 서버 응답이 없습니다"
echo "이는 애플리케이션 초기화 중이거나 포트 바인딩 문제일 수 있습니다"
else
echo "❌ 프로세스가 종료되었습니다"
exit 1
fi
fi
else
echo "⚠️ 포트 미설정 - 프로세스 상태만 확인"
fi
else
echo "❌ 프로세스 실행 실패"
if [ -f nohup.out ]; then
echo "=== nohup.out 에러 내용 ==="
cat nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
fi
exit 1
fi
else
echo "❌ PID 파일 없음"
exit 1
fi
'
- name: Deployment Summary
if: always()
run: |
ssh playground-umc-8th '
cd /home/ubuntu/coffect-BE
echo "📊 배포 완료 요약"
echo "===================="
# 프로세스 상태
if [ -f app.pid ]; then
PID=$(cat app.pid)
if kill -0 $PID 2>/dev/null; then
echo "✅ 애플리케이션 실행 중 (PID: $PID)"
else
echo "❌ 애플리케이션 중지됨"
fi
else
echo "❌ PID 파일 없음"
fi
# nohup.out 파일 상태
if [ -f nohup.out ]; then
echo "✅ nohup.out 파일 존재 (크기: $(ls -lh nohup.out | awk \"{print \$5}\"))"
echo "📄 nohup.out 마지막 3줄:"
tail -3 nohup.out 2>/dev/null || echo "nohup.out 읽기 실패"
else
echo "❌ nohup.out 파일 없음"
fi
# 백업 파일 정리 확인
echo ""
echo "🧹 nohup 백업 파일 정리 상태:"
BACKUP_COUNT=$(ls -la | grep -c "nohup.out.backup" || echo "0")
if [ "$BACKUP_COUNT" -eq "0" ]; then
echo "✅ 백업 파일 없음 (정리 완료)"
else
echo "⚠️ 백업 파일 $BACKUP_COUNT개 존재"
ls -la | grep "nohup.out.backup" | head -5
fi
# 포트 상태 (빠른 확인)
if [ ! -z "${{ secrets.EC2_PORT }}" ]; then
if netstat -ln 2>/dev/null | grep -q ":${{ secrets.EC2_PORT }}"; then
echo "✅ 포트 ${{ secrets.EC2_PORT }} 리스닝 중"
else
echo "⚠️ 포트 ${{ secrets.EC2_PORT }} 대기 중"
fi
fi
echo ""
echo "📄 nohup.out 파일 실시간 모니터링 명령어:"
echo " tail -f nohup.out"
echo ""
echo "⏰ 배포 완료: $(date)"
'