세종대학교 해커톤을 위한 Spring Boot 기반 REST API 서버입니다.
- Java 21
- Spring Boot 3.5.5
- Spring Security - JWT 기반 인증/인가
- Spring Data JPA + QueryDSL - 데이터베이스 접근
- PostgreSQL - 메인 데이터베이스
- Redis - 세션 관리 (예정)
- Docker + Docker Compose - 컨테이너화
- AWS ECR - Docker 이미지 저장소
- AWS EC2 - 서버 호스팅
- GitHub Actions - CI/CD 파이프라인
- Swagger/OpenAPI - API 문서화
- Lombok - 코드 간소화
- P6Spy - SQL 쿼리 로깅
- Sejong Portal Login - 세종대 포털 로그인 연동
- 세종대학교 포털 로그인 연동
- 세종대 포털 계정으로 간편 로그인
- 최초 로그인 시 회원 정보 자동 생성
- JWT 기반 인증
- Access Token / Refresh Token
- Stateless 인증 방식
- 내 정보 조회
- 회원 정보 자동 동기화 (포털 연동)
- 회원 상태 관리 (ACTIVE, INACTIVE, BANNED)
- Spring Security 기반 보안 설정
- JWT 토큰 인증/인가
- CORS 설정
- 비밀번호 암호화 (BCrypt)
- Java 21
- Docker & Docker Compose
- PostgreSQL 14+
- Redis (선택)
- 레포지토리 클론
git clone https://github.com/2025-Sejong-Hackathon/hackathon-backend.git
cd hackathon-backend- 환경 변수 설정
# src/main/resources/application-dev.yml 참고
# 또는 환경 변수로 설정
export DATASOURCE_URL=jdbc:postgresql://localhost:5432/hackathon
export DATASOURCE_USERNAME=your_username
export DATASOURCE_PASSWORD=your_password
export REDIS_HOST=localhost
export REDIS_PORT=6379
export JWT_SECRET=your-secret-key-min-32-characters
export JWT_ACCESS_TOKEN_EXPIRATION=3600000
export JWT_REFRESH_TOKEN_EXPIRATION=604800000- 데이터베이스 준비
# Docker로 PostgreSQL 실행
docker run -d \
--name hackathon-postgres \
-e POSTGRES_DB=hackathon \
-e POSTGRES_USER=hackathon \
-e POSTGRES_PASSWORD=password \
-p 5432:5432 \
postgres:14- 애플리케이션 실행
# Gradle 빌드 및 실행
./gradlew bootRun --args='--spring.profiles.active=dev'- API 문서 확인
http://localhost:8080/swagger-ui.html
개발 환경에서는 Swagger UI를 통해 API를 테스트할 수 있습니다.
- URL:
http://localhost:8080/swagger-ui.html - OpenAPI Spec:
http://localhost:8080/api-docs
POST /api/v1/auth/login # 세종대 포털 로그인
POST /api/v1/auth/refresh # 토큰 갱신
GET /api/v1/members/me # 내 정보 조회
GET /actuator/health # 서버 상태 확인
외부 요청 → Nginx (80/443) → Docker (8082:8080) → Spring Boot (8080)
- Nginx: 리버스 프록시, 로드밸런싱
- Docker: 컨테이너 격리 환경
- Spring Boot: 애플리케이션 서버
# 환경 변수 설정
export ECR_REGISTRY=your-account.dkr.ecr.ap-northeast-2.amazonaws.com
export ECR_REPO=hackathon-backend
# .env 파일 생성 (docker-compose.yml과 같은 위치)
cat > .env << EOF
SPRING_PROFILES_ACTIVE=prod
DATASOURCE_URL=jdbc:postgresql://your-db-host:5432/hackathon
DATASOURCE_USERNAME=your_username
DATASOURCE_PASSWORD=your_password
REDIS_HOST=your-redis-host
REDIS_PORT=6379
JWT_SECRET=your-secret-key
JWT_ACCESS_EXPIRATION=3600000
JWT_REFRESH_EXPIRATION=604800000
EOF
# 컨테이너 실행
docker-compose up -d# 이미지 빌드
docker build -t hackathon-backend .
# 컨테이너 실행
docker run -d \
-p 8082:8080 \
--env-file .env \
--name hackathon-backend \
hackathon-backend자동 배포 파이프라인이 구성되어 있습니다.
main브랜치에 Push → 자동 배포 시작- 빌드 → Docker 이미지 생성
- Push to ECR → AWS ECR에 이미지 업로드
- Deploy to EC2 → SSH로 EC2 접속하여 배포
GitHub Repository → Settings → Secrets and variables → Actions에 등록:
AWS_ACCOUNT_ID # AWS 계정 ID
EC2_HOST # EC2 인스턴스 IP/도메인
EC2_USER # SSH 사용자명 (ubuntu)
EC2_KEY # SSH 프라이빗 키 (PEM 파일 내용)
# 1. 이미지 빌드
./gradlew clean build -x test
docker build -t hackathon-backend .
# 2. ECR에 Push
aws ecr get-login-password --region ap-northeast-2 | \
docker login --username AWS --password-stdin ${ECR_REGISTRY}
docker tag hackathon-backend:latest ${ECR_REGISTRY}/hackathon-backend:latest
docker push ${ECR_REGISTRY}/hackathon-backend:latest
# 3. EC2에서 Pull & 실행
ssh ubuntu@your-ec2-host
docker pull ${ECR_REGISTRY}/hackathon-backend:latest
docker-compose up -d자세한 배포 가이드는 DEPLOYMENT_NOTES.md를 참고하세요.
hackathon-backend/
├── src/
│ ├── main/
│ │ ├── java/com/hackathon/backend/
│ │ │ ├── api/ # API Layer (Controller, DTO)
│ │ │ │ ├── auth/ # 인증 API
│ │ │ │ └── member/ # 회원 API
│ │ │ ├── domain/ # Domain Layer (Service, Entity, Repository)
│ │ │ │ ├── auth/ # 인증 도메인
│ │ │ │ └── member/ # 회원 도메인
│ │ │ ├── global/ # Global 설정 및 유틸리티
│ │ │ │ ├── aop/ # AOP (로깅 등)
│ │ │ │ ├── config/ # 설정 클래스
│ │ │ │ ├── entity/ # BaseEntity 등
│ │ │ │ ├── exception/ # 예외 처리
│ │ │ │ ├── jwt/ # JWT 유틸리티
│ │ │ │ ├── response/ # 공통 응답 형식
│ │ │ │ └── security/ # Spring Security 설정
│ │ │ └── config/ # 메인 설정 파일
│ │ │ ├── JwtProperties.java
│ │ │ ├── SecurityConfig.java
│ │ │ ├── SwaggerConfig.java
│ │ │ └── WebMvcConfig.java
│ │ └── resources/
│ │ ├── application.yml # 공통 설정
│ │ ├── application-dev.yml # 개발 환경
│ │ ├── application-prod.yml # 운영 환경
│ │ └── spy.properties # P6Spy 설정
│ └── test/ # 테스트 코드
├── infra/ # 인프라 설정
│ ├── nginx/ # Nginx 리버스 프록시 설정
│ │ ├── hackathon-backend.conf # Nginx 설정 파일
│ │ └── README.md # Nginx 설정 가이드
│ └── postgres/ # PostgreSQL 설정
│ └── docker-compose.yml
├── .github/
│ └── workflows/
│ └── deploy.yml # CI/CD 파이프라인
├── Dockerfile
├── docker-compose.yml
└── README.md
┌─────────────────────────────────────────────────────┐
│ 클라이언트 │
└─────────────────┬───────────────────────────────────┘
│ HTTP/HTTPS
↓
┌─────────────────────────────────────────────────────┐
│ Nginx (리버스 프록시 & 로드밸런싱) │
│ - 포트: 80 (HTTP), 443 (HTTPS) │
│ - 로드밸런싱 알고리즘: least_conn │
└─────────────────┬───────────────────────────────────┘
│ 8082
↓
┌─────────────────────────────────────────────────────┐
│ Docker Container (격리된 환경) │
│ - 외부: 8082 / 내부: 8080 │
│ ┌───────────────────────────────────────────────┐ │
│ │ Spring Boot Application │ │
│ │ - 포트: 8080 │ │
│ │ - Spring Security + JWT │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────┬───────────────────────────────────┘
│
┌─────────┴─────────┐
↓ ↓
┌─────────────────┐ ┌─────────────────┐
│ PostgreSQL │ │ Redis │
│ (Database) │ │ (Cache/Session)│
└─────────────────┘ └─────────────────┘
┌─────────────────────────────────┐
│ API Layer (Controller) │ ← HTTP 요청/응답 처리
├─────────────────────────────────┤
│ Domain Layer (Service) │ ← 비즈니스 로직
├─────────────────────────────────┤
│ Infrastructure Layer (Repository)│ ← 데이터 접근
└─────────────────────────────────┘
Client → Controller → Security Filter → JWT Validation
↓ ↓
Response ← Service ← Repository ← Load User Data
자세한 가이드: infra/nginx/README.md
# 1. Nginx 설치
sudo apt install nginx -y
# 2. 설정 파일 복사
sudo cp infra/nginx/hackathon-backend.conf /etc/nginx/sites-available/
sudo ln -s /etc/nginx/sites-available/hackathon-backend.conf /etc/nginx/sites-enabled/
# 3. 설정 테스트
sudo nginx -t
# 4. Nginx 재시작
sudo systemctl restart nginx단일 서버에서 시작하지만, 트래픽이 증가하면 다음과 같이 확장 가능:
upstream hackathon_backend {
least_conn; # 연결 수가 적은 서버로 분산
server localhost:8082 weight=1;
server localhost:8083 weight=1;
server localhost:8084 weight=1;
}- ✅ 리버스 프록시: 외부 요청을 백엔드로 전달
- ✅ 로드밸런싱: 다중 서버 부하 분산 (확장 시)
- ✅ SSL/TLS: HTTPS 지원 (Let's Encrypt)
- ✅ Rate Limiting: DDoS 방어
- ✅ 캐싱: API 응답 캐싱 (선택적)
- ✅ Gzip 압축: 응답 크기 최적화
- 공통 설정: 모든 프로파일에 적용
- JWT 설정: 토큰 만료 시간 등
- Logging 설정: 로그 레벨
- 개발 환경 설정
ddl-auto: update- 스키마 자동 업데이트show-sql: true- SQL 쿼리 로깅- Swagger UI 활성화
- 운영 환경 설정
ddl-auto: validate- 스키마 검증만 수행show-sql: false- SQL 쿼리 로깅 비활성화- Swagger UI 비활성화
- Connection Pool 최적화
# 전체 테스트 실행
./gradlew test
# 특정 테스트 실행
./gradlew test --tests com.hackathon.backend.domain.auth.service.AuthServiceTest
# 테스트 리포트 확인
open build/reports/tests/test/index.html- Lombok 활용으로 보일러플레이트 코드 최소화
- Builder 패턴 사용 (Entity 생성)
- LayeredArchitecture 준수
- RESTful API 설계 원칙 준수
main: 운영 환경 (자동 배포)develop: 개발 환경feature/*: 기능 개발hotfix/*: 긴급 수정
feat: 새로운 기능 추가
fix: 버그 수정
docs: 문서 수정
refactor: 코드 리팩토링
test: 테스트 코드 추가
chore: 빌드 설정, 패키지 매니저 수정
-
데이터베이스 연결 실패
- PostgreSQL이 실행 중인지 확인
DATASOURCE_URL환경 변수 확인
-
JWT 토큰 오류
JWT_SECRET이 최소 32자 이상인지 확인- 토큰 만료 시간 확인
-
세종대 포털 로그인 실패
- 세종대 포털 서버 상태 확인
- 학번/비밀번호 정확성 확인
자세한 문제 해결은 DEPLOYMENT_NOTES.md를 참고하세요.
2025 세종대학교 해커톤 백엔드 팀
This project is licensed under the MIT License.
Made with ❤️ by Sejong Hackathon Team