Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0f47731
💡 주석 수정
Kim-Yukyung Jun 16, 2025
a0e1c6b
💡 주석 수정
Kim-Yukyung Jun 16, 2025
04bf5f9
✨ 레디스 설정 추가
Kim-Yukyung Jun 16, 2025
a893b9c
♻️ Refactor
Kim-Yukyung Jun 16, 2025
f161091
♻️ Refactor
Kim-Yukyung Jun 16, 2025
61770b8
♻️ 파일명 변경 & 제약조건 추가
Kim-Yukyung Jun 16, 2025
92ddda6
♻️ 로깅 관련 개선
Kim-Yukyung Jun 16, 2025
ee920f5
🚚 예약어 충돌로 파일 이름 변경
Kim-Yukyung Jun 16, 2025
1ea9744
✨ 카카오 로그인 로직 수정
Kim-Yukyung Jun 16, 2025
4db2530
✨ JPA 추가
Kim-Yukyung Jun 16, 2025
30e9c63
♻️ JWT 관련 로직 수정
Kim-Yukyung Jun 16, 2025
23befa7
✨ 토큰 처리 수정
Kim-Yukyung Jun 16, 2025
f72d5f2
♻️ Refactor (주석, JWT 로직)
Kim-Yukyung Jun 16, 2025
21d4437
✨ 회원가입/로그인 로직 수정
Kim-Yukyung Jun 16, 2025
92597b1
✨ 거절/삭제 기능 추가 & 리팩토링
Kim-Yukyung Jun 16, 2025
f17442b
♻️ 입력 제한 및 검증 추가
Kim-Yukyung Jun 16, 2025
0f20154
✨ 토큰 블랙리스트 추가
Kim-Yukyung Jun 16, 2025
8754d4b
♻️ 검증 관련 로직 추가
Kim-Yukyung Jun 16, 2025
fb785ef
♻️ 검증 관련 로직 추가
Kim-Yukyung Jun 16, 2025
188536f
✨ 환경변수 변경 및 프로파일 설정
Kim-Yukyung Jun 16, 2025
24f3f57
💡 주석 수정
Kim-Yukyung Jun 16, 2025
20ae790
🔧 의존성 추가
Kim-Yukyung Jun 16, 2025
ef5efc5
♻️ 환경변수 제거
Kim-Yukyung Jun 16, 2025
581659d
♻️ 도커 관련 파일 수정
Kim-Yukyung Jun 16, 2025
f8c304f
✅ Test 코드 추가
Kim-Yukyung Jun 16, 2025
e8cf114
♻️ @Builder.Default 경고 수정
Kim-Yukyung Jun 16, 2025
6cfece3
📝 환경변수 예시 파일 생성
Kim-Yukyung Jun 16, 2025
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
44 changes: 44 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Git
.git
.gitignore
.gitattributes

# IDE
.idea
.vscode
*.iml

# Build outputs
build/
.gradle/
gradle/
gradlew
gradlew.bat

# Documentation
README.md
*.md

# Environment files
.env*
!.env.example

# Logs
*.log
logs/

# OS
.DS_Store
Thumbs.db

# Docker
Dockerfile
docker-compose.yml
.dockerignore

# Test files
src/test/

# Temporary files
tmp/
temp/
32 changes: 32 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
SPRING_PROFILES_ACTIVE=dev

# MySQL
DB_CONNECTION=localhost
DB_NAME=sayup_dev
DB_USERNAME=root
DB_PASSWORD=dev_password

# JWT
JWT_SECRET=dev_jwt_secret_key_for_development
JWT_EXPIRATION=3600000 # 1시간
JWT_REFRESH_EXPIRATION=86400000 # 1일

# Redis
REDIS_HOST=localhost
REDIS_PORT=6379

# 파일 업로드
FILE_UPLOAD_DIR=./uploads/dev

# 카카오 설정
KAKAO=your_kakao_dev_key
KAKAO_REDIRECT_URI=http://localhost:8080/api/auth/kakao/callback

# Python 서버
PYTHON_SERVER_URL=http://127.0.0.1:8000

# 프론트엔드 URL
FRONTEND_URL=http://localhost:3000

# OpenAI API 키
API_KEY=sk-your_openai_api_key_here
31 changes: 30 additions & 1 deletion .env.prod
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
# .env.prod

# 데이터베이스 환경변수
DB_USERNAME=root
DB_PASSWORD=0000
DB_CONNECTION=mysql
DB_NAME=sayup

# Redis 환경변수
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=redis

# JWT 관련
JWT_SECRET=your-jwt-secret
JWT_EXPIRATION=86400000
JWT_REFRESH_EXPIRATION=604800000

# 외부 API 키
CHATGPT_API_KEY=temp
DOCKERHUB_USERNAME=yukyung0
KAKAO_CLIENT_ID=kakao-temp-client-id
KAKAO_REDIRECT_URI=http://localhost:8080/api/auth/kakao/callback

# 파일 업로드 경로
FILE_UPLOAD_DIR=/app/tmp/file/userVoice

# Python 서버 URL
PYTHON_SERVER_URL=http://127.0.0.1:8000

# Docker 이미지 관련
DOCKERHUB_USERNAME=user
IMAGE_TAG=latest
37 changes: 25 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
FROM gradle:8.5-jdk17 AS build
WORKDIR /app
COPY . .
RUN gradle build -x test

FROM openjdk:17-jdk-slim

# 보안을 위한 비루트 사용자 생성
RUN groupadd -r sayup && useradd -r -g sayup sayup

# 필수 패키지 설치
RUN apt-get update && apt-get install -y \
curl \
&& rm -rf /var/lib/apt/lists/* \

WORKDIR /app
COPY --from=build /app/build/libs/*.jar app.jar

# 필요한 디렉토리 생성 및 권한 설정
RUN mkdir -p /app/logs /app/tmp/file/userVoice && \
chown -R sayup:sayup /app

USER sayup

# JAR 파일 복사 (빌드된 JAR 파일 이름에 맞춰 수정 필요)
COPY build/libs/SayUp-0.0.1-SNAPSHOT.jar app.jar
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"

ARG DB_PASSWORD
ARG API_KEY
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1

# 환경변수 설정
ENV DB_CONNECTION=mysql
ENV DB_NAME=sayup_db
ENV DB_USERNAME=root
ENV DB_PASSWORD=$DB_PASSWORD
ENV API_KEY=$API_KEY
ENV FILE_UPLOAD_DIR=/file/temp
EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
9 changes: 7 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mysql:1.20.0'
testImplementation 'com.h2database:h2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
Expand All @@ -55,7 +56,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'

// Swagger 3 (SpringDoc OpenAPI) 의존성
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'

// ClassGraph 버전 명시
implementation 'io.github.classgraph:classgraph:4.8.149'
Expand All @@ -74,7 +75,11 @@ dependencies {
// AOP
implementation 'org.springframework.boot:spring-boot-starter-aop'

implementation 'org.springframework.boot:spring-boot-starter-webflux'
// Redis 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

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

tasks.named('test') {
Expand Down
105 changes: 96 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,128 @@ services:
mysql:
image: mysql:8.0
container_name: sayup_mysql
restart: always
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
MYSQL_DATABASE: "sayup_db"
MYSQL_USER: "${DB_USERNAME}"
MYSQL_PASSWORD: "${DB_PASSWORD}"
TZ: "Asia/Seoul"
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- mysql_backup:/backup
- ./mysql/init:/docker-entrypoint-initdb.d
networks:
- app_network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
timeout: 20s
retries: 10
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M

redis:
image: redis:7-alpine
container_name: sayup_redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
- redis_backup:/backup
networks:
- app_network
command: redis-server --appendonly yes --requirepass "${REDIS_PASSWORD}"
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
timeout: 3s
retries: 5
deploy:
resources:
limits:
memory: 256M
reservations:
memory: 128M

app:
build: .
image: ${DOCKERHUB_USERNAME}/sayup:latest
container_name: sayup
restart: always
build:
context: .
dockerfile: Dockerfile
image: ${DOCKERHUB_USERNAME:-sayup}/sayup:${IMAGE_TAG:-latest}
container_name: sayup_app
restart: unless-stopped
depends_on:
- mysql
mysql:
condition: service_healthy
redis:
condition: service_healthy
env_file:
- .env.prod
environment:
SPRING_PROFILES_ACTIVE: "prod"
DB_CONNECTION: "mysql"
DB_HOST: "mysql"
DB_NAME: "sayup_db"
DB_USERNAME: "root"
DB_USERNAME: "${DB_USERNAME}"
DB_PASSWORD: "${DB_PASSWORD}"
# 경로 변경 필요
FILE_UPLOAD_DIR: "tmp/file/userVoice"
REDIS_HOST: "redis"
REDIS_PORT: "6379"
REDIS_PASSWORD: "${REDIS_PASSWORD}"
FILE_UPLOAD_DIR: "/app/tmp/file/userVoice"
API_KEY: "${CHATGPT_API_KEY}"
JWT_SECRET: "${JWT_SECRET}"
KAKAO_CLIENT_ID: "${KAKAO_CLIENT_ID}"
TZ: "Asia/Seoul"
ports:
- "8080:8080"
volumes:
- app_logs:/app/logs
- app_files:/app/tmp/file/userVoice
networks:
- app_network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
resources:
limits:
memory: 2G
cpus: '2.0'
reservations:
memory: 1G
cpus: '1.0'
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

networks:
app_network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16

volumes:
mysql_data:
driver: local
mysql_backup:
driver: local
redis_data:
driver: local
redis_backup:
driver: local
app_logs:
driver: local
app_files:
driver: local
Loading