Skip to content

Commit

Permalink
🎉 무중단 배포 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
rong5026 committed Oct 27, 2024
1 parent 44c8241 commit 7387d17
Show file tree
Hide file tree
Showing 16 changed files with 373 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@rong5026
72 changes: 72 additions & 0 deletions .github/workflows/minipc-docker-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: New-Animal-Meeting - BackEnd - CD

on:
push:
branches:
- main

jobs:
deploy:
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: Make application.yml
run: |
cd ./src/main/resources
touch ./application.yml
echo "$APPLICATION" > ./application.yml
env:
APPLICATION: ${{ secrets.APPLICATION }}
shell: bash

- name: Gradle 권한 부여
run: chmod +x gradlew

- name: Gradle로 빌드 실행
run: ./gradlew bootjar

# 배포에 필요한 여러 설정 파일과 프로젝트 빌드파일을 zip 파일로 모아줍니다.
- name: zip file 생성
run: |
mkdir deploy
cp ./docker/Dockerfile ./deploy/
cp ./docker/docker-compose.minipc.yml ./deploy/
cp ./scripts/minipc-docker-deploy.sh ./deploy/
cp ./build/libs/*.jar ./deploy/
chmod +x ./deploy/minipc-docker-deploy.sh
zip -r -qq -j ./sinabro-app.zip ./deploy
# ZIP 파일 전송
- name: Transfer ZIP file use SCP
uses: appleboy/scp-action@master
with:
username: ${{ secrets.SSH_USERNAME }}
host: ${{ secrets.SSH_HOST }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
source: "./sinabro-app.zip"
target: "/home/hong/app/sinabro-back"

# SSH 연결 후 배포 스크립트 실행
- name: Execute SSH command on remote server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
REMOTE_DIR="/home/hong/app/sinabro-back"
cd $REMOTE_DIR
unzip -o sinabro-app.zip
./minipc-docker-deploy.sh
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ dependencies {
tasks.named('test') {
useJUnitPlatform()
}

bootJar {
archiveFileName = 'sinabro-app.jar'
}
12 changes: 12 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
### Docker 이미지를 생성할 때 기반이 되는 베이스 이미지를 설정한다.
FROM openjdk:17
### Dockerfile 내에서 사용할 변수 JAR_FILE을 정의한다.
#WORKDIR /app
#ARG JAR_FILE=/build/libs/animal-meeting-blue-green-app.jar
ARG JAR_FILE=/sinabro-app.jar
### JAR_FILE 경로에 해당하는 파일을 Docker 이미지 내부로 복사한다.
COPY ${JAR_FILE} sinabro-app.jar
### Docker 컨테이너가 시작될 때 실행할 명령을 지정한다.
ENTRYPOINT ["java","-jar", "/sinabro-app.jar"]


14 changes: 14 additions & 0 deletions docker/docker-compose.minipc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: '3'
services:
animal-meeting-app:
image: sinabro-app:latest
container_name: sinabro-container
networks:
- pricewagon-network
ports:
- "8090:8090"
build:
context: .
networks:
pricewagon-network:
external: true # 이미 존재하는 네트워크를 사용
43 changes: 43 additions & 0 deletions scripts/minipc-docker-deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash

# 배포 로그 파일 설정
DEPLOY_LOG="/home/hong/app/sinabro-back/deploy.log"
COMPOSE_FILE="docker-compose.minipc.yml"

# 현재 디렉토리 이동
cd /home/hong/app/sinabro-back

# 새로운 Docker 이미지 빌드
echo "Docker 이미지 빌드 시작 ..." >> $DEPLOY_LOG
docker-compose -f $COMPOSE_FILE build >> $DEPLOY_LOG 2>&1

if [ $? -ne 0 ]; then
echo "Docker 이미지 빌드 실패!" >> $DEPLOY_LOG
exit 1
fi

echo "Docker 이미지 빌드 완료!" >> $DEPLOY_LOG

# 기존 컨테이너 중지 및 삭제 (존재 여부 확인 후 중지/삭제)
if [ "$(docker ps -a -q -f name=sinabro-container)" ]; then
echo "기존 컨테이너 종료 및 삭제 ..." >> $DEPLOY_LOG
docker stop -f $COMPOSE_FILE sinabro-container >> $DEPLOY_LOG 2>&1
docker rm -f $COMPOSE_FILE sinabro-container --force >> $DEPLOY_LOG 2>&1
if [ $? -ne 0 ]; then
echo "기존 컨테이너 종료 및 삭제 실패!" >> $DEPLOY_LOG
exit 1
fi
else
echo "삭제할 기존 컨테이너가 없습니다." >> $DEPLOY_LOG
fi

# 새로운 컨테이너 실행
echo "Docker 컨테이너 실행 시작 ..." >> $DEPLOY_LOG
docker-compose -f $COMPOSE_FILE up -d >> $DEPLOY_LOG 2>&1

if [ $? -ne 0 ]; then
echo "Docker 컨테이너 실행 실패!" >> $DEPLOY_LOG
exit 1
fi

echo "### Docker 컨테이너 실행 완료!" >> $DEPLOY_LOG
30 changes: 30 additions & 0 deletions src/main/java/com/sinabro/sinabro/controller/SurveyController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.sinabro.sinabro.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sinabro.sinabro.entity.Survey;
import com.sinabro.sinabro.entity.request.SurveyRequest;
import com.sinabro.sinabro.service.SurveyService;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/surveys")
public class SurveyController {

private final SurveyService surveyService;
@PostMapping("/")
public Survey createSurvey(@Valid @RequestBody SurveyRequest request) {
return surveyService.createSurvey(request);
}

// @PostMapping("/{uuid}/answers")
// public SurveyRequest getSurveyAnswers(@PathVariable String uuid) {
// return surveyService.getSurveyAnswers(uuid);
// }
}
33 changes: 33 additions & 0 deletions src/main/java/com/sinabro/sinabro/entity/Creator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.sinabro.sinabro.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Creator {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "survey_id", nullable = false)
private Survey survey;

@Column(nullable = false)
private Integer questionNumber;
@Column(nullable = false)
private Integer answerNumber;
}
34 changes: 34 additions & 0 deletions src/main/java/com/sinabro/sinabro/entity/Submitter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.sinabro.sinabro.entity;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Submitter {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne
@JoinColumn(name = "survey_id", nullable = false)
private Survey survey;

@Column(nullable = false, length = 20)
private String name;

@Column
private Integer score;
}
38 changes: 38 additions & 0 deletions src/main/java/com/sinabro/sinabro/entity/Survey.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.sinabro.sinabro.entity;

import java.time.LocalDateTime;
import java.util.List;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Survey {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "creator_name", nullable = false, length = 20)
private String creatorName;

@Column(nullable = false, length = 200)
private String url;

@Column(nullable = false)
private LocalDateTime createdAt;

@OneToMany(mappedBy = "survey")
private List<Submitter> submitters;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.sinabro.sinabro.entity.request;

import java.util.List;

public record SurveyRequest(
String creatorName,
List<QuestionAnswerPair> answers
) {
public record QuestionAnswerPair(
Integer questionId,
Integer answerId
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.sinabro.sinabro.entity.response;

public class SurveyResponse {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.sinabro.sinabro.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.sinabro.sinabro.entity.Creator;

public interface CreatorRepository extends JpaRepository<Creator, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.sinabro.sinabro.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.sinabro.sinabro.entity.Submitter;

public interface SubmitterRepository extends JpaRepository<Submitter, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.sinabro.sinabro.repository;

import org.springframework.data.jpa.repository.JpaRepository;

public interface SurveyRepository extends JpaRepository<com.sinabro.sinabro.entity.Survey, Long> {

}
52 changes: 52 additions & 0 deletions src/main/java/com/sinabro/sinabro/service/SurveyService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.sinabro.sinabro.service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.sinabro.sinabro.entity.Creator;
import com.sinabro.sinabro.entity.Survey;
import com.sinabro.sinabro.entity.request.SurveyRequest;
import com.sinabro.sinabro.repository.CreatorRepository;
import com.sinabro.sinabro.repository.SubmitterRepository;
import com.sinabro.sinabro.repository.SurveyRepository;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
@Transactional
public class SurveyService {

private final SurveyRepository surveyRepository;
private final SubmitterRepository submitterRepository;
private final CreatorRepository creatorRepository;

public Survey createSurvey(SurveyRequest surveyRequest) {
Survey survey = Survey.builder()
.creatorName(surveyRequest.creatorName())
.url(generateSurveyUrl())
.createdAt(LocalDateTime.now())
.build();
survey = surveyRepository.save(survey);

List<SurveyRequest.QuestionAnswerPair> answers = surveyRequest.answers();
for (SurveyRequest.QuestionAnswerPair answer : answers) {
Creator creator = Creator.builder()
.survey(survey)
.questionNumber(answer.questionId())
.answerNumber(answer.answerId())
.build();
creatorRepository.save(creator);
}
return survey;
}

private String generateSurveyUrl() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 5); // 5자리 문자열
}

}

0 comments on commit 7387d17

Please sign in to comment.