容器化改造
This commit is contained in:
parent
dc96db734f
commit
ec8fb48977
|
|
@ -0,0 +1,7 @@
|
||||||
|
.git
|
||||||
|
.idea
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
.env
|
||||||
|
logs
|
||||||
|
.DS_Store
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
# tradingSystem (PMS) 环境变量模板
|
||||||
|
# 服务器部署: cp .env.example .env 后填入真实值。.env 已在 .gitignore, 绝不入库。
|
||||||
|
# 键名与 bionic_trader 对齐, 同一台服务器两系统可参照同一套连接信息。
|
||||||
|
# 业务参数 (PMS_TOTAL_SCALE 等) 不必写在这里 —— settings.py 有初值,
|
||||||
|
# 上线后经管理页面调整并持久化到 pms_runtime_param 表。
|
||||||
|
|
||||||
|
# ---- 153 代理 (pms_* 全部表 + trading_* + strategy_daily_results, 严格单表访问) ----
|
||||||
|
PROXY_DB_URL=mysql+pymysql://用户:密码@192.168.16.153:3307/my_quant_db
|
||||||
|
|
||||||
|
# ---- 因子分表库 (gp_stock_factor_pro_*, 自算参考位用) ----
|
||||||
|
SOURCE_DB_EXT_DSN=mysql+pymysql://用户:密码@192.168.16.150:3306/factordb_mysql
|
||||||
|
|
||||||
|
# ---- 大盘指数库 (zs_day_data, 页面区制提示用) ----
|
||||||
|
DB_MYSQL_URL=mysql+pymysql://用户:密码@192.168.18.199:3306/db_gp_cj
|
||||||
|
|
||||||
|
# ---- 信号/行情 Redis (208: 决策系统信号流 db2/db3 订阅 + 实时行情 db13) ----
|
||||||
|
SIGNAL_REDIS_HOST=192.168.18.208
|
||||||
|
SIGNAL_REDIS_PORT=6379
|
||||||
|
SIGNAL_REDIS_PASSWORD=密码
|
||||||
|
|
||||||
|
# ---- PMS 自己的 Celery 总线 (150 Redis, db8; 决策系统用 db7, 逻辑隔离) ----
|
||||||
|
PMS_REDIS_URL=redis://:密码@192.168.16.150:6379/8
|
||||||
|
|
||||||
|
# ---- 管理页面 ----
|
||||||
|
PMS_WEB_PORT=38100
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# 机密: 数据库/Redis 连接串与密码, 绝不入库 (服务器上手工维护, 参照 .env.example)
|
||||||
|
.env
|
||||||
|
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
logs/
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# PyCharm 工程文件目前已跟踪; 如决定不入库, 取消下行注释并执行:
|
||||||
|
# git rm -r --cached .idea && git commit -m "untrack .idea"
|
||||||
|
#.idea/
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
# tradingSystem (PMS) 运行镜像
|
||||||
|
# 三个服务 (pms-web / pms-beat / pms-worker) 共用本镜像, 由 docker-compose 以不同 command 启动
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
ENV TZ=Asia/Shanghai \
|
||||||
|
PYTHONUNBUFFERED=1 \
|
||||||
|
PYTHONDONTWRITEBYTECODE=1
|
||||||
|
|
||||||
|
# 国内构建默认走清华 PyPI 镜像; 网络环境不同可覆盖:
|
||||||
|
# docker compose build --build-arg PIP_INDEX_URL=https://pypi.org/simple
|
||||||
|
ARG PIP_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple
|
||||||
|
|
||||||
|
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||||
|
&& echo "Asia/Shanghai" > /etc/timezone
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 依赖层单独 COPY, 代码改动不触发重装依赖
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install --no-cache-dir -i ${PIP_INDEX_URL} -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN mkdir -p /app/logs
|
||||||
|
|
||||||
|
# 默认命令 = 管理页面; beat/worker 由 compose 覆盖 command
|
||||||
|
CMD ["uvicorn", "app.web.main:app", "--host", "0.0.0.0", "--port", "38100"]
|
||||||
26
README.md
26
README.md
|
|
@ -23,9 +23,31 @@
|
||||||
2. **分工不越权**:持仓系统管「做什么、多少」,决策系统管「该不该、何时」,下游只管执行;研判不可用时降级为保守规则 + 人工确认,不自建第二套研判。
|
2. **分工不越权**:持仓系统管「做什么、多少」,决策系统管「该不该、何时」,下游只管执行;研判不可用时降级为保守规则 + 人工确认,不自建第二套研判。
|
||||||
3. **先记账后动作 + 故障即守成**:指令先落表再下发;故障不产生新指令;账本与下游定期对账,以下游为实际持仓事实源。
|
3. **先记账后动作 + 故障即守成**:指令先落表再下发;故障不产生新指令;账本与下游定期对账,以下游为实际持仓事实源。
|
||||||
|
|
||||||
|
## Docker 部署(项目统一以容器方式构建运行)
|
||||||
|
|
||||||
|
服务共用一个镜像:`pms-web`(管理页面,端口 38100)+ `pms-beat` / `pms-worker`(Celery 调度与执行,挂在 `sched` profile 下,调度器代码就绪后启用)。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 服务器首次部署
|
||||||
|
git clone <仓库地址> && cd tradingSystem
|
||||||
|
cp .env.example .env && vim .env # 填入真实连接串 (.env 不入库)
|
||||||
|
docker compose build # 默认走清华 PyPI 镜像; 可 --build-arg PIP_INDEX_URL=... 覆盖
|
||||||
|
docker compose run --rm pms-web python scripts/test_core_units.py # 构建验证: 应输出 ALL PASS (14 cases)
|
||||||
|
docker compose up -d # 当前仅启动 pms-web
|
||||||
|
curl http://127.0.0.1:38100/health # 健康检查 + 配置装载自证
|
||||||
|
|
||||||
|
# 调度器代码就绪后
|
||||||
|
docker compose --profile sched up -d
|
||||||
|
|
||||||
|
# 日常更新
|
||||||
|
git pull && docker compose build && docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
基础镜像 `python:3.11-slim` 拉取慢时,先给服务器 Docker 配置 registry 镜像加速。日志落 `./logs`(已挂载卷);容器时区 Asia/Shanghai。
|
||||||
|
|
||||||
## 开发约定
|
## 开发约定
|
||||||
|
|
||||||
- 开发机与服务器经 git 同步代码;测试脚本由用户在实机运行,结果回传后迭代。
|
- 开发机与服务器经 git 同步代码;**构建与运行统一走 Docker**(`docker compose build` → 容器内跑测试脚本 → `up -d`),测试结果回传后迭代。
|
||||||
- 153 代理侧数据库严格单表访问;持仓系统内部代码统一 Tushare 点式。
|
- 153 代理侧数据库严格单表访问;持仓系统内部代码统一 Tushare 点式。
|
||||||
- 配置全部在 `config/settings.py` 显式声明字段;参数可经管理页面在线修改并持久化。
|
- 配置分两层:基础设施连接串在 `.env`(服务器手工维护,不入库,模板见 `.env.example`);业务参数在 `config/settings.py` 只是初值,上线后经管理页面修改并持久化到 `pms_runtime_param` 表。
|
||||||
- 里程碑(设计定稿、建表、各期上线)及时 git 提交。
|
- 里程碑(设计定稿、建表、各期上线)及时 git 提交。
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
PMS 管理页面 · Web 入口 (当前为最小骨架)
|
||||||
|
==========================================
|
||||||
|
现阶段职责: 让 pms-web 容器可启动、可健康检查, 验证 Docker 构建与配置装载链路。
|
||||||
|
后续在此基础上扩展四块页面 (POSITION_MGMT_DESIGN.md §3.3):
|
||||||
|
参数设置 / 命令台 / 持仓与账本 / 提议确认。
|
||||||
|
"""
|
||||||
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
from config.settings import settings
|
||||||
|
|
||||||
|
VERSION = "0.1.0-dev"
|
||||||
|
|
||||||
|
app = FastAPI(title="PMS 持仓管理系统", version=VERSION)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/health")
|
||||||
|
def health():
|
||||||
|
"""容器健康检查 + 配置装载自证 (不连库, 只回显关键初值)。"""
|
||||||
|
return {
|
||||||
|
"status": "ok",
|
||||||
|
"version": VERSION,
|
||||||
|
"service": "pms-web",
|
||||||
|
"config_loaded": {
|
||||||
|
"total_scale": settings.PMS_TOTAL_SCALE,
|
||||||
|
"portfolio_cap": settings.PMS_PORTFOLIO_CAP,
|
||||||
|
"stock_cap": settings.PMS_STOCK_CAP,
|
||||||
|
"max_names": settings.PMS_MAX_NAMES,
|
||||||
|
"autonomy": settings.PMS_AUTONOMY,
|
||||||
|
"web_port": settings.PMS_WEB_PORT,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/")
|
||||||
|
def index():
|
||||||
|
return {"hint": "PMS 管理页面骨架。健康检查: /health ; 页面四块随后续开发接入。"}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
# tradingSystem (PMS) 容器编排
|
||||||
|
# 用法见 README「Docker 部署」。.env 放在本文件同目录 (服务器上手工维护, 不入库)。
|
||||||
|
# 当前默认只启动 pms-web; pms-beat / pms-worker 挂在 sched profile 下,
|
||||||
|
# 调度器代码 (app/scheduler.py) 就绪后用 --profile sched 启用。
|
||||||
|
|
||||||
|
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
|
||||||
Loading…
Reference in New Issue