-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
253 lines (236 loc) · 10.1 KB
/
docker-compose.yml
File metadata and controls
253 lines (236 loc) · 10.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
# =============================================================================
# docker-compose.yml — KeyCompute 线上部署编排
#
# 服务拓扑:
# postgres — PostgreSQL 数据库(keycompute-db 依赖)
# redis — Redis 缓存(限流、会话存储)
# keycompute-server — Axum 后端 API 服务
# keycompute-web — Nginx + Dioxus WASM 前端
# ollama — Ollama 本地模型服务
# ollama-model-init — 启动后自动拉取并预热指定模型
#
# 网络拓扑:
# keycompute-internal — 内部网络(后端 ↔ 数据库/Redis,外部不可访问)
# keycompute-public — 公共网络(仅 Web 与 Server 对外暴露端口)
#
# 使用方法:
# cp .env.example .env # 编辑填入生产密钥
# docker compose up -d # 启动所有服务
# docker compose logs -f # 实时查看日志
# =============================================================================
services:
# ─────────────────────────────────────────────────────────────────────────
# PostgreSQL — 主数据库
# ─────────────────────────────────────────────────────────────────────────
postgres:
image: postgres:16-alpine
container_name: keycompute-postgres
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB:-keycompute}
POSTGRES_USER: ${POSTGRES_USER:-keycompute}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
# 性能调优(根据服务器内存酌情调整)
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- keycompute-internal
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-keycompute} -d ${POSTGRES_DB:-keycompute}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
deploy:
resources:
limits:
memory: 512m
cpus: "1.0"
# ─────────────────────────────────────────────────────────────────────────
# Redis — 缓存与限流存储
# ─────────────────────────────────────────────────────────────────────────
redis:
image: redis:7-alpine
container_name: keycompute-redis
restart: unless-stopped
command: >
redis-server
--requirepass ${REDIS_PASSWORD}
--maxmemory 256mb
--maxmemory-policy allkeys-lru
--save 60 1000
--appendonly yes
volumes:
- redis_data:/data
networks:
- keycompute-internal
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
deploy:
resources:
limits:
memory: 256m
cpus: "0.5"
# ─────────────────────────────────────────────────────────────────────────
# keycompute-server — Axum 后端 API 服务
# ─────────────────────────────────────────────────────────────────────────
keycompute-server:
build:
context: .
dockerfile: Dockerfile.server
pull_policy: build
image: keycompute-server:latest
container_name: keycompute-server
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
environment:
# 运行环境
KC__ENV: production
# 数据库配置(使用 Docker 网络内服务名解析)
KC__DATABASE__URL: "postgres://${POSTGRES_USER:-keycompute}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB:-keycompute}"
KC__DATABASE__MAX_CONNECTIONS: ${DB_MAX_CONNECTIONS:-10}
KC__DATABASE__MIN_CONNECTIONS: ${DB_MIN_CONNECTIONS:-2}
# Redis 配置
KC__REDIS__URL: "redis://:${REDIS_PASSWORD}@redis:6379"
KC__REDIS__POOL_SIZE: ${REDIS_POOL_SIZE:-10}
# 认证配置(生产环境必须修改!)
KC__AUTH__JWT_SECRET: ${KC__AUTH__JWT_SECRET}
KC__AUTH__JWT_ISSUER: ${KC__AUTH__JWT_ISSUER:-keycompute}
KC__AUTH__JWT_EXPIRY_SECS: ${KC__AUTH__JWT_EXPIRY_SECS:-3600}
# 加密配置(API Key 加密存储,生产环境必须配置!)
KC__CRYPTO__SECRET_KEY: ${KC__CRYPTO__SECRET_KEY}
# 邮件服务配置
KC__EMAIL__SMTP_HOST: ${KC__EMAIL__SMTP_HOST}
KC__EMAIL__SMTP_PORT: ${KC__EMAIL__SMTP_PORT:-465}
KC__EMAIL__SMTP_USERNAME: ${KC__EMAIL__SMTP_USERNAME}
KC__EMAIL__SMTP_PASSWORD: ${KC__EMAIL__SMTP_PASSWORD}
KC__EMAIL__FROM_ADDRESS: ${KC__EMAIL__FROM_ADDRESS}
KC__EMAIL__FROM_NAME: ${KC__EMAIL__FROM_NAME:-KeyCompute}
APP_BASE_URL: ${APP_BASE_URL:-http://127.0.0.1}
# 服务器配置
KC__SERVER__BIND_ADDR: "0.0.0.0"
KC__SERVER__PORT: "3000"
# 默认系统管理员配置(首次启动时自动创建)
KC__DEFAULT_ADMIN_EMAIL: ${KC__DEFAULT_ADMIN_EMAIL:-admin@keycompute.local}
KC__DEFAULT_ADMIN_PASSWORD: ${KC__DEFAULT_ADMIN_PASSWORD:-12345}
networks:
- keycompute-internal
- keycompute-public
# 后端端口不对外直接暴露,通过 Nginx 代理访问
# 如需直接调试 API,可取消下行注释:
# ports:
# - "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
deploy:
resources:
limits:
memory: 1g
cpus: "2.0"
# ─────────────────────────────────────────────────────────────────────────
# keycompute-web — Nginx + Dioxus WASM 前端
# ─────────────────────────────────────────────────────────────────────────
keycompute-web:
build:
context: .
dockerfile: Dockerfile.web
pull_policy: build
image: keycompute-web:latest
container_name: keycompute-web
restart: unless-stopped
depends_on:
keycompute-server:
condition: service_healthy
ports:
- "${WEB_PORT:-80}:80"
networks:
- keycompute-public
- keycompute-internal # Nginx 需要访问 keycompute-server,必须加入内部网络
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost/"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
deploy:
resources:
limits:
memory: 128m
cpus: "0.5"
# ─────────────────────────────────────────────────────────────────────────
# Ollama — 本地模型服务
# ─────────────────────────────────────────────────────────────────────────
ollama:
image: ollama/ollama:latest
container_name: keycompute-ollama
restart: unless-stopped
environment:
OLLAMA_HOST: "0.0.0.0:11434"
# 控制模型在内存中的保活时间;如需常驻可在 .env 中设为 -1
OLLAMA_KEEP_ALIVE: ${OLLAMA_KEEP_ALIVE:-30m}
ports:
- "${OLLAMA_PORT:-11434}:11434"
volumes:
- ollama_data:/root/.ollama
networks:
- keycompute-public
healthcheck:
test: ["CMD", "ollama", "list"]
interval: 15s
timeout: 10s
retries: 20
start_period: 30s
# ─────────────────────────────────────────────────────────────────────────
# ollama-model-init — 自动拉取并预热指定模型
# ─────────────────────────────────────────────────────────────────────────
ollama-model-init:
image: ollama/ollama:latest
container_name: keycompute-ollama-model-init
restart: on-failure
depends_on:
ollama:
condition: service_healthy
environment:
OLLAMA_HOST: "http://ollama:11434"
OLLAMA_MODEL: ${OLLAMA_MODEL:-gemma3:270m}
OLLAMA_WARMUP_PROMPT: ${OLLAMA_WARMUP_PROMPT:-ready}
entrypoint:
- /bin/sh
- -c
- ollama pull "$$OLLAMA_MODEL" && ollama run "$$OLLAMA_MODEL" "$$OLLAMA_WARMUP_PROMPT" >/dev/null
networks:
- keycompute-public
# =============================================================================
# 持久化卷
# =============================================================================
volumes:
postgres_data:
driver: local
redis_data:
driver: local
ollama_data:
driver: local
# =============================================================================
# 网络定义
# =============================================================================
networks:
# 内部网络:Postgres/Redis/Server 之间通信,外部不可访问
keycompute-internal:
driver: bridge
internal: true
# 公共网络:Web/Server/Ollama 对外暴露,Nginx 通过此网络代理后端
keycompute-public:
driver: bridge