-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdeploy.sh
More file actions
145 lines (116 loc) · 4.08 KB
/
deploy.sh
File metadata and controls
145 lines (116 loc) · 4.08 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
#!/bin/bash
# 한 명령어라도 실패하면 스크립트 즉시 종료
set -e
cd /home/ubuntu/cicd/spring
# 환경변수 설정
APP_NAME="haru"
TARGET=""
OLD=""
NGINX_CONF_PATH="/etc/nginx"
BLUE_CONF="blue.conf"
GREEN_CONF="green.conf"
DEFAULT_CONF="nginx.conf"
MAX_RETRIES=3
HEALTH_CHECK_PORT=""
# 네트워크 존재 확인 및 생성
ensure_network() {
echo "Checking Docker network 'haru-network'..."
if ! docker network inspect haru-network >/dev/null 2>&1; then
echo "Network 'haru-network' not found. Creating it..."
docker network create haru-network
else
echo "Network 'haru-network' already exists."
fi
}
# 활성화된 서비스 확인 및 스위칭 대상 결정
determine_target() {
if docker compose -f docker-compose.yml ps | grep -q "app-blue.*Up"; then
TARGET="green"
OLD="blue"
HEALTH_CHECK_PORT="8081"
elif docker compose -f docker-compose.yml ps | grep -q "app-green.*Up"; then
TARGET="blue"
OLD="green"
HEALTH_CHECK_PORT="8080"
else
TARGET="blue" # 첫 실행 시 기본값
OLD="none"
HEALTH_CHECK_PORT="8080"
fi
echo "TARGET: $TARGET"
echo "OLD: $OLD"
}
# 헬스체크 실패 시 롤백 처리
health_check() {
local RETRIES=0
local URL="http://localhost:$HEALTH_CHECK_PORT/actuator/health"
echo "Starting health check for the new '$TARGET' container on port $HEALTH_CHECK_PORT..."
# 새로운 컨테이너가 실행될 때까지 충분히 대기
sleep 10
while [ $RETRIES -lt $MAX_RETRIES ]; do
echo "Attempt $((RETRIES + 1)) of $MAX_RETRIES: Checking $URL..."
# curl 명령어로 애플리케이션의 헬스 체크 엔드포인트에 HTTP 요청
STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$URL" || true)
if [ "$STATUS_CODE" -eq 200 ]; then
echo "Health check succeeded! Container '$TARGET' is healthy."
return 0
else
echo "Health check failed with status code: $STATUS_CODE. Retrying in 5 seconds..."
sleep 5
fi
RETRIES=$((RETRIES + 1))
done
echo "Health check failed after $MAX_RETRIES attempts."
return 1 # 헬스 체크 실패 시 1을 반환하여 스크립트 롤백을 유도
}
# NGINX 설정 스위칭 함수
switch_nginx_conf() {
if [ "$TARGET" = "blue" ]; then
sudo cp "${NGINX_CONF_PATH}/${BLUE_CONF}" "${NGINX_CONF_PATH}/${DEFAULT_CONF}"
else
sudo cp "${NGINX_CONF_PATH}/${GREEN_CONF}" "${NGINX_CONF_PATH}/${DEFAULT_CONF}"
fi
echo "Reloading NGINX configuration..."
nginx -s reload
}
# 이전 컨테이너 종료 함수
down_old_container() {
if [ "$OLD" != "none" ]; then
echo "Stopping old container: $OLD"
docker compose -f docker-compose.yml stop "app-$OLD"
docker compose -f docker-compose.yml rm -f "app-$OLD"
fi
}
# 메인 실행 로직
main() {
ensure_network
determine_target
# 컨테이너 충돌 방지를 위해, 동일한 이름의 컨테이너가 있을 경우 미리 삭제
echo "Removing any existing container with the name 'app-$TARGET'..."
docker compose -f docker-compose.yml rm -f "app-$TARGET" 2>/dev/null || true
# 최신 이미지 풀
echo "Pulling the latest image for '$TARGET' service..."
docker compose -f docker-compose.yml pull "app-$TARGET"
# 대상 컨테이너 실행
echo "Starting '$TARGET' container..."
docker compose -f docker-compose.yml up -d "app-$TARGET"
# 헬스 체크 및 롤백 로직
if ! health_check; then
echo "Health check failed. Initiating rollback..."
# 실패한 컨테이너를 중지하고 제거
echo "Removing failed container: 'app-$TARGET'..."
docker compose -f docker-compose.yml down --remove-orphans "app-$TARGET" || true
echo "Rollback complete. The previous version remains active."
exit 1 # 스크립트 종료
fi
# 헬스 체크 성공 시, NGINX 설정 스위칭
switch_nginx_conf
# 이전 컨테이너 종료
down_old_container
echo "Deployment to '$TARGET' completed successfully!"
echo "Cleaning up dangling Docker images..."
docker image prune -f
echo "Deployment finished at $(date)"
}
# 스크립트 실행
main