λ¬Έμ μΈμ΄ μ ν | Select language: νκΈ (kor) Β· English (eng)
| λ°μ΄ν°λ² μ΄μ€ | 컨ν μ΄λ | μ©λ |
|---|---|---|
| Auth DB | msa-db-auth (PostgreSQL 15) |
μΈμ¦Β·κΆν, κ΄λ¦¬μ, OAuth2 μ°λ μ 보 |
| User DB | msa-db-user (PostgreSQL 15) |
μ¬μ©μ νλ‘νΒ·μ 보 |
| Post DB | msa-db-post (PostgreSQL 15) |
κ²μκΈ, λκΈ, μΉ΄ν κ³ λ¦¬Β·νκ·Έ |
| Search DB | msa-db-search (pgvector/pg15) |
λ²‘ν° κ²μ μΈλ±μ€ (sentence-transformers μλ² λ©) |
μ±λ΄ λνΒ·νμΌ λ±μ data/chatbot λλ ν°λ¦¬μ λ³Όλ₯¨μΌλ‘ μ μ₯λ©λλ€.
flowchart TB
subgraph Client
Browser[λΈλΌμ°μ ]
end
subgraph Nginx["Nginx (νΈμ€νΈ)"]
N[":443 / :80"]
end
subgraph Frontend
Next["Next.js\n:3000"]
end
subgraph Gateway["API Gateway :8085"]
GW[Spring Cloud Gateway]
end
subgraph Backend["λ°±μλ μλΉμ€"]
Auth[auth-service :8084]
User[user-service :8081]
Post[post-service :8082]
AI[fastapi-ai :8000]
Search[search-service :8010]
Mail[mail-service :8083]
end
subgraph Data["λ°μ΄ν°Β·μΈνλΌ"]
Redis[Redis :6379]
Kafka[Kafka :9092]
DBA[db-auth]
DBU[db-user]
DBP[db-post]
DBS[db-search]
end
Browser --> N
N -->|"/"| Next
N -->|"/user/,/auth/,/api/,/chat"| GW
GW --> Auth
GW --> User
GW --> Post
GW --> AI
GW --> Search
Auth --> Redis
Auth --> DBA
User --> DBU
User --> Kafka
Post --> DBP
Post --> Kafka
AI --> Redis
Search --> DBS
Search --> Kafka
Mail --> Kafka
- λ¨μΌ μ§μ μ : Nginx β API Gateway(Spring Cloud Gateway). λͺ¨λ APIλ Gatewayλ₯Ό κ±°μ³ JWT κ²μ¦Β·Trace ID λΆμ¬ ν κ° λ§μ΄ν¬λ‘μλΉμ€λ‘ λΌμ°ν λ©λλ€.
- νλ‘ νΈμλ: Next.js 14 (App Router). Nginxμμ
/λ Next.js(3000)λ‘ μ§μ νλ‘μλ©λλ€. - μ΄λ²€νΈ λ리λΈ: νμκ°μ Β·κ²μκΈ λ± μ΄λ²€νΈλ Kafkaλ‘ λ°νλλ©°, Mail μλΉμ€Β·Search μΈλ±μ± λ±μ΄ ꡬλ ν©λλ€.
- μΈνλΌ: Redis(μΊμΒ·Refresh TokenΒ·λνΉ), Kafka(KRaft λ¨μΌ λ Έλ), PostgreSQL 4μ’ (μλΉμ€λ³ DB λΆλ¦¬).
my-msa-project-new/
βββ backend/
β βββ gateway-service/ # Spring Cloud Gateway (JWT, λΌμ°ν
)
β βββ auth-service/ # λ‘κ·ΈμΈΒ·νμκ°μ
Β·OAuth2Β·JWT
β βββ user-service/ # μ¬μ©μ νλ‘ν
β βββ post-service/ # κ²μκΈΒ·λκΈ
β βββ smtp-service/ # Kafka μμ β μ΄λ©μΌ λ°μ‘
β βββ fastapi-ai/ # AI μ±λ΄ (LangChain, Groq)
β βββ search-service/ # FastAPI + pgvector λ²‘ν° κ²μ
βββ frontend/
β βββ nextjs-app/ # Next.js 14 μ±
βββ nginx/ # Nginx μ€μ (λ³λ μ μ₯μ/ν΄λ)
β βββ sites-available/
β βββ sites-enabled/
βββ monitoring/ # Loki Stack (Fluent Bit, Loki, Grafana)
βββ docs/ # νλ‘μ νΈΒ·Nginx λ¬Έμ
βββ data/ # DBΒ·μ±λ΄ λ³Όλ₯¨ λ§μ΄νΈ
βββ docker-compose.yml # λ©μΈ μ€μΌμ€νΈλ μ΄μ
βββ .env.example # νκ²½ λ³μ ν
νλ¦Ώ
- μ¬μ©μ β Nginx(HTTPS) β κ²½λ‘μ λ°λΌ λΆκΈ°
/β Next.js(3000): νμ΄μ§Β·μ μ μμ°/user/,/auth/,/api/posts,/api/search,/chatβ API Gateway(8085)- Gateway β JWT κ²μ¦(ν΄λΉ κ²½λ‘) Β· Trace ID λΆμ¬ β ν΄λΉ μλΉμ€λ‘ νλ‘μ
/user/**β user-service:8081/auth/**β auth-service:8084/api/posts/**β post-service:8082/api/search/**β search-service:8010/chat/**β fastapi-ai:8000
- μλΉμ€ β κ° DBΒ·RedisΒ·Kafka μ¬μ© ν μλ΅ β Gateway β Nginx β ν΄λΌμ΄μΈνΈ
Nginx μ€μ μ nginx/ λλ ν°λ¦¬μ μμΌλ©°, μ΄μμ sites-available/msa-project(νμ±: sites-enabled/msa-project)λ₯Ό μ¬μ©ν©λλ€.
| location | νλ‘μ λμ | λΉκ³ |
|---|---|---|
location / |
http://127.0.0.1:3000 |
Next.js |
location /user/ |
http://msa-gateway (127.0.0.1:8085) |
Gateway β user-service |
location /auth/ |
http://msa-gateway |
Gateway β auth-service |
location /api/posts |
http://msa-gateway |
Gateway β post-service |
location /api/search |
http://msa-gateway |
Gateway β search-service |
location /chat |
http://msa-gateway |
AI μ±λ΄ (νμμμ 600s) |
location /actuator |
http://msa-gateway |
ν¬μ€μ²΄ν¬Β·λ°±μ€νΌμ€ |
location /grafana/ |
http://127.0.0.1:3001 |
Grafana (monitoring νλ‘νμΌ) |
- μ
μ€νΈλ¦Ό:
upstream msa-gateway { server 127.0.0.1:8085 max_fails=2 fail_timeout=30s; keepalive 8; } - κ°λ° λλ©μΈ
dev.minkowskim.com:/β 4000, APIΒ·authΒ·userΒ·chat β 9085(Gateway).
μμΈν μ€λͺ
μ docs/nginx-aws-lightsail.mdλ₯Ό μ°Έκ³ νμΈμ.
Gateway κ²½λ‘μ λ°±μλ μλΉμ€ λ§€ν(μ΄μ: application-prod.yml κΈ°μ€)μ λ€μκ³Ό κ°μ΅λλ€.
| κ²½λ‘ | μλΉμ€ | μ€λͺ |
|---|---|---|
/user, /user/** |
user-service:8081 | μ¬μ©μ νλ‘νΒ·μ 보 |
/auth, /auth/** |
auth-service:8084 | λ‘κ·ΈμΈΒ·νμκ°μ Β·OAuth2Β·JWTΒ·μΈμ¦ λ©μΌ |
/api/posts, /api/posts/** |
post-service:8082 | κ²μκΈΒ·λκΈ CRUD |
/chat, /chat/** |
fastapi-ai:8000 | AI μ±λ΄ (SSE/μ€νΈλ¦¬λ°) |
/api/search, /api/search/** |
search-service:8010 | 벑ν°Β·ν€μλ κ²μ |
μΈμ¦μ΄ νμν APIλ Authorization: Bearer <JWT> λλ μΏ ν€(authToken)λ‘ μ λ¬ν©λλ€. μμΈ μλν¬μΈνΈλ κ° μλΉμ€ μμ€ λ° Gateway μ€μ μ μ°Έκ³ νμΈμ.
- Docker, Docker Compose
- (μ ν) Nginx μ€μΉ λ°
nginx/μ€μ λ°°μΉ
# 1. νκ²½ λ³μ μ€μ
cp .env.example .env
# .env λ΄ DB λΉλ°λ²νΈ, JWT_SECRET, OAuth2, GROQ_API_KEY λ± μμ
# 2. μ 체 μ€ν κΈ°λ (4GB λ©λͺ¨λ¦¬ κΈ°μ€)
docker compose up -d
# 3. (μ ν) λͺ¨λν°λ§ μ€ν κΈ°λ
docker compose --profile monitoring up -d- νλ‘ νΈμλ: http://localhost:3000
- API Gateway: http://localhost:8085 (Nginx μ¬μ© μ Nginxκ° 8085λ‘ νλ‘μ)
- Grafana(monitoring νλ‘νμΌ): http://localhost:3001
| μλΉμ€ | ν¬νΈ | κΈ°μ μ€ν | λΉκ³ |
|---|---|---|---|
| api-gateway | 8085 | Spring Boot 3, Spring Cloud Gateway | JWTΒ·Trace IDΒ·λΌμ°ν |
| auth-service | 8084 | Spring Boot, JPA, OAuth2, Redis, Kafka | κ΄λ¦¬μ λΆνΈμ€νΈλ© |
| user-service | 8081 | Spring Boot, JPA, Kafka | |
| post-service | 8082 | Spring Boot, JPA, WebClient, Kafka | |
| mail-service | 8083 | Spring Boot, Kafka, Mail | Kafka ꡬλ β SMTP |
| fastapi-ai | 8000 | FastAPI, LangChain, Groq, Redis | μ±λ΄ |
| search-service | 8010 | FastAPI, pgvector, Kafka | λ²‘ν° μΈλ±μ± |
| frontend | 3000 | Next.js 14 | |
| redis | 6379 | Redis Alpine | |
| msa-kafka | 9092 | Apache Kafka 3.7 (KRaft) | |
| db-auth / db-user / db-post / db-search | 5434/5432/5433/5435 | PostgreSQL 15, pgvector |
- λ°±μ€νΌμ€: Next.js
/backofficeνμ΄μ§μμ κ΄λ¦¬ κΈ°λ₯ μ 곡. Gateway/actuatorλ‘ ν¬μ€μ²΄ν¬ κ°λ₯. - λͺ¨λν°λ§:
docker compose --profile monitoring up -dλ‘ Fluent Bit β Loki β Grafana κΈ°λ. Grafanaλ Nginxμμ/grafana/λ‘ μ κ·Ό κ°λ₯(μ€μ μ 3001βνλ‘μ). - Kafka UI(μ ν):
docker compose --profile tools up -dλ‘ 8080μμ Kafka UI μ¬μ© κ°λ₯.
.env.exampleμ 볡μ¬ν΄ .envλ₯Ό λ§λ€κ³ μλ νλͺ©μ μ±μλλ€.
| κ΅¬λΆ | μ£Όμ λ³μ |
|---|---|
| DB | POSTGRES_USER, POSTGRES_PASSWORD, DB_AUTH_NAME, DB_USER_NAME, DB_POST_NAME, DB_SEARCH_NAME |
| JWTΒ·κ΄λ¦¬μ | JWT_SECRET, ADMIN_USERNAME, ADMIN_PASSWORD |
| OAuth2 | OAUTH2_GOOGLE_*, OAUTH2_KAKAO_*, COOKIE_DOMAIN, FRONTEND_URL |
| RedisΒ·Kafka | SPRING_REDIS_HOST, REDIS_*, SPRING_KAFKA_BOOTSTRAP_SERVERS |
| SMTP | MAIL_USERNAME, MAIL_PASSWORD |
| AI | GROQ_API_KEY |
| νλ‘ νΈ λΉλ μ | NEXT_PUBLIC_API_URL, NEXT_PUBLIC_AUTH_API_URL, NEXT_PUBLIC_*_API_URL |
| λͺ¨λν°λ§ | GRAFANA_ADMIN_PASSWORD |
| λ¬Έμ | μ€λͺ |
|---|---|
docs/PROJECT_UPDATES.md |
νλ‘μ νΈ μ λ°μ΄νΈΒ·λ³κ²½ μ΄λ ₯ |
docs/nginx-aws-lightsail.md |
Nginx λλ ν°λ¦¬ ꡬ쑰, λΌμ°ν , SSL, Lightsail μ°Έκ³ |
nginx/sites-available/msa-project |
μ΄μ Nginx μ€μ νμΌ |
monitoring/docker-compose.monitoring.yml |
Loki Stack λͺ¨λν°λ§ Compose |
Select language: νκΈ (kor) Β· English (eng)
| Database | Container | Purpose |
|---|---|---|
| Auth DB | msa-db-auth (PostgreSQL 15) |
Authentication, authorization, admin, OAuth2 |
| User DB | msa-db-user (PostgreSQL 15) |
User profiles and info |
| Post DB | msa-db-post (PostgreSQL 15) |
Posts, comments, categories, tags |
| Search DB | msa-db-search (pgvector/pg15) |
Vector search index (sentence-transformers embeddings) |
Chatbot conversations and files are stored under data/chatbot (volume).
flowchart TB
subgraph Client
Browser[Browser]
end
subgraph Nginx["Nginx (Host)"]
N[":443 / :80"]
end
subgraph Frontend
Next["Next.js\n:3000"]
end
subgraph Gateway["API Gateway :8085"]
GW[Spring Cloud Gateway]
end
subgraph Backend["Backend Services"]
Auth[auth-service :8084]
User[user-service :8081]
Post[post-service :8082]
AI[fastapi-ai :8000]
Search[search-service :8010]
Mail[mail-service :8083]
end
subgraph Data["Data & Infra"]
Redis[Redis :6379]
Kafka[Kafka :9092]
DBA[db-auth]
DBU[db-user]
DBP[db-post]
DBS[db-search]
end
Browser --> N
N -->|"/"| Next
N -->|"/user/,/auth/,/api/,/chat"| GW
GW --> Auth
GW --> User
GW --> Post
GW --> AI
GW --> Search
Auth --> Redis
Auth --> DBA
User --> DBU
User --> Kafka
Post --> DBP
Post --> Kafka
AI --> Redis
Search --> DBS
Search --> Kafka
Mail --> Kafka
- Single entry point: Nginx β API Gateway (Spring Cloud Gateway). All API traffic is validated (JWT), tagged with Trace ID, then routed to microservices.
- Frontend: Next.js 14 (App Router). Nginx proxies
/to Next.js on port 3000. - Event-driven: User/post events are published to Kafka; Mail and Search services consume them.
- Infrastructure: Redis (cache, refresh tokens, rankings), Kafka (KRaft single node), four PostgreSQL instances (one per domain).
my-msa-project-new/
βββ backend/
β βββ gateway-service/ # Spring Cloud Gateway (JWT, routing)
β βββ auth-service/ # Login, signup, OAuth2, JWT
β βββ user-service/ # User profiles
β βββ post-service/ # Posts, comments
β βββ smtp-service/ # Kafka β email (SMTP)
β βββ fastapi-ai/ # AI chatbot (LangChain, Groq)
β βββ search-service/ # FastAPI + pgvector search
βββ frontend/
β βββ nextjs-app/ # Next.js 14 app
βββ nginx/ # Nginx config (separate folder)
β βββ sites-available/
β βββ sites-enabled/
βββ monitoring/ # Loki Stack (Fluent Bit, Loki, Grafana)
βββ docs/ # Project and Nginx docs
βββ data/ # DB and chatbot volumes
βββ docker-compose.yml # Main orchestration
βββ .env.example # Environment template
- User β Nginx (HTTPS) β path-based routing.
/β Next.js (3000): pages and static assets./user/,/auth/,/api/posts,/api/search,/chatβ API Gateway (8085).- Gateway β JWT validation (where applicable), Trace ID β proxy to service:
/user/**β user-service:8081/auth/**β auth-service:8084/api/posts/**β post-service:8082/api/search/**β search-service:8010/chat/**β fastapi-ai:8000
- Services β DB / Redis / Kafka β response β Gateway β Nginx β client.
Nginx configuration lives under nginx/. Production uses sites-available/msa-project (enabled via sites-enabled/msa-project).
| location | Proxy target | Notes |
|---|---|---|
location / |
http://127.0.0.1:3000 |
Next.js |
location /user/ |
http://msa-gateway (127.0.0.1:8085) |
Gateway β user-service |
location /auth/ |
http://msa-gateway |
Gateway β auth-service |
location /api/posts |
http://msa-gateway |
Gateway β post-service |
location /api/search |
http://msa-gateway |
Gateway β search-service |
location /chat |
http://msa-gateway |
AI chatbot (timeout 600s) |
location /actuator |
http://msa-gateway |
Health checks, back office |
location /grafana/ |
http://127.0.0.1:3001 |
Grafana (monitoring profile) |
- Upstream:
upstream msa-gateway { server 127.0.0.1:8085 max_fails=2 fail_timeout=30s; keepalive 8; } - Dev domain
dev.minkowskim.com:/β 4000, API/auth/user/chat β 9085 (Gateway).
See docs/nginx-aws-lightsail.md for details.
Gateway path to backend mapping (production: application-prod.yml):
| Path | Service | Description |
|---|---|---|
/user, /user/** |
user-service:8081 | User profile and info |
/auth, /auth/** |
auth-service:8084 | Login, signup, OAuth2, JWT, verification email |
/api/posts, /api/posts/** |
post-service:8082 | Post and comment CRUD |
/chat, /chat/** |
fastapi-ai:8000 | AI chatbot (SSE/streaming) |
/api/search, /api/search/** |
search-service:8010 | Vector and keyword search |
Protected APIs use Authorization: Bearer <JWT> or cookie authToken. For endpoint details, see each service and Gateway config.
- Docker and Docker Compose
- (Optional) Nginx with config from
nginx/
# 1. Environment
cp .env.example .env
# Edit .env: DB passwords, JWT_SECRET, OAuth2, GROQ_API_KEY, etc.
# 2. Start full stack (4GB memory oriented)
docker compose up -d
# 3. (Optional) Monitoring
docker compose --profile monitoring up -d- Frontend: http://localhost:3000
- API Gateway: http://localhost:8085 (or via Nginx)
- Grafana (monitoring profile): http://localhost:3001
| Service | Port | Stack | Notes |
|---|---|---|---|
| api-gateway | 8085 | Spring Boot 3, Spring Cloud Gateway | JWT, Trace ID, routing |
| auth-service | 8084 | Spring Boot, JPA, OAuth2, Redis, Kafka | Admin bootstrap |
| user-service | 8081 | Spring Boot, JPA, Kafka | |
| post-service | 8082 | Spring Boot, JPA, WebClient, Kafka | |
| mail-service | 8083 | Spring Boot, Kafka, Mail | Kafka β SMTP |
| fastapi-ai | 8000 | FastAPI, LangChain, Groq, Redis | Chatbot |
| search-service | 8010 | FastAPI, pgvector, Kafka | Vector indexing |
| frontend | 3000 | Next.js 14 | |
| redis | 6379 | Redis Alpine | |
| msa-kafka | 9092 | Apache Kafka 3.7 (KRaft) | |
| db-auth / db-user / db-post / db-search | 5434/5432/5433/5435 | PostgreSQL 15, pgvector |
- Back office: Next.js
/backoffice; Gateway/actuatorfor health. - Monitoring:
docker compose --profile monitoring up -druns Fluent Bit β Loki β Grafana. Grafana is exposed via Nginx at/grafana/(proxy to 3001). - Kafka UI (optional):
docker compose --profile tools up -dexposes Kafka UI on 8080.
Copy .env.example to .env and set:
| Category | Variables |
|---|---|
| DB | POSTGRES_USER, POSTGRES_PASSWORD, DB_AUTH_NAME, DB_USER_NAME, DB_POST_NAME, DB_SEARCH_NAME |
| JWT & Admin | JWT_SECRET, ADMIN_USERNAME, ADMIN_PASSWORD |
| OAuth2 | OAUTH2_GOOGLE_*, OAUTH2_KAKAO_*, COOKIE_DOMAIN, FRONTEND_URL |
| Redis & Kafka | SPRING_REDIS_HOST, REDIS_*, SPRING_KAFKA_BOOTSTRAP_SERVERS |
| SMTP | MAIL_USERNAME, MAIL_PASSWORD |
| AI | GROQ_API_KEY |
| Frontend build | NEXT_PUBLIC_API_URL, NEXT_PUBLIC_*_API_URL |
| Monitoring | GRAFANA_ADMIN_PASSWORD |
| Document | Description |
|---|---|
docs/PROJECT_UPDATES.md |
Project update and change history |
docs/nginx-aws-lightsail.md |
Nginx layout, routing, SSL, Lightsail |
nginx/sites-available/msa-project |
Production Nginx config |
monitoring/docker-compose.monitoring.yml |
Loki Stack monitoring Compose |