-
Notifications
You must be signed in to change notification settings - Fork 1
234 lines (184 loc) · 8.42 KB
/
cd-develop.yml
File metadata and controls
234 lines (184 loc) · 8.42 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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
name: CI/CD
on:
# push:
# branches: [ "feature/seungmin" ]
#push:
# branches: [ "feature/seungin" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
jobs:
# 1. 도커 이미지 빌드 및 푸시
build-docker-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Create application.yml from secrets
run: |
mkdir -p src/main/resources
echo "${{ secrets.APPLICATION_YML }}" > src/main/resources/application.yml
- name: Copy keystore.p12
run: |
cd ./src/main/resources
touch ./keystore.p12
echo "${{secrets.KEYSTORE}}" | base64 --decode > ./keystore.p12
- name: Build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: clean bootJar
- name: Docker build with latest tag
run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/github-actions-demo:latest .
- name: Docker login
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}
- name: Push Docker image
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/github-actions-demo:latest
# 2. EC2에서 컨테이너 실행
run-docker-image-on-ec2:
needs: build-docker-image
runs-on: self-hosted
steps:
- uses: actions/checkout@v3
- name: Pull latest image from Docker Hub
run: sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/github-actions-demo:latest
- name: Cleanup all existing containers before starting
run: |
echo "🧹 Cleaning up all existing containers"
# Stop and remove specific containers (로그는 볼륨에 보존됨)
sudo docker stop github-actions-demo || true
sudo docker rm github-actions-demo || true
sudo docker stop elasticsearch || true
sudo docker rm elasticsearch || true
echo "📋 Ensuring log directory exists on host"
sudo mkdir -p /var/log/wayble
sudo chmod 755 /var/log/wayble
echo "🧯 Cleaning up unused Docker networks (excluding volumes)"
sudo docker system prune -f --volumes=false || true
- name: Create Docker network if not exists
run: |
sudo docker network create wayble-network || true
- name: Check if Elasticsearch image exists locally
run: |
if sudo docker images | grep -q "es-with-nori.*9.0.2"; then
echo "✅ Elasticsearch image found locally - skipping download"
else
echo "⬇️ Building Elasticsearch with Nori image..."
sudo docker build -f Dockerfile.elasticsearch -t es-with-nori:9.0.2 .
fi
- name: Run Elasticsearch container
run: |
sudo docker run -d \
--name elasticsearch \
--network wayble-network \
-p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e "xpack.security.enabled=false" \
-e "network.host=0.0.0.0" \
-e "ES_JAVA_OPTS=-Xms384m -Xmx384m" \
-v elasticsearch-data:/usr/share/elasticsearch/data \
es-with-nori:9.0.2
- name: Wait for test Elasticsearch to be ready
run: |
echo "Waiting for test Elasticsearch to start..."
for i in {1..30}; do
HEALTH_STATUS=$(curl -s http://localhost:9200/_cluster/health | jq -r '.status' 2>/dev/null || echo "down")
if [ "$HEALTH_STATUS" = "green" ] || [ "$HEALTH_STATUS" = "yellow" ]; then
echo "✅ Test Elasticsearch is ready and healthy! Status: $HEALTH_STATUS"
curl -s http://localhost:9200/_cluster/health | jq .
break
fi
echo "Waiting... ($i/30) - Current status: $HEALTH_STATUS"
sleep 5
done
- name: Verify network connectivity
run: |
echo "=== Network Information ==="
sudo docker network inspect wayble-network
echo "=== Test DNS resolution from Spring Boot container ==="
sudo docker run --rm --network wayble-network alpine:latest nslookup elasticsearch || echo "DNS resolution failed"
echo "=== Test ping from Spring Boot container ==="
sudo docker run --rm --network wayble-network alpine:latest ping -c 2 elasticsearch || echo "Ping failed"
echo "=== Test direct HTTP connection from container ==="
sudo docker run --rm --network wayble-network alpine/curl:latest curl -v http://elasticsearch:9200/_cluster/health || echo "HTTP connection failed"
echo "=== Test Elasticsearch from same network context ==="
sudo docker run --rm --network wayble-network alpine/curl:latest curl -s http://elasticsearch:9200/_cluster/health | jq . || echo "JSON parsing failed"
- name: Run new Spring Boot container
run: |
sudo docker run -d \
--name github-actions-demo \
--network wayble-network \
-p 8080:8080 \
-v /var/log/wayble:/app/logs \
-e "SPRING_PROFILES_ACTIVE=develop" \
-e "TZ=Asia/Seoul" \
${{ secrets.DOCKERHUB_USERNAME }}/github-actions-demo:latest
- name: Test application health
run: |
echo "Waiting for application to start..."
sleep 30
# 애플리케이션 로그 확인
echo "=== Application Logs ==="
sudo docker logs github-actions-demo || echo "Failed to get app logs"
# 컨테이너 상태 확인
echo "=== Container Status ==="
sudo docker ps -a --filter "name=github-actions-demo"
# 포트 확인
echo "=== Port Check ==="
netstat -tlnp | grep 8080 || echo "Port 8080 not listening"
# 애플리케이션 헬스체크 (상세 디버그)
echo "=== Health Check Details ==="
curl -v http://localhost:8080/ || echo "Health check failed with exit code $?"
# 간단한 연결 테스트
echo "=== Simple Connection Test ==="
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/localhost/8080' && echo "Port 8080 is open" || echo "Port 8080 is closed"
echo "✅ Debug information collected"
# Elasticsearch 연결 테스트
if curl -f http://localhost:9200/_cluster/health > /dev/null 2>&1; then
echo "✅ Elasticsearch is accessible!"
else
echo "❌ Elasticsearch connection failed"
exit 1
fi
# 로그 파일 상태 확인
echo "=== Log Directory Status ==="
ls -la /var/log/wayble/ || echo "Log directory not found"
if [ -f "/var/log/wayble/wayble-error.log" ]; then
echo "✅ Error log file exists"
echo "📊 Error log file size: $(du -h /var/log/wayble/wayble-error.log | cut -f1)"
echo "📅 Last modified: $(stat -c %y /var/log/wayble/wayble-error.log)"
else
echo "ℹ️ No error log file yet (normal for new deployment)"
fi
# ✅ 배포 성공 알림 (Discord)
- name: Send success webhook to Discord
if: success()
run: |
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"✅ EC2 배포 성공!\"}" \
${{ secrets.DISCORD_WEBHOOK_URL }}
# ❌ 배포 실패 알림 (Discord)
- name: Send failure webhook to Discord
if: failure()
run: |
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"❌ EC2 배포 실패! 확인이 필요합니다.\"}" \
${{ secrets.DISCORD_WEBHOOK_URL }}
# on: #이 워크플로우가 언제 실행될지 트리거를 정의함.
# pull_request:
# types : [closed] #누군가가 Pull request를 닫았을 때 실행됨.
# workflow_dispatch: #수동 실행도 가능하도록
# jobs: #실제 실행할 작업을 정의
# build: #작업 이름
# runs-on: ubuntu-latest #OS환경
# if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'develop'
# #닫힌 Pull Request 중에서, 병합된 것이고, 병합 대상 브랜치가 develop 브랜치일 경우에만 이 작업을 실행