-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.sh
More file actions
158 lines (128 loc) · 4.89 KB
/
deploy.sh
File metadata and controls
158 lines (128 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/bin/bash
# deploy.sh - Blue-Green 무중단 배포 스크립트
set -euo pipefail
echo "=== Blue-Green 배포 시작 ==="
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="${SCRIPT_DIR}"
COMPOSE_FILE="${REPO_ROOT}/docker/docker-compose.yml"
PROJECT="linkiving-core"
COMPOSE="sudo docker compose -p ${PROJECT} -f ${COMPOSE_FILE}"
# compose 파일 존재 확인
if [ ! -f "${COMPOSE_FILE}" ]; then
echo "❌ Compose file not found: ${COMPOSE_FILE}"
echo "현재 위치: $(pwd)"
echo "스크립트 위치: ${SCRIPT_DIR}"
exit 1
fi
echo "✅ Using compose file: ${COMPOSE_FILE}"
echo "✅ Using project name: ${PROJECT}"
echo "이미지 업데이트 중..."
if ! ${COMPOSE} pull; then
echo "❌ Docker 이미지 pull 실패! GitHub Actions 빌드를 확인해주세요."
echo "❌ 배포를 중단합니다."
exit 1
fi
echo "✅ 새로운 이미지가 성공적으로 pull되었습니다."
echo "사용하지 않는 이미지 정리 중..."
sudo docker image prune -f
# 현재 활성화된 컨테이너 확인
EXIST_BLUE=$(sudo docker ps --filter "name=blue" --filter "status=running" -q)
if [ -z "$EXIST_BLUE" ]; then
echo "BLUE 컨테이너 실행"
${COMPOSE} up -d blue
BEFORE_COLOR="green"
AFTER_COLOR="blue"
BEFORE_PORT=8081
AFTER_PORT=8080
else
echo "GREEN 컨테이너 실행"
${COMPOSE} up -d green
BEFORE_COLOR="blue"
AFTER_COLOR="green"
BEFORE_PORT=8080
AFTER_PORT=8081
fi
echo "${AFTER_COLOR} server up (port:${AFTER_PORT})"
# 서버 응답 확인 (헬스체크)
echo "서버 헬스체크 시작..."
HEALTH_CHECK_COUNT=0
MAX_RETRY=30 # 최대 5분 대기 (10초 * 30회)
HEALTH_URL="http://127.0.0.1:${AFTER_PORT}/health-check"
while [ $HEALTH_CHECK_COUNT -lt $MAX_RETRY ]; do
HEALTH_CHECK_COUNT=$((HEALTH_CHECK_COUNT + 1))
echo "서버 응답 확인중 (${HEALTH_CHECK_COUNT}/${MAX_RETRY})"
# curl로 헬스체크 (타임아웃 5초, 실패 시 failed 문자열로 치환)
UP=$(curl -s --connect-timeout 5 --max-time 10 "${HEALTH_URL}" 2>/dev/null || echo "failed")
if echo "${UP}" | grep -q "OK"; then
echo "✅ 서버가 정상적으로 구동되었습니다!"
break
else
echo "⏳ 서버 응답 대기 중... (${UP})"
sleep 10
fi
done
# 헬스체크 실패 시 롤백
if [ $HEALTH_CHECK_COUNT -eq $MAX_RETRY ]; then
echo "❌ 서버가 정상적으로 구동되지 않았습니다. 롤백을 시작합니다."
${COMPOSE} stop ${AFTER_COLOR}
${COMPOSE} rm -f ${AFTER_COLOR}
# 이전 컨테이너가 있다면 다시 시작
if [ "${BEFORE_COLOR}" != "" ]; then
echo "이전 ${BEFORE_COLOR} 컨테이너를 다시 시작합니다."
${COMPOSE} up -d ${BEFORE_COLOR}
fi
echo "❌ 배포 실패 - 롤백 완료"
exit 1
fi
# Nginx 설정 파일 백업
if [ -f /etc/nginx/conf.d/service-url.inc ]; then
sudo cp /etc/nginx/conf.d/service-url.inc /etc/nginx/conf.d/service-url.inc.backup
fi
# Nginx 설정 업데이트
echo "Nginx 설정 업데이트 중..."
if [ -f /etc/nginx/conf.d/service-url.inc ]; then
sudo sed -i "s/${BEFORE_PORT}/${AFTER_PORT}/g" /etc/nginx/conf.d/service-url.inc
# Nginx 설정 문법 검사
if sudo nginx -t; then
sudo nginx -s reload
echo "✅ Nginx 설정이 성공적으로 업데이트되었습니다."
else
echo "❌ Nginx 설정 오류. 백업 파일로 복원합니다."
sudo cp /etc/nginx/conf.d/service-url.inc.backup /etc/nginx/conf.d/service-url.inc
sudo nginx -s reload
exit 1
fi
else
echo "⚠️ Nginx 설정 파일을 찾을 수 없습니다: /etc/nginx/conf.d/service-url.inc"
fi
# 트래픽 전환 확인 (Nginx 기준 헬스체크)
echo "트래픽 전환 확인 중..."
sleep 5
NGINX_CHECK=$(curl -s --connect-timeout 5 http://127.0.0.1/health-check 2>/dev/null || echo "failed")
if echo "${NGINX_CHECK}" | grep -q "OK"; then
echo "✅ 트래픽이 성공적으로 전환되었습니다."
else
echo "⚠️ 트래픽 전환 확인 실패. 수동으로 확인해주세요."
fi
# 이전 컨테이너 종료 (안전하게)
if [ "${BEFORE_COLOR}" != "" ]; then
echo "${BEFORE_COLOR} server down (port:${BEFORE_PORT})"
# 잠시 대기 후 이전 컨테이너 종료
echo "이전 컨테이너 종료 전 30초 대기..."
sleep 30
${COMPOSE} stop ${BEFORE_COLOR} 2>/dev/null || true
${COMPOSE} rm -f ${BEFORE_COLOR} 2>/dev/null || true
echo "✅ 이전 ${BEFORE_COLOR} 컨테이너가 종료되었습니다."
fi
# 배포 완료
echo ""
echo "🎉 Deploy Completed!!"
echo "✅ Active Container: ${AFTER_COLOR} (Port: ${AFTER_PORT})"
echo "✅ Deployment Time: $(date)"
echo ""
# 최종 상태 확인
echo "=== 배포 후 상태 확인 ==="
echo "실행 중인 컨테이너:"
sudo docker ps --filter "name=blue" --filter "name=green" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
echo ""
echo "=== 배포 완료 ==="