-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdocker-compose.demo.yml
More file actions
337 lines (319 loc) · 11.1 KB
/
docker-compose.demo.yml
File metadata and controls
337 lines (319 loc) · 11.1 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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# ==========================================
# DeepMed Search - Demo 版本配置
# ==========================================
#
# 此配置文件用于不需要 GPU 的演示环境
#
# 与完整版的主要区别:
# - ❌ 不包含 MinerU 服务(需要 GPU)
# - ✅ 仅使用 Markitdown 作为文档解析器
# - ✅ 更轻量,适合演示和开发
#
# 使用方法:
# docker compose -f docker-compose.demo.yml up -d
#
# 参考文档:
# docs/deployment/DOCKER_COMPOSE_VARIANTS.md
#
# ==========================================
services:
# Traefik 反向代理和负载均衡器
traefik:
image: traefik:v2.10
container_name: deepmed-traefik
restart: always
ports:
- "80:80"
- "443:443"
- "8080:8080" # Traefik 仪表板(可选)
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik/dynamic:/etc/traefik/dynamic:ro
- traefik-certificates:/letsencrypt
- traefik-logs:/var/log/traefik
labels:
- "traefik.enable=true"
# Traefik 仪表板(仅匹配仪表板路径,不拦截应用 API)
- "traefik.http.routers.traefik.rule=Host(`www.deepmedsearch.cloud`) && PathPrefix(`/dashboard`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.service=api@internal"
# 仪表板认证(建议配置)
# - "traefik.http.routers.traefik.middlewares=auth"
# - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$..." # 使用 htpasswd 生成
networks:
- traefik-public
- default
# PostgreSQL 数据库服务(仅用于结构化数据)
postgres:
image: postgres:16-alpine
container_name: deepmed-postgres
restart: always
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres", "-q"]
interval: 10s
timeout: 5s
retries: 5
# MinIO 对象存储服务(文件存储 + Milvus 向量存储)
minio:
image: minio/minio:latest
container_name: deepmed-minio
restart: always
environment:
MINIO_ROOT_USER: ${MINIO_ACCESS_KEY:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minioadmin}
MINIO_BROWSER_REDIRECT_URL: ${MINIO_BROWSER_REDIRECT_URL}
volumes:
- minio-data:/data
ports:
- "${MINIO_PORT:-9000}:9000" # API 端口
- "9001:9001" # 控制台端口
command: minio server /data --console-address ":9001"
healthcheck:
test: [ "CMD", "mc", "ready", "local" ]
interval: 30s
timeout: 10s
retries: 3
# Milvus 向量数据库 - standalone 模式(使用内嵌 etcd)
milvus:
container_name: deepmed-milvus
image: docker.m.daocloud.io/milvusdb/milvus:v2.3.10
command: ["milvus", "run", "standalone"]
security_opt:
- seccomp:unconfined
environment:
ETCD_USE_EMBED: "true"
ETCD_DATA_DIR: "/var/lib/milvus/etcd"
MINIO_ADDRESS: minio:9000
MINIO_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY:-minioadmin}
MINIO_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY:-minioadmin}
MINIO_USE_SSL: "false"
MINIO_BUCKET_NAME: "milvus-bucket"
COMMON_STORAGETYPE: "minio"
volumes:
- milvus-data:/var/lib/milvus
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
interval: 30s
start_period: 90s
timeout: 20s
retries: 3
ports:
- "19530:19530"
- "9091:9091"
depends_on:
- minio
restart: always
# Redis 服务 - 用于队列或者缓存系统
redis:
image: redis:alpine
container_name: deepmed-redis
restart: always
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- redis-data:/data
command: redis-server --appendonly yes
healthcheck:
test: [ "CMD", "redis-cli", "ping" ]
interval: 10s
timeout: 5s
retries: 5
queue-worker:
# 使用腾讯云预构建镜像(无需本地编译)
# image: jpccr.ccs.tencentyun.com/deepmedsearch/deepmed-search-worker:latest
build:
context: .
dockerfile: Dockerfile.worker
container_name: deepmed-queue-worker
depends_on:
- redis
- postgres
- markitdown
- milvus
environment:
NODE_ENV: production
NODE_OPTIONS: --max-old-space-size=512
BULLMQ_CONCURRENCY: ${BULLMQ_CONCURRENCY:-8}
# 队列和数据库连接(必需)
# 注意:在 Docker 容器内使用服务名 postgres 而不是 localhost
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
# 数据库连接:在容器内必须使用 postgres 服务名而不是 localhost
# 从环境变量提取数据库凭证,但使用 postgres 作为主机名
DATABASE_URL: ${DATABASE_URL}
# 加密密钥(必需:用于解密用户配置的 API keys)
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
# Milvus 向量数据库连接
MILVUS_ADDRESS: ${MILVUS_ADDRESS:-milvus:19530}
# 文档解析器服务端点配置(容器内使用服务名)
# 注意:实际使用的解析器由用户在 /settings/document 页面配置
# Demo 分支:仅支持 Markitdown(不需要 GPU)
MARKITDOWN_URL: http://markitdown:5000
# 注意:所有 LLM 和搜索 API Keys 从用户配置中读取(数据库)
# 用户需在 /settings/llm 和 /settings/search 页面配置
restart: always
# Next.js 主应用服务
app:
# 使用腾讯云预构建镜像(无需本地编译)
# image: jpccr.ccs.tencentyun.com/deepmedsearch/deepmed-search-app:latest
build:
context: .
dockerfile: Dockerfile
container_name: deepmed-app
# 端口配置说明:
# - 生产环境:推荐只通过 Traefik (HTTPS) 访问,注释掉下面的 ports
# - 开发/调试:如需直接访问 3000 端口,可取消注释下面的 ports
# ports:
# - "${APP_PORT:-3000}:3000"
expose:
- "3000" # 仅在 Docker 网络内暴露,供 Traefik 使用
labels:
- "traefik.enable=true"
# HTTP 路由
- "traefik.http.routers.app.rule=Host(`www.deepmedsearch.cloud`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.services.app.loadbalancer.server.port=3000"
# 安全头
- "traefik.http.middlewares.security-headers.headers.frameDeny=true"
- "traefik.http.middlewares.security-headers.headers.contentTypeNosniff=true"
- "traefik.http.middlewares.security-headers.headers.browserXssFilter=true"
- "traefik.http.middlewares.security-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.security-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.security-headers.headers.stsPreload=true"
- "traefik.http.routers.app.middlewares=security-headers"
volumes:
- ./logs:/app/logs # 挂载日志目录,解决权限问题
networks:
- traefik-public
- default
environment:
NODE_ENV: production
NODE_OPTIONS: --max-old-space-size=2048
NEXT_TELEMETRY_DISABLED: 1
# 数据库连接
DATABASE_URL: ${DATABASE_URL}
# NextAuth 配置
# 注意:使用 Traefik + SSL 时,请在 .env 中设置:
# NEXTAUTH_URL=https://www.deepmedsearch.cloud
NEXTAUTH_URL: ${NEXTAUTH_URL:-http://localhost:3000}
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
# 加密密钥(用于解密用户配置的 API keys)
ENCRYPTION_KEY: ${ENCRYPTION_KEY}
# 注意:所有 LLM 和搜索 API Keys 从用户配置中读取(数据库)
# 以下是解析器服务的端点配置,非解析器选择
# Demo 分支:仅支持 Markitdown(不需要 GPU)
MARKITDOWN_URL: ${MARKITDOWN_URL:-http://markitdown:5000}
# MinIO 配置
MINIO_ENDPOINT: ${MINIO_ENDPOINT:-minio:9000}
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
MINIO_USE_SSL: ${MINIO_USE_SSL:-false}
# Redis 配置
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
# Milvus 配置
MILVUS_ADDRESS: ${MILVUS_ADDRESS:-milvus:19530}
# OAuth 配置(添加这些行)
GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}
GOOGLE_CLIENT_SECRET: ${GOOGLE_CLIENT_SECRET:-}
GITHUB_CLIENT_ID: ${GITHUB_CLIENT_ID:-}
GITHUB_CLIENT_SECRET: ${GITHUB_CLIENT_SECRET:-}
depends_on:
- postgres
- redis
- milvus
- minio
- markitdown
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/ || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
markitdown:
# 使用腾讯云预构建镜像(无需本地编译)
# image: jpccr.ccs.tencentyun.com/deepmedsearch/deepmed-markitdown:latest
build:
context: ./docker/markitdown
dockerfile: Dockerfile
container_name: deepmed-markitdown
restart: always
ports:
- "${MARKITDOWN_PORT:-5001}:5000"
environment:
PORT: 5000
APP_ENV: production
UVICORN_WORKERS: 1
UVICORN_LOG_LEVEL: info
# MinIO 配置(用于图片上传)
MINIO_ENDPOINT: ${MINIO_ENDPOINT:-minio:9000}
MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
MINIO_SECURE: ${MINIO_USE_SSL:-false}
MINIO_BUCKET_NAME: ${MINIO_BUCKET_NAME:-deepmed}
MINIO_PUBLIC_URL: ${MINIO_PUBLIC_URL:-http://localhost:9000}
depends_on:
- minio
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
attu:
image: zilliz/attu:latest
container_name: attu
ports:
- "8001:3000"
environment:
MILVUS_URL: milvus:19530
# Attu 默认连接配置
HOST_URL: http://milvus:19530
depends_on:
milvus:
condition: service_healthy
restart: unless-stopped
# BullMQ Board - BullMQ 队列监控界面
bull-board:
build:
context: ./docker/bull-board
dockerfile: Dockerfile
container_name: deepmed-bull-board
ports:
- "${BULL_BOARD_PORT:-8003}:3000"
environment:
REDIS_URL: ${REDIS_URL:-redis://redis:6379}
REDIS_HOST: ${REDIS_HOST:-redis}
REDIS_PORT: ${REDIS_PORT:-6379}
REDIS_PASSWORD: ${REDIS_PASSWORD:-}
PORT: 3000
depends_on:
- redis
restart: unless-stopped
# ==========================================
# Demo 分支说明:
# 此分支移除了 MinerU 服务(需要 GPU)
# 仅使用 Markitdown 作为文档解析器
# ==========================================
volumes:
postgres-data:
minio-data:
redis-data:
milvus-data:
redisinsight-data:
traefik-certificates:
traefik-logs:
networks:
traefik-public:
name: traefik-public
driver: bridge