Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] #10 - CI/CD 구축 #11

Merged
merged 8 commits into from
Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/CD.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: CD

on:
push:
branches: [ "develop" ]

jobs:
deploy-ci:
runs-on: ubuntu-22.04

steps:
- name: checkout
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: '17'

- name: application.yaml 생성
run: |
cd src/main/resources
echo "${{ secrets.APPLICATION }}" > ./application-deploy.yaml

- name: build
run: |
chmod +x gradlew
./gradlew build -x test
shell: bash

- name: docker build setting
uses: docker/[email protected]

- name: docker hub login
uses: docker/[email protected]
with:
username: ${{ secrets.DOCKERHUB_LOGIN_USERNAME }}
password: ${{ secrets.DOCKERHUB_LOGIN_ACCESSTOKEN }}

- name: docker image build and push
run: |
docker build --platform linux/amd64 -t teammoonshot/server .
docker push teammoonshot/server

deploy-cd:
needs: deploy-ci
runs-on: ubuntu-22.04

steps:
- name: docker container running
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.RELEASE_SERVER_IP }}
username: ${{ secrets.RELEASE_SERVER_USER }}
key: ${{ secrets.RELEASE_SERVER_KEY }}
script: |
cd ~
./deploy.sh
30 changes: 30 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
pull_request:
branches: [ "develop" ]

jobs:
build:
runs-on: ubuntu-22.04

steps:
- name: checkout
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'corretto'
java-version: '17'

- name: application.yaml 작성
run: |
cd src/main/resources
echo "${{ secrets.APPLICATION }}" > ./application-deploy.yaml

- name: build
run: |
chmod +x gradlew
./gradlew build -x test
shell: bash
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM amd64/amazoncorretto:17

WORKDIR /app

COPY ./build/libs/server-0.0.1-SNAPSHOT.jar /app/moonshot.jar

CMD ["java", "-Duser.timezone=Asia/Seoul", "-jar", "-Dspring.profiles.active=deploy", "moonshot.jar"]
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'

// spring-actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

dependencyManagement {
Expand Down
99 changes: 99 additions & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash

nginx_config_path="/etc/nginx"
all_port=("8080" "8081")
available_port=()
server_name=server

docker_ps_output=$(docker ps | grep $server_name)
running_container_name=$(echo "$docker_ps_output" | awk '{print $NF}')
blue_port=$(echo "$running_container_name" | awk -F'-' '{print $NF}')
web_health_check_url=/actuator/health

if [ -z "$blue_port" ]; then
echo "> 실행 중인 서버의 포트: 없음"
else
echo "> 실행 중인 서버의 포트: $blue_port"
fi

# 실행 가능한 포트 확인 ( all_port 중 blue_port를 제외한 port )
for item in "${all_port[@]}"; do
if [ "$item" != "$blue_port" ]; then
available_port+=("$item")
fi
done

# 실행 가능한 포트 없으면 끝내기
if [ ${#available_port[@]} -eq 0 ]; then
echo "> 실행 가능한 포트가 없습니다."
exit 1
fi

green_port=${available_port[0]}

echo "----------------------------------------------------------------------"
# docker image pull
echo "> 도커 이미지 pull 받기"
docker pull teammoonshot/${server_name}

# green_port로 서버 실행
echo "> ${green_port} 포트로 서버 실행"
echo "> docker run -d --name ${server_name}-${green_port} -p ${green_port}:8080 -e TZ=Asia/Seoul teammoonshot/${server_name}"
docker run -d --name ${server_name}-${green_port} -p ${green_port}:8080 -e TZ=Asia/Seoul teammoonshot/${server_name}
echo "----------------------------------------------------------------------"

# green_port 서버 제대로 실행 중인지 확인
sleep 10
for retry_count in {1..10}
do
echo "> 서버 상태 체크"
echo "> curl -s http://localhost:${green_port}${web_health_check_url}"
# http://localhost:{그린포트}{health check 주소} -> nginx
response=$(curl -s http://localhost:${green_port}${web_health_check_url})
up_count=$(echo $response | grep 'UP' | wc -l)

if [ $up_count -ge 1 ]
then
echo "> 서버 실행 성공"
break
else
echo "> 아직 서버 실행 안됨"
echo "> 응답 결과: ${response}"
fi
if [ $retry_count -eq 10 ]
then
echo "> 서버 실행 실패"
docker rm -f ${server_name}-${green_port}

exit 1
fi
sleep 2
done
echo "----------------------------------------------------------------------"

# nginx switching
echo "> nginx 포트 스위칭"
echo "set \$service_url http://127.0.0.1:${green_port};" | sudo tee ${nginx_config_path}/conf.d/service-url.inc
sudo nginx -s reload

sleep 1

echo "----------------------------------------------------------------------"
# nginx를 통해서 서버 접근 가능한지 확인
response=$(curl -s http://localhost${web_health_check_url})
up_count=$(echo $response | grep 'UP' | wc -l)
if [ $up_count -ge 1 ]
then
echo "> 서버 변경 성공"
else
echo "> 서버 변경 실패"
echo "> 서버 응답 결과: ${response}"
exit 1
fi

# blue_port 서버 있다면 중단
if [ -n "$blue_port" ]; then
echo "> 기존 ${blue_port}포트 서버 중단"
echo "> docker rm -f ${server_name}-${blue_port}"
sudo docker rm -f ${server_name}-${blue_port}
fi
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
public class SecurityConfig {
private static final String[] WHITELIST = {
"/login/**",
"/"
"/",
"/actuator/health"
};

private final MoonshotExceptionHandler moonshotExceptionHandler;
Expand Down