tradingSystem/docker-compose.yml

65 lines
2.3 KiB
YAML
Raw Normal View History

2026-07-27 16:02:43 +08:00
# tradingSystem (PMS) 容器编排
# 用法见 README「Docker 部署」。.env 放在本文件同目录 (服务器上手工维护, 不入库)。
2026-07-28 15:48:57 +08:00
# 三组服务:
# 默认 pms-web 管理页面 (38100)
# --profile sched pms-beat / pms-worker Celery 调度与执行
# --profile ws pms-ws QMT WebSocket 常驻连接 (协议 V1.0)
#
# pms-ws 与 worker 的关系: worker 里的 executor 把待发委托写进 pms_qmt_order 出口表,
# pms-ws 亚秒轮询取走并发出。两者**只经数据库耦合**, 谁先起谁后起都不影响 —— pms-ws 没起
# 来时 dispatcher 会因心跳陈旧而拒发, 指令保持原状, 不会静默堆在队列里。
2026-07-27 16:02:43 +08:00
x-pms-base: &pms-base
build: .
image: pms:latest
env_file: .env
environment:
- TZ=Asia/Shanghai
volumes:
- ./logs:/app/logs
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "50m"
max-file: "5"
services:
pms-web:
<<: *pms-base
container_name: pms-web
command: uvicorn app.web.main:app --host 0.0.0.0 --port 38100
ports:
- "38100:38100"
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:38100/health', timeout=3)"]
interval: 30s
timeout: 5s
retries: 3
start_period: 10s
pms-beat:
<<: *pms-base
container_name: pms-beat
profiles: ["sched"]
command: celery -A app.scheduler.celery_app beat -l info
pms-worker:
<<: *pms-base
container_name: pms-worker
profiles: ["sched"]
command: celery -A app.scheduler.celery_app worker -l info -c 2
2026-07-28 15:48:57 +08:00
# QMT WebSocket 常驻连接。协议 §1 规定 PMS 只开一条连接 (多开会让指令乱序),
# 所以这个服务**绝不能扩副本** —— 不要 deploy.replicas, 不要 docker compose up --scale。
# 退出流程见 app/ws/runner.py 的 _shutdown: 刷水位 → 最后一次 ack → 关连接 → 清心跳,
# stop_grace_period 给足 25 秒是为了让这一串跑完; 强杀会丢掉最后一批 ack (不丢数据,
# 只是让 QMT 多留一会儿, 重连后按 last_seq 补发)。
pms-ws:
<<: *pms-base
container_name: pms-ws
profiles: ["ws"]
command: python -m app.ws.runner
stop_grace_period: 25s
stop_signal: SIGTERM