Skip to content
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
75 changes: 51 additions & 24 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,33 +1,60 @@
# Docker 이미지를 위한 설정 파일 (레시피)
# 이 파일을 통해 Java 환경이 완벽하게 갖춰진 이미지를 만듦
# [멀티스테이지 빌드] 이 파일은 2단계(스테이지)로 나뉨:
# - 빌드 스테이지: 소스코드를 받아서 jar 파일로 빌드 (요리하는 주방)
# - 실행 스테이지: 완성된 jar만 가져와서 실행 (손님에게 나가는 접시)
# 이렇게 나누는 이유:
# 1. Render 같은 배포 서버는 git 저장소만 받아감 → build/libs 폴더가 없음 → 서버가 직접 빌드해야 함
# 2. 최종 이미지에 Gradle, 소스코드 같은 빌드 도구를 안 남겨서 이미지가 가볍고 안전해짐

# 1단계: 기초 이미지 선택 (운영체제 + Java)
# FROM: 어떤 기초 이미지를 사용할 것인가?
# eclipse-temurin:21-jdk = Java 21이 이미 설치된 리눅스 이미지
# eclipse-temurin = OpenJDK의 공식 배포판 (가장 안정적)
FROM eclipse-temurin:21-jdk
# ─────────── 1단계: 빌드 스테이지 ───────────
# FROM ... AS builder : 이 스테이지에 "builder"라는 이름을 붙임 (아래에서 참조하기 위해)
# eclipse-temurin:21-jdk = Java 21 개발도구(JDK)가 설치된 리눅스 이미지 (빌드엔 JDK가 필요)
FROM eclipse-temurin:21-jdk AS builder

# 2단계: 작업 디렉토리 설정
# WORKDIR: 컨테이너 내부에서 어디를 기본 위치로 할 것인가?
# /app = 모든 파일을 /app 폴더에 저장
# 컨테이너 내부 작업 폴더를 /app으로 지정
WORKDIR /app

# 3단계: 빌드된 jar 파일을 컨테이너로 복사
# COPY: 파일을 복사해서 넣는 명령어
# ./build/libs/again-0.0.1-SNAPSHOT.jar = 로컬 PC의 jar 파일 (build.gradle의 artifactId에서 결정됨)
# app.jar = 컨테이너 내부에서의 이름 (간단하게)
# 주의: 이 jar 파일은 미리 빌드되어 있어야 함 (gradle build 후)
COPY build/libs/again-0.0.1-SNAPSHOT.jar app.jar
# Gradle 관련 파일들을 먼저 복사 (소스코드보다 먼저 복사하는 이유: Docker 캐시 활용)
# gradlew = Gradle을 설치 없이 실행해주는 스크립트 (로컬에서 ./gradlew 하던 그것)
# gradle/ = gradlew가 사용하는 Gradle 본체 설정 폴더
# build.gradle, settings.gradle = 프로젝트 빌드 설정 (의존성 목록 등)
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./

# 4단계: 컨테이너가 실행될 때 뭘 할 것인가?
# ENTRYPOINT: 컨테이너 시작 시 실행할 명령어 (변경 불가)
# java -jar app.jar = jar 파일 실행
# gradlew 스크립트에 실행 권한 부여 (리눅스는 권한 없으면 실행 거부함)
RUN chmod +x gradlew

# 의존성(라이브러리)만 미리 다운로드
# || true = 이 명령이 실패해도 무시하고 계속 진행 (소스코드가 아직 없어서 일부 작업은 실패할 수 있음)
# 이 줄의 목적: 소스코드만 바뀌었을 때 라이브러리 다운로드를 다시 안 하도록 캐시를 만들어둠 (재배포 속도 향상)
RUN ./gradlew dependencies --no-daemon || true

# 이제 소스코드 전체를 복사
COPY src src

# jar 파일로 빌드
# -x test = 테스트는 건너뜀 (테스트는 GitHub Actions CI에서 이미 돌고 있음.
# 여기서 또 돌리면 배포가 느려지고, DB가 없는 빌드 환경이라 실패할 수도 있음)
# --no-daemon = 백그라운드 프로세스 없이 1회성 실행 (컨테이너 환경 권장 옵션)
RUN ./gradlew build -x test --no-daemon

# ─────────── 2단계: 실행 스테이지 ───────────
# 새로운 깨끗한 이미지에서 다시 시작
# 21-jre = 실행 전용 Java (JRE). 빌드도구가 빠져서 JDK보다 가벼움
FROM eclipse-temurin:21-jre

WORKDIR /app

# COPY --from=builder : 위 "builder" 스테이지에서 만든 파일을 가져옴
# 소스코드, Gradle 등은 안 가져오고 완성된 jar 딱 하나만 가져옴
COPY --from=builder /app/build/libs/again-0.0.1-SNAPSHOT.jar app.jar

# 컨테이너 시작 시 실행할 명령어: java -jar app.jar (서버 실행)
ENTRYPOINT ["java", "-jar", "app.jar"]

# ⚠️ 주의: 환경변수 설정
# 현재 이 Dockerfile은 환경변수 설정이 없음
# docker run 할 때 -e 옵션으로 환경변수를 넘겨줘야 함
# 예: docker run -e DB_PASSWORD=xxx -e JWT_SECRET=yyy app
# 이 컨테이너는 8080 포트를 사용한다고 문서화 (Render는 PORT 환경변수로 실제 포트를 알려줌)
EXPOSE 8080

# Nginx 기본포트는 80
EXPOSE 8080
# ⚠️ 환경변수(DB 접속정보, JWT 비밀키 등)는 이미지에 넣지 않음
# → Render 대시보드의 Environment 설정에서 주입함 (지난번 터미널에서 export 했던 것과 같은 원리)
3 changes: 2 additions & 1 deletion frontend/src/api/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

// import.meta.env: Vite가 제공하는 환경변수 접근 객체
// VITE_API_URL이 .env 파일에 설정돼 있으면 그 값을 쓰고, 없으면 로컬 백엔드 주소 사용
const BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8080';
// export: 카카오 로그인처럼 api 객체를 거치지 않고 백엔드 주소가 직접 필요한 곳에서도 쓰도록 공개
export const BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:8080';

// 모든 API 호출에서 공통으로 사용하는 fetch 래퍼 함수
// path: '/api/musicians' 같은 API 경로
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/pages/auth/KakaoLoginModal.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import Logo from '../../components/Logo';
import Icon from '../../components/Icon';
// BASE_URL: 백엔드 주소 (VITE_API_URL 환경변수 또는 로컬 기본값) — 하드코딩 대신 이걸 사용
import { BASE_URL } from '../../api/client';

export default function KakaoLoginModal({ onClose, onLogin, reason }) {
return (
Expand All @@ -18,7 +20,8 @@ export default function KakaoLoginModal({ onClose, onLogin, reason }) {
</p>

<button className="btn kakao full lg" onClick={() => {
window.location.href = 'http://localhost:8080/oauth2/authorization/kakao';
// 카카오 로그인 시작: 백엔드의 OAuth2 시작 주소로 브라우저를 통째로 이동 (fetch가 아닌 페이지 이동이라 api 객체 대신 BASE_URL 직접 사용)
window.location.href = `${BASE_URL}/oauth2/authorization/kakao`;
}}>
<Icon name="chat" size={18} /> 카카오 계정으로 로그인 / 가입
</button>
Expand Down
Loading