Skip to content

Commit

Permalink
Merge pull request #23 from KCY-Fit-a-Pet/feat/8
Browse files Browse the repository at this point in the history
✨ PR 하나로 Issue 도장깨기
  • Loading branch information
heejinnn authored Oct 2, 2023
2 parents 091d1b4 + 3295791 commit 8dae02e
Show file tree
Hide file tree
Showing 87 changed files with 3,747 additions and 51 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
.env

### STS ###
.apt_generated
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM openjdk:17
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar","--spring.profiles.active=prod","-Duser.timezone=Asia/Seoul"]
93 changes: 53 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,67 @@
김최양 사이드 프로젝트 FitaPet 백엔드 Repository 입니다.

- 기획&디자인: [김유빈](https://github.com/youvebeen09)
- [프론트엔드](https://github.com/heejinnn/fit-a-pet-frontend): [최희진](https://github.com/heejinnn)
- [프론트엔드](https://github.com/KCY-Fit-a-Pet/fit-a-pet-client): [최희진](https://github.com/heejinnn)
- 백엔드: [양재서](https://github.com/psychology50)

## [ Contents ]
- [Project Summary](#project-summary)
- [Version Control](#version-control)
- [Dev Environment](#dev-environment)
- [Tech Stack](#tech-stack)
- [Framework & Library](#framework--library)
- [Build tool](#build-tool)
- [Database](#database)
- [Infra](#infra)
- [Project Check List](#project-check-list)
- [System Architecture](#system-architecture)
- [WAS Architecture](#was-architecture)
- [ERD](#erd)
- [Branch Convention](#branch-convention)

## Version Control
| Version # | Revision Date | Description | Author |
|:---------:|:-------------:|:--------------------|:------:|
| v0.0.1 | 2023.10.1 | 프로젝트 기본 기능 구현 및 배포 | 양재서 |

## Dev Environment
- IntelliJ 2023.1.2
- Postman
- GitHub
- Virtual Machine (Linux)
- Postman 10.18.9
- GitHub
- Windows 11
- Notion

## Tech Stack
### Framework & Library
- Java (버전 미정)
- SpringBoot 3.0.1
- JDK 11
- SpringBoot 3.1.0
- SpringBoot Security
- Spring Data JPA
- Swagger
- Lombok
- Spring Doc Open API
- Lombok
- JUnit5
- jjwt 0.11.5
- httpclient 4.5.14 & httpclient5 5.1.4

### Build tool
- Gradle

### Database
- Maria DB
- MySQL8
- Redis

### Infra
- AWS EC2
- AWS S3
- AWS CodeDeploy
- AWS Route53
- Docker & Kubernetes
- AWS EC2 (for Build Server)
- Docker & Docker-compose
- Jenkins
- Github Todo bot
- GitHub Todo bot
- GitHub Action
- Kakao Talk
- Naver Cloud Platform Server (for WAS)
- Naver Cloud Platform Cloud DB for Redis
- Naver Cloud Platform Object Storage
- Naver Cloud Platform Simple & Easy Notification Service
- Goorm IDE (for DB Server)

## Project Check List
- [ ] 실제 서비스를 공개적으로 배포하고 운영하는 경험을 해보았다.
Expand All @@ -50,16 +77,17 @@
- [ ] 타인과의 협업을 효율적으로 하기 위한 고민을 해보았다.

## System Architecture

<div align="center"><img src="https://github.com/KCY-Fit-a-Pet/fit-a-pet-client/assets/96044622/08a48299-460b-46c9-ac83-ac7aec15d73c"></img></div>

## WAS Architecture
<div align="center"><img src="https://github.com/KCY-Fit-a-Pet/fit-a-pet-client/assets/96044622/81ec4e4b-8a15-4a26-a8ff-96022dfde03f"></img></div>

- WAS Server 내부에 Nginx를 통해 Reverse Proxy를 구현했습니다.

## ERD
<div align="center"><img src="https://github.com/KCY-Fit-a-Pet/fit-a-pet-client/assets/96044622/25596514-4b67-4ccb-9186-4197f0facb3d"></img></div>


## Projcet Board

- 현재 많은 부분이 수정되었고, 앞으로도 계속 수정될 예정입니다.

## Branch Convention

Expand All @@ -68,22 +96,12 @@ main ── develop ── feature
└── hotfix
```

| Brach name | description |
| --- | --- |
| main | 배포 중인 서비스 브랜치
• 실제 서비스가 이루어지는 브랜치입니다.
• 해당 브랜치를 기준으로 develop 브랜치가 분기됩니다.
• 긴급 수정 안건에 대해서는 hotfix 브랜치에서 처리합니다. |
| develop | 작업 브랜치
• 개발, 테스트, 릴리즈 등 배포 전 단계의 기준이 되는 브랜치입니다.
• 프로젝트의 default 브랜치입니다.
• 해당 브랜치에서 feature 브랜치가 분기됩니다. |
| feature | 기능 단위 구현
• 개별 개발자가 맡은 작업을 개발하는 브랜치입니다.
• feature/(feature-name)처럼 머릿말-꼬릿말(개발하는 기능)으로 명명합니다.
• kebab-case 네이밍 규칙을 준수합니다. |
| hotfix | 서비스 중 긴급 수정 사항 처리
• main에서 분기합니다. |
| Brach name | description |
| --- |-------------------------------------------------------------------------------------------------------------------------------------------|
| main | 배포 중인 서비스 브랜치 <br/> • 실제 서비스가 이루어지는 브랜치입니다. <br/> • 해당 브랜치를 기준으로 develop 브랜치가 분기됩니다.<br/> • 긴급 수정 안건에 대해서는 hotfix 브랜치에서 처리합니다. |
| develop | 작업 브랜치 <br/> • 개발, 테스트, 릴리즈 등 배포 전 단계의 기준이 되는 브랜치입니다. <br/> • 프로젝트의 default 브랜치입니다. <br/> • 해당 브랜치에서 feature 브랜치가 분기됩니다. |
| feature | 기능 단위 구현 <br/> • 개별 개발자가 맡은 작업을 개발하는 브랜치입니다. <br/> • feature/(feature-name)처럼 머릿말-꼬릿말(개발하는 기능)으로 명명합니다. <br/> • kebab-case 네이밍 규칙을 준수합니다. |
| hotfix | 서비스 중 긴급 수정 사항 처리 <br/> • main에서 분기합니다. |

## Commit Convention

Expand Down Expand Up @@ -122,8 +140,3 @@ main ── develop ── feature
```
</div>
</details>

## Version Control



13 changes: 12 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {

group = 'com.kcy'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '20'
sourceCompatibility = '17'

configurations {
compileOnly {
Expand All @@ -21,10 +21,20 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'com.jcraft:jsch:0.1.55'

implementation 'org.apache.httpcomponents:httpclient:4.5.14'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
implementation 'org.apache.httpcomponents:httpcore:4.4.14'

// swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'

// jwt
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
Expand All @@ -35,6 +45,7 @@ dependencies {
developmentOnly 'org.springframework.boot:spring-boot-devtools'
implementation 'mysql:mysql-connector-java:8.0.28'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
}
Expand Down
27 changes: 27 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
version: '3.7'
services:
proxy:
image: jaeseo/nginx:latest
restart: always
ports:
- "80:80"
- "443:443"
networks:
- was-net
depends_on:
- api

fitapet-api:
image: jaeseo/fitapet:latest
restart: unless-stopped
ports:
- "8080:8080"
env_file:
- .env
networks:
- was-net

networks:
was-net:
name: fitapet
external: true
3 changes: 3 additions & 0 deletions proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM nginx

ADD nginx.conf /etc/nginx/nginx.conf
57 changes: 57 additions & 0 deletions proxy/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types; # 옵션 항목을 설정해둔 파일의 경로
default_type application/octet-stream; # 옥텟 스트림 기반의 http를 사용

# 백엔드 upstream 설정 (nginx가 downstream)
upstream docker-server {
server fitapet-api:8080; # nginx가 요청을 전달할 서버를 정의하는 지시자 (여기서는 WAS, 웹 어플리케이션 서버 host주소:포트)
}

server {
listen 80; # 서버가 리스닝할 포트를 설정하는 지시자 (server 블록 하나 당 하나의 웹 사이트 선언)
listen [::]:80;

server_name localhost; # 서버의 도메인 이름을 설정하는 지시자 (request header의 host와 비교하여 일치하는 경우에만 처리)

location / {
root /usr/share/nginx/html; # root 지시자는 요청이 들어왔을 때, 해당 요청을 처리할 파일의 기본 경로를 설정
index index.html index.htm; # index 지시자는 root 지시자에서 설정한 경로에서 찾을 파일의 이름을 설정
try_files $uri $uri/ /index.html =404; # try_files 지시자는 파일을 찾을 수 없는 경우의 처리 방법을 설정
}

location /api {
proxy_pass http://docker-server; # proxy_pass 지시자는 요청을 전달할 서버의 주소를 설정
proxy_redirect off; # proxy_redirect 지시자는 리다이렉션을 설정
proxy_set_header Host $host; # proxy_set_header 지시자는 요청 헤더의 값을 변경
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header 지시자는 요청 헤더의 값을 변경
proxy_set_header X-Forwarded-Proto $scheme; # proxy_set_header 지시자는 요청 헤더의 값을 변경
}

# location /socket {
# proxy_pass http://docker-server;
# proxy_http_version 1.1; # proxy_http_version 지시자는 HTTP 버전을 설정
# proxy_set_header Upgrade $http_upgrade; # proxy_set_header 지시자는 요청 헤더의 값을 변경
# proxy_set_header Connection "upgrade"; # proxy_set_header 지시자는 요청 헤더의 값을 변경
# proxy_set_header Host $host; # proxy_set_header 지시자는 요청 헤더의 값을 변경
# }
}

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; # log_format 지시자는 로그의 형식을 설정
access_log /var/log/nginx/access.log main; # access_log 지시자는 로그 파일의 경로와 형식을 설정

sendfile on; # sendfile 지시자는 파일 전송 방식을 설정
server_tokens off; # server_tokens 지시자는 응답 헤더의 Server 값을 설정
keepalive_timeout 65; # keepalive_timeout 지시자는 keep-alive 연결의 타임아웃 시간을 설정
include /etc/nginx/conf.d/*.conf; # include 지시자는 외부 설정 파일을 포함
}
1 change: 0 additions & 1 deletion src/main/java/com/kcy/fitapet/FitapetApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

@SpringBootApplication
public class FitapetApplication {

public static void main(String[] args) {
SpringApplication.run(FitapetApplication.class, args);
}
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/com/kcy/fitapet/domain/care/domain/Care.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.kcy.fitapet.domain.care.domain;

import com.kcy.fitapet.domain.member.domain.Member;
import com.kcy.fitapet.domain.model.Auditable;
import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "CARE")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@ToString(of = {"careName", "dtype"})
public class Care extends Auditable {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "care_name")
private String careName;
@Column(name = "dtype")
@Convert(converter = CareTypeConverter.class)
private CareType dtype;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id", updatable = false)
private Member author;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "last_editor_id")
private Member lastEditor;
@OneToMany(mappedBy = "care", cascade = CascadeType.ALL)
private List<CareDetail> careDetails = new ArrayList<>();

@Builder
private Care(String careName, CareType dtype) {
this.careName = careName;
this.dtype = dtype;
}

public static Care of(String careName, CareType dtype) {
return Care.builder()
.careName(careName)
.dtype(dtype)
.build();
}
}
Loading

0 comments on commit 8dae02e

Please sign in to comment.