Skip to content
Open
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
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ aws-credentials.txt
credentials

### Docker 관련 ###
docker-compose.yml
docker-compose.override.yml
.dockerignore
*.log

Expand All @@ -123,3 +121,5 @@ Desktop.ini # Windows

### Lombok 관련 캐시 ###
*.lombok.log

data/
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ WORKDIR /app
# 1단계에서 생성된 JAR 파일만 복사
COPY --from=builder /app/build/libs/*.jar ./app.jar

# 컨테이너 외부에서 접근할 포트
EXPOSE 80
# 컨테이너 외부에서 접근할 포트 (앱은 8080에서 리슨)
EXPOSE 8080

ENV PROJECT_NAME=discodeit
ENV PROJECT_VERSION=1.2-M8
Expand Down
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ext {
}

group = 'com.sprint.mission'
version = '2.2-M11'
version = '3.0-M12'

java {
toolchain {
Expand All @@ -34,6 +34,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'org.springframework.boot:spring-boot-starter-websocket'
testImplementation 'org.springframework.security:spring-security-test'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
Expand Down Expand Up @@ -69,6 +70,7 @@ dependencies {

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

implementation 'org.springframework.security:spring-security-messaging'
}
dependencyManagement {
imports {
Expand Down
11 changes: 9 additions & 2 deletions discodeit.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,16 @@ AWS_S3_PRESIGNED_URL_EXPIRATION=

# DataSource Configuration
RDS_ENDPOINT=
SPRING_DATASOURCE_URL=jdbc:
SPRING_DATASOURCE_URL=
SPRING_DATASOURCE_USERNAME=
SPRING_DATASOURCE_PASSWORD=

STORAGE_LOCAL_ROOT_PATH=

# JVM Configuration (프리티어 고려)
JVM_OPTS=
JVM_OPTS=

ADMIN_PASSWORD=

# Local Storage Path inside app container
STORAGE_LOCAL_ROOT_PATH=
48 changes: 24 additions & 24 deletions docker-compose-kafka.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# https://developer.confluent.io/confluent-tutorials/kafka-on-docker/#the-docker-compose-file
services:
broker:
image: apache/kafka:latest
hostname: broker
container_name: broker
ports:
- 9092:9092
environment:
KAFKA_BROKER_ID: 1
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_NODE_ID: 1
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@broker:29093
KAFKA_LISTENERS: PLAINTEXT://broker:29092,CONTROLLER://broker:29093,PLAINTEXT_HOST://0.0.0.0:9092
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
## https://developer.confluent.io/confluent-tutorials/kafka-on-docker/#the-docker-compose-file
#services:
# broker:
# image: apache/kafka:latest
# hostname: broker
# container_name: broker
# ports:
# - 9092:9092
# environment:
# KAFKA_BROKER_ID: 1
# KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT,CONTROLLER:PLAINTEXT
# KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:29092,PLAINTEXT_HOST://localhost:9092
# KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
# KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
# KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
# KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
# KAFKA_PROCESS_ROLES: broker,controller
# KAFKA_NODE_ID: 1
# KAFKA_CONTROLLER_QUORUM_VOTERS: 1@broker:29093
# KAFKA_LISTENERS: PLAINTEXT://broker:29092,CONTROLLER://broker:29093,PLAINTEXT_HOST://0.0.0.0:9092
# KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
# KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
# KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
# CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
26 changes: 13 additions & 13 deletions docker-compose-redis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# https://developer.confluent.io/confluent-tutorials/kafka-on-docker/#the-docker-compose-file
services:
redis:
image: redis:7.2-alpine
container_name: redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes

volumes:
redis-data:
## https://developer.confluent.io/confluent-tutorials/kafka-on-docker/#the-docker-compose-file
#services:
# redis:
# image: redis:7.2-alpine
# container_name: redis
# ports:
# - "6379:6379"
# volumes:
# - redis-data:/data
# command: redis-server --appendonly yes
#
#volumes:
# redis-data:
149 changes: 149 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Docker Compose를 활용한 멀티 컨테이너 환경 구성
# Spring Boot 애플리케이션 + PostgreSQL 데이터베이스 연동
# version: '3.8' # (Compose V2에서 불필요하여 주석 처리)

# ====================================================================
# 서비스 정의
# ====================================================================
services:
##################################################################
# DB (내부 전용): 외부 포트 미노출, 백엔드만 접근
##################################################################
postgres:
image: postgres:17-alpine
# container_name: discodeit-db
restart: unless-stopped
env_file:
- .env
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
# 외부 노출 금지: ports 제거
volumes:
- postgres_data:/var/lib/postgresql/data
# - ./src/main/resources/schema.sql:/docker-entrypoint-initdb.d/schema.sql:ro
configs:
- source: schema_sql
target: /docker-entrypoint-initdb.d/001-schema.sql
mode: 0444
healthcheck: # [ADDED] DB 준비 여부 확인
test: ["CMD-SHELL", "pg_isready -U $POSTGRES_USER -d $POSTGRES_DB -h 127.0.0.1"]
interval: 5s
timeout: 3s
retries: 20
start_period: 20s
deploy:
mode: replicated
replicas: 1

##################################################################
# Redis (내부 전용): 외부 포트 미노출, 백엔드만 접근
##################################################################
redis:
image: redis:7.2-alpine
# container_name: discodeit-redis
restart: unless-stopped
# 외부 노출 금지: ports 없음
volumes:
- redis-data:/data
command: redis-server --appendonly yes

##################################################################
# Kafka (KRaft, 내부 전용): 외부 포트 미노출, 백엔드만 접근
##################################################################
broker:
image: apache/kafka:latest
hostname: broker
# container_name: discodeit-kafka
restart: unless-stopped
# 외부 노출 금지: ports 없음
environment:
KAFKA_BROKER_ID: 1
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:29092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_NODE_ID: 1
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@broker:29093
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,CONTROLLER://0.0.0.0:29093
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk

##################################################################
# Backend (내부 전용): 외부 포트 미노출, Nginx만 접근
##################################################################
app:
image: discodeit-app:1.0.0
build: .
# container_name: discodeit-app
restart: unless-stopped
env_file:
- .env
volumes:
- ./data/discodeit/storage:${STORAGE_LOCAL_ROOT_PATH:-/app/data/discodeit/storage}
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB}
SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER}
SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
SPRING_KAFKA_BOOTSTRAP_SERVERS: ${SPRING_KAFKA_BOOTSTRAP_SERVERS:-broker:29092}
REDIS_HOST: ${REDIS_HOST:-redis}
REDIS_PORT: ${REDIS_PORT:-6379}
STORAGE_LOCAL_ROOT_PATH: ${STORAGE_LOCAL_ROOT_PATH:-/app/data/discodeit/storage}
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-dev}
PORT: ${PORT:-8080}
JWT_ACCESS_TOKEN: ${JWT_ACCESS_TOKEN}
JWT_REFRESH_TOKEN: ${JWT_REFRESH_TOKEN}
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
broker:
condition: service_started
deploy:
mode: replicated
replicas: 3
endpoint_mode: dnsrr
networks:
- default
- mesh

##################################################################
# Reverse Proxy (외부 유일 진입점: 3000 → 컨테이너 80)
##################################################################
nginx:
image: discodeit-nginx:1.0.0
build:
context: . # [CHANGED] Nginx 빌드 컨텍스트를 프로젝트 루트로 변경
dockerfile: nginx/Dockerfile # [CHANGED] Dockerfile 경로 명시
container_name: discodeit-nginx-lb
depends_on:
- app
deploy:
mode: replicated
replicas: 1
ports:
- "3000:80"
# restart: unless-stopped
networks:
- default # [ADDED] 기본 네트워크도 연결해 DNS 해석 안정화
- mesh # [ADDED]

configs:
schema_sql:
file: ./src/main/resources/schema.sql

volumes:
postgres_data:
redis-data:

networks:
mesh: # [ADDED] Nginx ↔ app 전용 사용자 정의 네트워크
18 changes: 18 additions & 0 deletions nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM nginx:alpine

# 기본 제공 default.conf 제거(충돌 방지)
RUN rm /etc/nginx/conf.d/default.conf

# 우리의 리버스 프록시 설정 복사(80 포트에서 동작)
COPY nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

# 정적 리소스(프론트엔드 빌드 산출물) 복사
# 프로젝트 내 src/main/resources/static 을 컨테이너 표준 경로로 복사
COPY src/main/resources/static /usr/share/nginx/html

# 정적/인증서 디렉토리 보강(필요 시)
RUN mkdir -p /usr/share/nginx/html/static && \
mkdir -p /etc/nginx/certs

# 외부 노출은 80만 사용(Compose에서 3000:80)
EXPOSE 80
Loading