Skip to content

Commit 7579681

Browse files
committed
init
- 서버 점검 컨트롤러 개발 - Dockerfile 작성 완료 - CICD.yml 작성 완료 -> 배포 가능 - gitignore 설정 완료
1 parent d0f979e commit 7579681

File tree

5 files changed

+257
-0
lines changed

5 files changed

+257
-0
lines changed

.github/workflows/CICD.yml

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
name: CICD
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v3
17+
- name: Install JDK 17
18+
uses: actions/setup-java@v3
19+
with:
20+
java-version: '17'
21+
distribution: 'temurin'
22+
23+
- name: Create application-secret-deploy.yml
24+
run: |
25+
echo "Decoding SECRET_FILE secret and create application-secret-deploy.yml"
26+
echo "${{ secrets.SECRET_FILE }}" | base64 -d > ./src/main/resources/application-secret-deploy.yml
27+
28+
29+
- name: Build with Gradle
30+
run: |
31+
chmod 777 ./gradlew
32+
./gradlew clean assemble -x test
33+
34+
- name: Login to DockerHub
35+
if: github.event_name == 'push'
36+
uses: docker/login-action@v1
37+
with:
38+
username: ${{ secrets.DOCKERHUB_USERNAME }}
39+
password: ${{ secrets.DOCKERHUB_TOKEN }}
40+
41+
- name: Build Docker
42+
if: github.event_name == 'push'
43+
run: docker build --platform linux/amd64 -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPO_NAME }} .
44+
45+
- name: Push Docker
46+
if: github.event_name == 'push'
47+
run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPO_NAME }}:latest
48+
49+
deploy:
50+
needs: build
51+
if: github.event_name == 'push'
52+
runs-on: ubuntu-latest
53+
steps:
54+
- name: Set target IP
55+
run: |
56+
STATUS=$(curl -o /dev/null -w "%{http_code}" "http://${{ secrets.LIVE_SERVER_IP }}/env")
57+
echo $STATUS
58+
if [ $STATUS = 200 ]; then
59+
CURRENT_UPSTREAM=$(curl -s "http://${{ secrets.LIVE_SERVER_IP }}/env")
60+
else
61+
CURRENT_UPSTREAM=green
62+
fi
63+
echo CURRENT_UPSTREAM=$CURRENT_UPSTREAM >> $GITHUB_ENV
64+
if [ $CURRENT_UPSTREAM = blue ]; then
65+
echo "CURRENT_PORT=8080" >> $GITHUB_ENV
66+
echo "STOPPED_PORT=8081" >> $GITHUB_ENV
67+
echo "TARGET_UPSTREAM=green" >> $GITHUB_ENV
68+
elif [ $CURRENT_UPSTREAM = green ]; then
69+
echo "CURRENT_PORT=8081" >> $GITHUB_ENV
70+
echo "STOPPED_PORT=8080" >> $GITHUB_ENV
71+
echo "TARGET_UPSTREAM=blue" >> $GITHUB_ENV
72+
else
73+
echo "error"
74+
exit 1
75+
fi
76+
77+
- name: Login Server
78+
uses: appleboy/ssh-action@master
79+
with:
80+
username: ${{ secrets.SERVER_USER_NAME }}
81+
host: ${{ secrets.LIVE_SERVER_IP }}
82+
key: ${{ secrets.SSH_KEY }}
83+
script_stop: true
84+
85+
- name: Docker compose
86+
uses: appleboy/ssh-action@master
87+
with:
88+
username: ${{ secrets.SERVER_USER_NAME }}
89+
host: ${{ secrets.LIVE_SERVER_IP }}
90+
key: ${{ secrets.SSH_KEY }}
91+
script_stop: true
92+
script: |
93+
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPO_NAME }}:latest
94+
sudo docker-compose -f docker-compose-${{env.TARGET_UPSTREAM}}.yml up -d
95+
96+
- name: Check deploy server URL
97+
uses: jtalk/url-health-check-action@v3
98+
with:
99+
url: http://${{ secrets.LIVE_SERVER_IP }}:${{env.STOPPED_PORT}}/env
100+
max-attempts: 5
101+
retry-delay: 10s
102+
103+
- name: Change nginx upstream
104+
uses: appleboy/ssh-action@master
105+
with:
106+
username: ${{ secrets.SERVER_USER_NAME }}
107+
host: ${{ secrets.LIVE_SERVER_IP }}
108+
key: ${{ secrets.SSH_KEY }}
109+
script_stop: true
110+
script: |
111+
sudo docker exec -i nginxserver bash -c 'echo "set \$service_url ${{ env.TARGET_UPSTREAM }};" > /etc/nginx/conf.d/service-env.inc && nginx -s reload'
112+
113+
- name: Stop current server
114+
uses: appleboy/ssh-action@master
115+
with:
116+
username: ${{ secrets.SERVER_USER_NAME }}
117+
host: ${{ secrets.LIVE_SERVER_IP }}
118+
key: ${{ secrets.SSH_KEY }}
119+
script_stop: true
120+
script: |
121+
if [ $(sudo docker ps -a -q -f name=${{env.CURRENT_UPSTREAM}}) ]; then
122+
sudo docker stop ${{env.CURRENT_UPSTREAM}}
123+
sudo docker rm ${{env.CURRENT_UPSTREAM}}
124+
else
125+
echo "Container ${{env.CURRENT_UPSTREAM}} does not exist, skipping stop and remove steps."
126+
fi
127+
128+
- name: Delete old docker images
129+
uses: appleboy/ssh-action@master
130+
with:
131+
username: ${{ secrets.SERVER_USER_NAME }}
132+
host: ${{ secrets.LIVE_SERVER_IP }}
133+
key: ${{ secrets.SSH_KEY }}
134+
script: |
135+
dangling_images=$(sudo docker images -f "dangling=true" -q)
136+
if [ ! -z "$dangling_images" ]; then
137+
sudo docker rmi $dangling_images
138+
else
139+
echo "No dangling images found"
140+
fi

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ build/
44
!gradle/wrapper/gradle-wrapper.jar
55
!**/src/main/**/build/
66
!**/src/test/**/build/
7+
!**/src/main/resoureces/application.yml
8+
application-*.yml
79

810
### STS ###
911
.apt_generated

Dockerfile

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM amazoncorretto:17-alpine-jdk
2+
ARG JAR_FILE=build/libs/*.jar
3+
ARG PROFILES
4+
ARG ENV
5+
COPY ${JAR_FILE} app.jar
6+
ENTRYPOINT ["java", "-Dspring.profiles.active=${PROFILES}", "-Dserver.env=${ENV}", "-jar", "app.jar"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package codeview.main.controller;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.http.ResponseEntity;
5+
import org.springframework.web.bind.annotation.GetMapping;
6+
import org.springframework.web.bind.annotation.ResponseBody;
7+
import org.springframework.web.bind.annotation.RestController;
8+
9+
import java.util.Map;
10+
import java.util.TreeMap;
11+
12+
@RestController
13+
public class ServerHealthCheckController {
14+
@Value("${server.env}")
15+
private String env;
16+
@Value("${server.port}")
17+
private String serverPort;
18+
@Value("${server.serverAddress}")
19+
private String serverAddress;
20+
@Value("${serverName}")
21+
private String serverName;
22+
23+
@GetMapping("/hc")
24+
public ResponseEntity<?> healthCheck() {
25+
Map<String, String> responseData = new TreeMap<>();
26+
responseData.put("serverName", serverName);
27+
responseData.put("serverAddress", serverAddress);
28+
responseData.put("serverPort", serverPort);
29+
responseData.put("env", env);
30+
return ResponseEntity.ok(responseData);
31+
}
32+
33+
@GetMapping("/env")
34+
@ResponseBody
35+
public ResponseEntity<?> getEnv() {
36+
return ResponseEntity.ok().body(env);
37+
}
38+
}

src/main/resources/application.yml

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
spring:
2+
profiles:
3+
active: local
4+
group:
5+
local: local, common, secret-dev
6+
blue: blue, common, secret-deploy
7+
green: green, common, secret-deploy
8+
9+
server:
10+
env: blue
11+
12+
---
13+
14+
spring:
15+
config:
16+
activate:
17+
on-profile: local
18+
19+
server:
20+
port: 8080
21+
serverAddress: localhost
22+
23+
serverName: local_server
24+
25+
---
26+
27+
spring:
28+
config:
29+
activate:
30+
on-profile: blue
31+
32+
server:
33+
port: 8080
34+
serverAddress: 34.64.190.54
35+
36+
serverName: blue_server
37+
38+
---
39+
40+
spring:
41+
config:
42+
activate:
43+
on-profile: green
44+
45+
server:
46+
port: 8081
47+
serverAddress: 34.64.190.54
48+
49+
serverName: green_server
50+
51+
---
52+
53+
spring:
54+
config:
55+
activate:
56+
on-profile: common
57+
58+
application:
59+
name: codeview
60+
jpa:
61+
hibernate:
62+
ddl-auto: create
63+
show_sql: true
64+
properties:
65+
hibernate:
66+
format_sql: true
67+
dialect: org.hibernate.dialect.MySQLDialect
68+
69+
logging:
70+
level:
71+
org.springframework.security: DEBUG

0 commit comments

Comments
 (0)