From 9f9eff71d7212b796f0e99924ba23d3ed9849458 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 7 Jun 2026 10:04:08 +0000 Subject: [PATCH 1/4] chore: persist docker deployment state --- .env.example | 24 ++++++++++++++---------- Dockerfile | 2 +- docker-compose.yml | 30 ++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index 27787cd2..7cbc3f36 100644 --- a/.env.example +++ b/.env.example @@ -1,20 +1,25 @@ # Flask DEBUG=True -SECRET_KEY=change-this-secret +SECRET_KEY=change-me -# SQLite ORM default -SQLITE_DATABASE_PATH=./instance/stock_cursor.sqlite3 +# SQLite ORM default inside the container. +# docker-compose.yml persists this file under ./instance on the host. +SQLITE_DATABASE_PATH=/app/instance/stock_cursor.sqlite3 -# Redis / Celery -REDIS_HOST=localhost +# Redis / Celery inside the Docker Compose network. +# Use the service name "redis" instead of localhost from containers. +REDIS_HOST=redis REDIS_PORT=6379 REDIS_DB=0 -CELERY_BROKER_URL=redis://localhost:6379/0 -CELERY_RESULT_BACKEND=redis://localhost:6379/0 +CELERY_BROKER_URL=redis://redis:6379/0 +CELERY_RESULT_BACKEND=redis://redis:6379/0 -# Data source +# Data source. +# docker-compose.yml mounts the host ./data directory to /app/data. +# Put the downloaded Parquet data package contents in ./data on the host. DATA_SOURCE=parquet -TUSHARE_TOKEN=your_tushare_token +DATA_DIR=/app/data +TUSHARE_TOKEN=your_token # Runtime mode DATA_JOB_EXECUTION_MODE=inline @@ -22,5 +27,4 @@ DATA_JOB_EXECUTION_MODE=inline # OpenAI / LLM optional LLM_PROVIDER=openai LLM_API_KEY= -LLM_BASE_URL=https://api.deepseek.com LLM_MODEL=deepseek-v4-flash diff --git a/Dockerfile b/Dockerfile index 93077bd3..e9f7078a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* COPY requirements.txt requirements_minimal.txt ./ -RUN pip install --no-cache-dir -r requirements_minimal.txt +RUN pip install --no-cache-dir -r requirements.txt COPY . . diff --git a/docker-compose.yml b/docker-compose.yml index cd194264..e0eb9b06 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.9" - services: web: build: . @@ -8,18 +6,46 @@ services: - "5000:5000" env_file: - .env + environment: + DATA_DIR: /app/data + SQLITE_DATABASE_PATH: /app/instance/stock_cursor.sqlite3 + REDIS_HOST: redis + CELERY_BROKER_URL: redis://redis:6379/0 + CELERY_RESULT_BACKEND: redis://redis:6379/0 + volumes: + - ./data:/app/data + - ./instance:/app/instance + - ./logs:/app/logs depends_on: - redis + restart: unless-stopped worker: build: . command: celery -A app.celery_app.celery worker -l info -P solo env_file: - .env + environment: + DATA_DIR: /app/data + SQLITE_DATABASE_PATH: /app/instance/stock_cursor.sqlite3 + REDIS_HOST: redis + CELERY_BROKER_URL: redis://redis:6379/0 + CELERY_RESULT_BACKEND: redis://redis:6379/0 + volumes: + - ./data:/app/data + - ./instance:/app/instance + - ./logs:/app/logs depends_on: - redis + restart: unless-stopped redis: image: redis:7-alpine ports: - "6379:6379" + volumes: + - redis_data:/data + restart: unless-stopped + +volumes: + redis_data: From 4430c307b89fb56742c9938b56ef1aba76d2d1a4 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 7 Jun 2026 11:54:05 +0000 Subject: [PATCH 2/4] fix: include pytdx for minute data sync --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index f6b9bd18..37d823c9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -72,3 +72,4 @@ cvxpy>=1.4.0 #金融数据获取 baostock>=0.8.9 tushare>=1.3.0 +pytdx>=1.72 From f73b48e68906ea0f3bb04a553a2fc1b812ca0be5 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 7 Jun 2026 23:59:24 +0000 Subject: [PATCH 3/4] fix: address docker config review feedback --- .env.docker.example | 35 +++++++++++++++++++++++++++++++++ .env.example | 24 ++++++++++------------- app/celery_app.py | 5 +++-- docker-compose.yml | 48 +++++++++++++++------------------------------ 4 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 .env.docker.example diff --git a/.env.docker.example b/.env.docker.example new file mode 100644 index 00000000..f6a9d834 --- /dev/null +++ b/.env.docker.example @@ -0,0 +1,35 @@ +# Docker deployment example. +# Copy this file to .env before running docker compose: +# cp .env.docker.example .env + +# Flask +DEBUG=True +SECRET_KEY=change-this-secret + +# SQLite ORM default inside the container. +# docker-compose.yml persists this file under ./instance on the host. +SQLITE_DATABASE_PATH=/app/instance/stock_cursor.sqlite3 + +# Redis / Celery inside the Docker Compose network. +# Use the service name "redis" instead of localhost from containers. +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_DB=0 +CELERY_BROKER_URL=redis://redis:6379/0 +CELERY_RESULT_BACKEND=redis://redis:6379/0 +# Data source. +# docker-compose.yml mounts the host ./data directory to /app/data. +# Put the downloaded Parquet data package contents in ./data on the host. +DATA_SOURCE=parquet +DATA_DIR=/app/data +TUSHARE_TOKEN=your_tushare_token + +# Runtime mode. +# Docker Compose starts a worker service, so data jobs should use Celery. +DATA_JOB_EXECUTION_MODE=celery + +# OpenAI / LLM optional +LLM_PROVIDER=openai +LLM_API_KEY= +LLM_BASE_URL=https://api.deepseek.com +LLM_MODEL=deepseek-v4-flash diff --git a/.env.example b/.env.example index 7cbc3f36..27787cd2 100644 --- a/.env.example +++ b/.env.example @@ -1,25 +1,20 @@ # Flask DEBUG=True -SECRET_KEY=change-me +SECRET_KEY=change-this-secret -# SQLite ORM default inside the container. -# docker-compose.yml persists this file under ./instance on the host. -SQLITE_DATABASE_PATH=/app/instance/stock_cursor.sqlite3 +# SQLite ORM default +SQLITE_DATABASE_PATH=./instance/stock_cursor.sqlite3 -# Redis / Celery inside the Docker Compose network. -# Use the service name "redis" instead of localhost from containers. -REDIS_HOST=redis +# Redis / Celery +REDIS_HOST=localhost REDIS_PORT=6379 REDIS_DB=0 -CELERY_BROKER_URL=redis://redis:6379/0 -CELERY_RESULT_BACKEND=redis://redis:6379/0 +CELERY_BROKER_URL=redis://localhost:6379/0 +CELERY_RESULT_BACKEND=redis://localhost:6379/0 -# Data source. -# docker-compose.yml mounts the host ./data directory to /app/data. -# Put the downloaded Parquet data package contents in ./data on the host. +# Data source DATA_SOURCE=parquet -DATA_DIR=/app/data -TUSHARE_TOKEN=your_token +TUSHARE_TOKEN=your_tushare_token # Runtime mode DATA_JOB_EXECUTION_MODE=inline @@ -27,4 +22,5 @@ DATA_JOB_EXECUTION_MODE=inline # OpenAI / LLM optional LLM_PROVIDER=openai LLM_API_KEY= +LLM_BASE_URL=https://api.deepseek.com LLM_MODEL=deepseek-v4-flash diff --git a/app/celery_app.py b/app/celery_app.py index 863d7596..c2e14e56 100644 --- a/app/celery_app.py +++ b/app/celery_app.py @@ -38,12 +38,13 @@ def _decorator(func): def make_celery(config_name: str = "default"): cfg = config[config_name] - broker = f"redis://{cfg.REDIS_HOST}:{cfg.REDIS_PORT}/{cfg.REDIS_DB}" + broker = cfg.CELERY_BROKER_URL + backend = cfg.CELERY_RESULT_BACKEND if Celery is None: return _LocalCelery() - celery = Celery("quant_data_jobs", broker=broker, backend=broker) + celery = Celery("quant_data_jobs", broker=broker, backend=backend) celery.conf.update( task_serializer="json", accept_content=["json"], diff --git a/docker-compose.yml b/docker-compose.yml index e0eb9b06..f21d3650 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,43 +1,27 @@ +version: "3.9" + +x-app-common: &app-common + build: . + env_file: + - .env + volumes: + - ./data:/app/data + - ./instance:/app/instance + - ./logs:/app/logs + depends_on: + - redis + restart: unless-stopped + services: web: - build: . + <<: *app-common command: python run.py ports: - "5000:5000" - env_file: - - .env - environment: - DATA_DIR: /app/data - SQLITE_DATABASE_PATH: /app/instance/stock_cursor.sqlite3 - REDIS_HOST: redis - CELERY_BROKER_URL: redis://redis:6379/0 - CELERY_RESULT_BACKEND: redis://redis:6379/0 - volumes: - - ./data:/app/data - - ./instance:/app/instance - - ./logs:/app/logs - depends_on: - - redis - restart: unless-stopped worker: - build: . + <<: *app-common command: celery -A app.celery_app.celery worker -l info -P solo - env_file: - - .env - environment: - DATA_DIR: /app/data - SQLITE_DATABASE_PATH: /app/instance/stock_cursor.sqlite3 - REDIS_HOST: redis - CELERY_BROKER_URL: redis://redis:6379/0 - CELERY_RESULT_BACKEND: redis://redis:6379/0 - volumes: - - ./data:/app/data - - ./instance:/app/instance - - ./logs:/app/logs - depends_on: - - redis - restart: unless-stopped redis: image: redis:7-alpine From 109061c677824e34a4f1355e278567a4f48337ec Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Mon, 8 Jun 2026 00:11:19 +0000 Subject: [PATCH 4/4] chore: remove unused minimal requirements copy --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index e9f7078a..3240b6d2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ pkg-config \ && rm -rf /var/lib/apt/lists/* -COPY requirements.txt requirements_minimal.txt ./ +COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt COPY . .