docker-compose.yml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. services:
  2. # ──────────────────────────────────────────
  3. # 1. MySQL 主数据库
  4. # ──────────────────────────────────────────
  5. mysql:
  6. image: mysql:8.0
  7. container_name: ws-mysql
  8. restart: unless-stopped
  9. environment:
  10. TZ: ${TZ:-Asia/Shanghai}
  11. MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root_pass_change_me}
  12. MYSQL_DATABASE: ${MYSQL_DATABASE:-wenshu_platform}
  13. MYSQL_USER: ${MYSQL_USER:-wenshu}
  14. MYSQL_PASSWORD: ${MYSQL_PASSWORD:-wenshu_db_pass}
  15. volumes:
  16. - ./data/mysql:/var/lib/mysql
  17. - ./backend/src/main/resources/db/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql:ro
  18. ports:
  19. - "3306:3306"
  20. healthcheck:
  21. test: ["CMD-SHELL", "mysqladmin ping -h localhost -u$${MYSQL_USER} -p$${MYSQL_PASSWORD} --silent"]
  22. interval: 10s
  23. timeout: 5s
  24. retries: 10
  25. # ──────────────────────────────────────────
  26. # 2. Milvus 向量数据库(依赖 etcd + minio)
  27. # ──────────────────────────────────────────
  28. milvus-etcd:
  29. image: quay.io/coreos/etcd:v3.5.18
  30. container_name: ws-milvus-etcd
  31. restart: unless-stopped
  32. environment:
  33. ETCD_AUTO_COMPACTION_MODE: revision
  34. ETCD_AUTO_COMPACTION_RETENTION: "1000"
  35. ETCD_QUOTA_BACKEND_BYTES: "4294967296"
  36. ETCD_SNAPSHOT_COUNT: "50000"
  37. volumes:
  38. - ./data/milvus/etcd:/etcd
  39. command: >
  40. etcd
  41. -advertise-client-urls=http://127.0.0.1:2379
  42. -listen-client-urls=http://0.0.0.0:2379
  43. --data-dir=/etcd
  44. healthcheck:
  45. test: ["CMD", "etcdctl", "endpoint", "health"]
  46. interval: 30s
  47. timeout: 20s
  48. retries: 3
  49. milvus-minio:
  50. image: minio/minio:RELEASE.2023-03-20T20-16-18Z
  51. container_name: ws-milvus-minio
  52. restart: unless-stopped
  53. environment:
  54. MINIO_ACCESS_KEY: ${MINIO_ACCESS_KEY:-minioadmin}
  55. MINIO_SECRET_KEY: ${MINIO_SECRET_KEY:-minioadmin}
  56. volumes:
  57. - ./data/milvus/minio:/minio_data
  58. command: minio server /minio_data --console-address ":9001"
  59. healthcheck:
  60. test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
  61. interval: 30s
  62. timeout: 20s
  63. retries: 3
  64. milvus-standalone:
  65. image: milvusdb/milvus:v2.4.15
  66. container_name: ws-milvus-standalone
  67. restart: unless-stopped
  68. depends_on:
  69. milvus-etcd:
  70. condition: service_healthy
  71. milvus-minio:
  72. condition: service_healthy
  73. environment:
  74. ETCD_ENDPOINTS: milvus-etcd:2379
  75. MINIO_ADDRESS: milvus-minio:9000
  76. volumes:
  77. - ./data/milvus/milvus:/var/lib/milvus
  78. ports:
  79. - "19530:19530"
  80. - "9091:9091"
  81. command: ["milvus", "run", "standalone"]
  82. healthcheck:
  83. test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
  84. interval: 30s
  85. timeout: 20s
  86. retries: 5
  87. # ──────────────────────────────────────────
  88. # 3. Apache Polaris(Iceberg REST Catalog)
  89. # 依赖专属 Postgres
  90. # ──────────────────────────────────────────
  91. polaris-postgres:
  92. image: postgres:16
  93. container_name: ws-polaris-postgres
  94. restart: unless-stopped
  95. environment:
  96. TZ: ${TZ:-Asia/Shanghai}
  97. POSTGRES_DB: ${POLARIS_POSTGRES_DB:-polaris}
  98. POSTGRES_USER: ${POLARIS_POSTGRES_USER:-polaris}
  99. POSTGRES_PASSWORD: ${POLARIS_POSTGRES_PASSWORD:-polaris_pg_pass}
  100. volumes:
  101. - ./data/polaris/postgres:/var/lib/postgresql/data
  102. healthcheck:
  103. test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
  104. interval: 10s
  105. timeout: 5s
  106. retries: 10
  107. polaris:
  108. image: apache/polaris:1.3.0-incubating
  109. container_name: ws-polaris
  110. restart: unless-stopped
  111. depends_on:
  112. polaris-postgres:
  113. condition: service_healthy
  114. ports:
  115. - "8181:8181"
  116. environment:
  117. POLARIS_PERSISTENCE_TYPE: relational-jdbc
  118. DROP_WITH_PURGE_ENABLED: ${POLARIS_DROP_WITH_PURGE_ENABLED:-true}
  119. QUARKUS_DATASOURCE_USERNAME: ${POLARIS_POSTGRES_USER:-polaris}
  120. QUARKUS_DATASOURCE_PASSWORD: ${POLARIS_POSTGRES_PASSWORD:-polaris_pg_pass}
  121. QUARKUS_DATASOURCE_JDBC_URL: jdbc:postgresql://polaris-postgres:5432/${POLARIS_POSTGRES_DB:-polaris}
  122. QUARKUS_HTTP_PORT: 8181
  123. AWS_ACCESS_KEY_ID: ${OSS_AK:-}
  124. AWS_SECRET_ACCESS_KEY: ${OSS_SK:-}
  125. AWS_REGION: ${OSS_REGION:-cn-hangzhou}
  126. AWS_DEFAULT_REGION: ${OSS_REGION:-cn-hangzhou}
  127. AWS_REQUEST_CHECKSUM_CALCULATION: WHEN_REQUIRED
  128. AWS_RESPONSE_CHECKSUM_VALIDATION: WHEN_REQUIRED
  129. healthcheck:
  130. test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8181' 2>/dev/null && exit 0 || exit 1"]
  131. interval: 15s
  132. timeout: 5s
  133. retries: 20
  134. start_period: 60s
  135. # ──────────────────────────────────────────
  136. # 4. TEI 向量化服务(CPU 模式)
  137. # ──────────────────────────────────────────
  138. tei:
  139. image: ghcr.io/huggingface/text-embeddings-inference:cpu-latest
  140. container_name: ws-tei
  141. restart: unless-stopped
  142. volumes:
  143. - ./data/huggingface:/data
  144. ports:
  145. - "7997:80"
  146. command: ["--model-id", "${TEI_MODEL_ID:-intfloat/multilingual-e5-base}"]
  147. healthcheck:
  148. test: ["CMD", "curl", "-sf", "http://localhost:80/health"]
  149. interval: 30s
  150. timeout: 10s
  151. retries: 10
  152. start_period: 120s # 首次下载模型需要时间
  153. # ──────────────────────────────────────────
  154. # 5. Spring Boot 后端
  155. # ──────────────────────────────────────────
  156. backend:
  157. build:
  158. context: ./backend
  159. dockerfile: Dockerfile
  160. container_name: ws-backend
  161. restart: unless-stopped
  162. environment:
  163. TZ: ${TZ:-Asia/Shanghai}
  164. MYSQL_URL: ${MYSQL_URL:-mysql:3306}
  165. MYSQL_DATABASE: ${MYSQL_DATABASE:-wenshu_platform}
  166. MYSQL_USER: ${MYSQL_USER:-wenshu}
  167. MYSQL_PASSWORD: ${MYSQL_PASSWORD:-wenshu_db_pass}
  168. STOCK_SSH_CRYPTO_KEY: ${STOCK_SSH_CRYPTO_KEY:-change-me-stock-ssh-key-32chars}
  169. SERVER_IP: ${SERVER_IP:-}
  170. POLARIS_HOST: ${POLARIS_HOST:-}
  171. POLARIS_REALM: ${POLARIS_REALM:-POLARIS}
  172. POLARIS_CLIENT_ID: ${POLARIS_CLIENT_ID:-root}
  173. POLARIS_CLIENT_SECRET: ${POLARIS_CLIENT_SECRET:-s3cr3t}
  174. POLARIS_DEFAULT_CATALOG: ${POLARIS_DEFAULT_CATALOG:-demo_catalog}
  175. POLARIS_CACHE_TTL_MINUTES: ${POLARIS_CACHE_TTL_MINUTES:-10}
  176. KUBEADM_JOIN_COMMAND: ${KUBEADM_JOIN_COMMAND:-}
  177. OSS_ENDPOINT: ${OSS_ENDPOINT:-https://oss-cn-hangzhou.aliyuncs.com}
  178. OSS_AK: ${OSS_AK:-}
  179. OSS_SK: ${OSS_SK:-}
  180. OSS_REGION: ${OSS_REGION:-cn-hangzhou}
  181. OSS_BUCKET: ${OSS_BUCKET:-}
  182. ICEBERG_SERVICE_URL: ${ICEBERG_SERVICE_URL:-http://python-iceberg:8090}
  183. K8S_ORCHESTRATOR_BASE_URL: ${K8S_ORCHESTRATOR_BASE_URL:-http://ws-orchestrator-api:8080}
  184. K8S_ORCHESTRATOR_TIMEOUT_MS: ${K8S_ORCHESTRATOR_TIMEOUT_MS:-5000}
  185. K8S_ORCHESTRATOR_WAIT_TIMEOUT_MS: ${K8S_ORCHESTRATOR_WAIT_TIMEOUT_MS:-300000}
  186. K8S_ORCHESTRATOR_POLL_INTERVAL_MS: ${K8S_ORCHESTRATOR_POLL_INTERVAL_MS:-2000}
  187. K8S_ORCHESTRATOR_RECONCILE_CREATE_DELAY_MS: ${K8S_ORCHESTRATOR_RECONCILE_CREATE_DELAY_MS:-5000}
  188. K8S_ORCHESTRATOR_RECONCILE_BATCH_SIZE: ${K8S_ORCHESTRATOR_RECONCILE_BATCH_SIZE:-100}
  189. BACKEND_INTERNAL_HEADER: ${BACKEND_INTERNAL_HEADER:-X-Internal-Token}
  190. BACKEND_INTERNAL_TOKEN: ${BACKEND_INTERNAL_TOKEN:-change-me-internal-token}
  191. STARROCKS_SQL_RUNNER_USERNAME: ${STARROCKS_SQL_RUNNER_USERNAME:-root}
  192. STARROCKS_SQL_RUNNER_PASSWORD: ${STARROCKS_SQL_RUNNER_PASSWORD:-}
  193. STARROCKS_SQL_RUNNER_POLARIS_CATALOG: ${STARROCKS_SQL_RUNNER_POLARIS_CATALOG:-polaris}
  194. STARROCKS_SQL_RUNNER_QUERY_PORT: ${STARROCKS_SQL_RUNNER_QUERY_PORT:-9030}
  195. RAG_EMBEDDING_DIMENSION: ${RAG_EMBEDDING_DIMENSION:-768}
  196. RAG_EMBEDDING_URL: ${RAG_EMBEDDING_URL:-http://tei:80/v1}
  197. RAG_EMBEDDING_MODEL: ${RAG_EMBEDDING_MODEL:-intfloat/multilingual-e5-base}
  198. RAG_MILVUS_URI: ${RAG_MILVUS_URI:-http://milvus-standalone:19530}
  199. RAG_MILVUS_COLLECTION: ${RAG_MILVUS_COLLECTION:-knowledge_vectors}
  200. RAG_RETRIEVAL_TOP_K: ${RAG_RETRIEVAL_TOP_K:-8}
  201. RAG_RETRIEVAL_SCORE_THRESHOLD: ${RAG_RETRIEVAL_SCORE_THRESHOLD:-0.3}
  202. extra_hosts:
  203. - "host.docker.internal:host-gateway"
  204. volumes:
  205. - ./backend/config:/app/config
  206. depends_on:
  207. mysql:
  208. condition: service_healthy
  209. milvus-standalone:
  210. condition: service_healthy
  211. ports:
  212. - "8080:8080"
  213. healthcheck:
  214. test: ["CMD-SHELL", "bash -c '</dev/tcp/localhost/8080' 2>/dev/null && exit 0 || exit 1"]
  215. interval: 15s
  216. timeout: 5s
  217. retries: 20
  218. start_period: 90s
  219. # ──────────────────────────────────────────
  220. # 6. Python Iceberg 服务
  221. # 启动时会调用 backend 获取配置,必须在 backend 之后启动
  222. # ──────────────────────────────────────────
  223. python-iceberg:
  224. build:
  225. context: ./python-iceberg
  226. dockerfile: Dockerfile
  227. container_name: ws-python-iceberg
  228. restart: unless-stopped
  229. depends_on:
  230. backend:
  231. condition: service_healthy
  232. polaris:
  233. condition: service_healthy
  234. ports:
  235. - "8090:8090"
  236. environment:
  237. BACKEND_URL: ${ICEBERG_BACKEND_URL:-http://backend:8080}
  238. BACKEND_INTERNAL_HEADER: ${BACKEND_INTERNAL_HEADER:-X-Internal-Token}
  239. BACKEND_INTERNAL_TOKEN: ${BACKEND_INTERNAL_TOKEN:-change-me-internal-token}
  240. # ──────────────────────────────────────────
  241. # 7. 前端(Nginx)
  242. # ──────────────────────────────────────────
  243. frontend:
  244. build:
  245. context: ./frontend
  246. dockerfile: Dockerfile
  247. container_name: ws-frontend
  248. restart: unless-stopped
  249. depends_on:
  250. - backend
  251. ports:
  252. - "80:80"
  253. # ──────────────────────────────────────────
  254. # 8. k8s-orchestrator(默认启动,需可访问 K8s API)
  255. # ──────────────────────────────────────────
  256. ws-orchestrator-api:
  257. build:
  258. context: ./k8s-orchestrator
  259. dockerfile: Dockerfile.api
  260. container_name: ws-orchestrator-api
  261. restart: unless-stopped
  262. user: "0:0"
  263. environment:
  264. TZ: ${TZ:-Asia/Shanghai}
  265. API_BIND_ADDRESS: ":8080"
  266. SECRET_NAMESPACE: ${K8S_ORCHESTRATOR_SECRET_NAMESPACE:-orchestrator-system}
  267. KUBECONFIG: /kube/config
  268. volumes:
  269. - ${K8S_KUBECONFIG_PATH:-/root/.kube/config}:/kube/config:ro
  270. ports:
  271. - "18080:8080"
  272. ws-orchestrator-controller:
  273. build:
  274. context: ./k8s-orchestrator
  275. dockerfile: Dockerfile.controller
  276. container_name: ws-orchestrator-controller
  277. restart: unless-stopped
  278. user: "0:0"
  279. command: ["--leader-elect=false"]
  280. environment:
  281. TZ: ${TZ:-Asia/Shanghai}
  282. KUBECONFIG: /kube/config
  283. SERVER_IP: ${SERVER_IP:-}
  284. KUBEADM_JOIN_COMMAND: ${KUBEADM_JOIN_COMMAND:-}
  285. STARROCKS_BOOTSTRAP_POLARIS_ENABLED: ${STARROCKS_BOOTSTRAP_POLARIS_ENABLED:-true}
  286. POLARIS_HOST: ${POLARIS_HOST:-}
  287. POLARIS_CLIENT_ID: ${POLARIS_CLIENT_ID:-root}
  288. POLARIS_CLIENT_SECRET: ${POLARIS_CLIENT_SECRET:-s3cr3t}
  289. POLARIS_CATALOG_NAME: ${POLARIS_CATALOG_NAME:-polaris}
  290. POLARIS_CATALOG_WAREHOUSE: ${POLARIS_CATALOG_WAREHOUSE:-demo_catalog}
  291. POLARIS_CATALOG_DROP_WITH_PURGE_ENABLED: ${POLARIS_CATALOG_DROP_WITH_PURGE_ENABLED:-true}
  292. POLARIS_CATALOG_OAUTH2_CREDENTIAL: ${POLARIS_CATALOG_OAUTH2_CREDENTIAL:-}
  293. POLARIS_CATALOG_OAUTH2_SCOPE: ${POLARIS_CATALOG_OAUTH2_SCOPE:-PRINCIPAL_ROLE:ALL}
  294. POLARIS_CATALOG_VENDED_CREDENTIALS_ENABLED: ${POLARIS_CATALOG_VENDED_CREDENTIALS_ENABLED:-false}
  295. STARROCKS_BOOTSTRAP_STORAGE_REGION: ${STARROCKS_BOOTSTRAP_STORAGE_REGION:-${OSS_REGION:-}}
  296. STARROCKS_BOOTSTRAP_STORAGE_ENDPOINT: ${STARROCKS_BOOTSTRAP_STORAGE_ENDPOINT:-${OSS_ENDPOINT:-}}
  297. STARROCKS_BOOTSTRAP_STORAGE_ACCESS_KEY: ${STARROCKS_BOOTSTRAP_STORAGE_ACCESS_KEY:-${OSS_AK:-}}
  298. STARROCKS_BOOTSTRAP_STORAGE_SECRET_KEY: ${STARROCKS_BOOTSTRAP_STORAGE_SECRET_KEY:-${OSS_SK:-}}
  299. STARROCKS_BOOTSTRAP_STORAGE_PATH_STYLE_ACCESS: ${STARROCKS_BOOTSTRAP_STORAGE_PATH_STYLE_ACCESS:-false}
  300. volumes:
  301. - ${K8S_KUBECONFIG_PATH:-/root/.kube/config}:/kube/config:ro