-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.prod.yml
More file actions
235 lines (216 loc) · 6.86 KB
/
Copy pathdocker-compose.prod.yml
File metadata and controls
235 lines (216 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
name: catchtable-clone
services:
app:
image: ghcr.io/catchtable-clone/backend:${IMAGE_TAG}
container_name: catchtable-app
env_file: .env
expose:
- "8080"
# t3.small 메모리 한도 고려한 app 한도 (OTel Agent 80MB 포함 600M)
environment:
# 분산 트레이싱(Jaeger + OTel Collector) 제거 — OTel javaagent SDK 전체 비활성화.
# 메트릭은 Micrometer/Prometheus, 로그는 Promtail/Loki가 담당하므로 트레이싱만 끔.
# 트레이싱 복원 시: 이 줄 제거 후 export/sampler 설정 복구 + otel-collector/jaeger 서비스 재추가.
OTEL_SDK_DISABLED: "true"
deploy:
resources:
limits:
memory: 1000M
reservations:
memory: 400M
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 120s
restart: unless-stopped
networks:
- catchtable-net
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
nginx:
image: nginx:1.26.3-alpine
container_name: catchtable-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
depends_on:
app:
condition: service_healthy
deploy:
resources:
limits:
memory: 50M
restart: unless-stopped
networks:
- catchtable-net
certbot:
image: certbot/certbot:v3.2.0
container_name: catchtable-certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --quiet; sleep 12h & wait $${!}; done;'"
deploy:
resources:
limits:
memory: 30M
restart: unless-stopped
prometheus:
image: prom/prometheus:v2.55.0
container_name: catchtable-prometheus
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=7d'
- '--storage.tsdb.retention.size=1GB'
- '--web.enable-lifecycle'
- '--web.enable-remote-write-receiver'
ports:
- "9090:9090"
deploy:
resources:
limits:
memory: 800M
restart: unless-stopped
networks:
- catchtable-net
loki:
image: grafana/loki:3.2.0
container_name: catchtable-loki
volumes:
- ./monitoring/loki-config.yml:/etc/loki/local-config.yaml:ro
- loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
expose:
- "3100"
deploy:
resources:
limits:
memory: 300M
restart: unless-stopped
networks:
- catchtable-net
promtail:
image: grafana/promtail:3.2.0
container_name: catchtable-promtail
volumes:
- ./monitoring/promtail-config.yml:/etc/promtail/config.yml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- promtail-positions:/tmp
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki
deploy:
resources:
limits:
memory: 200M
restart: unless-stopped
networks:
- catchtable-net
grafana:
image: grafana/grafana:11.3.0
container_name: catchtable-grafana
environment:
GF_SECURITY_ADMIN_USER: ${GRAFANA_USER:-admin}
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}
GF_USERS_ALLOW_SIGN_UP: "false"
volumes:
- ./grafana/provisioning:/etc/grafana/provisioning:ro
- grafana-data:/var/lib/grafana
ports:
- "3001:3000" # Grafana UI (외부 접근, 3000은 프론트 dev와 충돌 회피)
depends_on:
- prometheus
- loki
deploy:
resources:
limits:
memory: 300M
restart: unless-stopped
networks:
- catchtable-net
# ============================================================
# 고도화 인프라 (Kafka는 해당 작업 시작 시 주석 해제)
# ============================================================
redis:
image: redis:7-alpine
container_name: catchtable-redis
command:
- redis-server
- --maxmemory
- 80mb
- --maxmemory-policy
- allkeys-lru
- --appendonly
- "yes"
expose:
- "6379"
volumes:
- redis-data:/data
deploy:
resources:
limits:
memory: 200M
restart: unless-stopped
networks:
- catchtable-net
kafka:
image: apache/kafka:3.7.0
container_name: catchtable-kafka-prod
user: "0" # 볼륨 마운트 폴더에 로그를 쓰고 지울 수 있도록 최고 관리자 권한 부여
# 외부(내 PC 등)로 포트를 무방비하게 노출하지 않고, 오직 'catchtable-net' 내부에서만 통신하도록 격리
expose:
- "9092"
- "9093"
environment:
# KRaft 모드 핵심 식별자 설정
KAFKA_CLUSTER_ID: "MkU3OEV5NURaZW52OTYyM2RjY1JqcA" # 운영 환경 고유 클러스터 ID
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: 'broker,controller'
KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
# 모든 인터페이스(0.0.0.0)로 귀를 열어두고, 운영 서버 안의 다른 컨테이너(Spring Boot)에는 서비스 명인 'kafka:9092'로 광고합니다.
KAFKA_LISTENERS: 'PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093'
KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://kafka:9092'
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT'
KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
KAFKA_CONTROLLER_QUORUM_VOTERS: '1@127.0.0.1:9093' # 루프백 주소로 바인딩 충돌 방지
# 메모리 제한 설정 (서버 스펙에 맞게 조정 가능, 최소 256m~512m 추천)
KAFKA_HEAP_OPTS: "-Xms256m -Xmx256m"
# 단일 broker 운영용 internal topic 설정.
# default(3)면 __consumer_offsets/__transaction_state 가 영원히 생성 실패 → consumer group join 불가.
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
# 임시 폴더인 /tmp 대신 컨테이너가 내려가도 데이터와 오프셋 장부가 보존되도록 볼륨 볼륨 마운트 경로 고정
volumes:
- kafka-prod-data:/var/lib/kafka/data
# 리소스 상한선 설정 (메모리 릭으로 인한 전체 서버 다운 방지)
deploy:
resources:
limits:
memory: 600M
restart: unless-stopped
networks:
- catchtable-net
networks:
catchtable-net:
driver: bridge
volumes:
prometheus-data:
loki-data:
grafana-data:
promtail-positions:
kafka-prod-data:
redis-data: