DEPLOYMENT.md 19 KB

auto_put_ad_mini 生产部署指南

概述

本文档说明如何将 auto_put_ad_mini 部署到海外服务器的 Docker/Kubernetes 环境,实现生产级自动化运行。

核心特性

已实现功能

Docker 容器化

  • Dockerfile 基于 Python 3.10 slim
  • 多阶段构建,优化镜像大小
  • 健康检查支持

账户白名单机制

  • 环境变量配置白名单账户
  • 双重安全检查(决策阶段 + 执行阶段)
  • 支持 whitelist.json 配置文件

海外环境适配

  • 代理配置从环境变量读取
  • 时区支持(UTC/Asia/Shanghai)
  • 移除硬编码本地代理

定时调度

  • FastAPI + APScheduler 常驻服务(推荐)
  • Kubernetes CronJob 支持(备用)
  • HTTP API 手动触发

监控和日志

  • 健康检查端点 /health
  • 请求日志中间件
  • Prometheus metrics 导出(可选)
  • 日志输出到 stdout(Kubernetes 友好)

安全配置

  • Kubernetes Secret 管理敏感信息
  • NetworkPolicy 网络隔离
  • 非 root 用户运行
  • 资源限制和配额

项目结构

auto_put_ad_mini/
├── Dockerfile              # Docker 镜像定义
├── .dockerignore          # Docker 构建排除文件
├── docker-compose.yml     # 本地开发环境
├── requirements.txt       # Python 依赖
├── server.py              # FastAPI + APScheduler 服务器(推荐)
├── execute_once.py        # 单次执行入口
├── schedule.sh            # Cron 脚本(备用)
├── whitelist.json         # 白名单账户配置
├── metrics.py             # Prometheus 指标导出
├── utils/
│   └── log_capture.py     # 并发日志捕获
├── k8s/                   # Kubernetes 部署清单
│   ├── README.md          # K8s 部署详细说明
│   ├── namespace.yaml     # 命名空间
│   ├── deployment.yaml    # Deployment + Service
│   ├── cronjob.yaml       # CronJob(备用)
│   ├── configmap.yaml     # 公开配置
│   ├── secret.yaml        # 敏感信息
│   ├── pvc.yaml           # 持久化存储
│   └── network-policy.yaml # 网络策略
└── DEPLOYMENT.md          # 本文档

快速开始

阶段 1:本地测试

方式 A:Docker Compose(开发环境)

# 1. 进入项目目录
cd /Users/liulidong/project/agent/Agent/examples/auto_put_ad_mini

# 2. 创建 .env 文件(从 .env.example 复制并填入真实值)
cp .env.example .env
vim .env  # 填入实际的 API 密钥和配置

# 3. 构建镜像
docker build -t auto-put-ad-mini:test .

# 4. 启动服务(APScheduler 模式)
docker-compose up -d

# 5. 查看日志
docker-compose logs -f

# 6. 测试健康检查
curl http://localhost:8080/health | jq .

# 7. 手动触发任务
curl -X POST http://localhost:8080/trigger | jq .

# 8. 停止服务
docker-compose down

方式 B:单次执行测试

# 测试单次执行(不启动调度服务)
docker run --rm \
  --env-file .env \
  -e EXECUTION_ENABLED=false \
  -e WHITELIST_ENABLED=true \
  -e WHITELIST_ACCOUNTS=80769799 \
  -v $(pwd)/outputs:/app/outputs \
  auto-put-ad-mini:test \
  python execute_once.py

# 验证输出
ls -lh outputs/reports/
cat outputs/reports/llm_decisions_*.csv | head

阶段 2:推送镜像到仓库

# 1. 登录镜像仓库
docker login your-registry.com

# 2. 打标签
docker tag auto-put-ad-mini:test your-registry.com/auto-put-ad-mini:v1.0.0
docker tag auto-put-ad-mini:test your-registry.com/auto-put-ad-mini:latest

# 3. 推送
docker push your-registry.com/auto-put-ad-mini:v1.0.0
docker push your-registry.com/auto-put-ad-mini:latest

阶段 3:Kubernetes 部署

详细步骤见 k8s/README.md

推荐部署方式:Deployment + APScheduler

# 1. 创建命名空间
kubectl apply -f k8s/namespace.yaml

# 2. 修改 k8s/secret.yaml,填入真实密钥
vim k8s/secret.yaml

# 3. 部署所有资源
kubectl apply -f k8s/pvc.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/deployment.yaml

# 4. 验证部署
kubectl get all -n ad-automation
kubectl logs -f -n ad-automation deployment/auto-put-ad-mini

# 5. 端口转发测试
kubectl port-forward -n ad-automation svc/auto-put-ad-mini 8080:8080

# 6. 测试健康检查
curl http://localhost:8080/health | jq .

# 7. 手动触发任务
curl -X POST http://localhost:8080/trigger | jq .

配置说明

日级 ROI 三日口径

  • 正式任务每天北京时间09:00执行;在创建数据库批次和发送消息前,必须确认 loghubods.opengid_base_data 已存在精确T-1分区,且小程序投流和公众号投流相关数据均非空。未就绪时禁止退回旧分区。
  • 日级 ROI 读取 T-1 至 T-3 三个连续完整数据日,数据深度过滤使用最新业务 SQL 的 usersharedepth<=1
  • 正式阈值样本为连续三天每天首层 UV>200、成本>0 且 ROI 有效的小程序创意级和公众号实体;两类实体合并后按实体等权计算整体 P20 关停线。
  • 小程序广告级从 ODPS 原始数据按广告直接 COUNT(DISTINCT mid),复用同一 P20,但不重复进入样本池;低于关停线且广告 age>3 天时生成广告级关停建议。
  • 金额、UV 和人数在三日汇总表展示为三日总量/3;ROI 与裂变率使用三日总分子/总分母的加权口径。
  • 未进入三日正式样本的小程序创意增加单日补充判断:最新日首层 UV>200 且预测总效率 ROI≤0.20,或最新日首层 UV>500 且预测总效率 ROI≤全部最新日 UV>500 小程序创意的实体等权 P30;命中且广告 age>3 天时建议关停,命中但 age≤3 天时观察。动作原因同时展示最新日判断值与仅供参考的三日预测 ROI。其余最新日首层 UV>200 的非正式实体继续置底观察,不参与三日 P20。
  • 报表包含小程序创意级、小程序广告级、公众号的三日汇总与每日明细共 6 个主 Sheet;广告级两个 Sheet 默认隐藏,企微暂不进入本版计算和报表。
  • 每日明细 Sheet 的 dt 位于第一列,整表按日期倒序排列。
  • 可见 ROI 列简化为“当日效率ROI”和“预测总效率ROI”;其后依次展示“关停线(P20)”和“扩量线(P80)”,公众号不参与扩量故扩量线留空;整体三日排名百分位保留为隐藏审计字段。
  • “动作”可见列改为“建议动作”,其后展示“建议说明”;小程序创意级和广告级关停分别显示“关停创意”“关停广告”,但底层动作不变。创意关停按三日P20、单日硬线、单日P30三类原因分组,同类按 ROI 升序。底层无动作的正式中间区间在报表中显示为“观察”,但不生成可执行动作。阈值样本状态、执行状态和执行结果保留为隐藏审计字段。
  • 当前三日策略以创意级+公众号合格实体统一等权 P20 生成低 ROI 关停建议;以合格小程序创意实体等权 P80 识别头部20%,广告 age≥3 时生成扩量建议。所有小程序创意级和广告级关停均要求广告 age>3 天;创意级关停批准后只暂停对应动态创意,广告级关停批准后暂停整个广告。
  • 汇总表将三日总 T0 裂变人数 / 三日总首层 UV 的加权比例展示为“日均T0裂变率”。汇总顺序为关停、扩量、中间观察、条件不足观察;第一条扩量行和扩量后第一条观察行顶部均使用粗线分隔。“当日效率ROI”和“预测总效率ROI”均使用深红—黄—绿色阶,绿色代表表现好。普通数值显示两位小数,UV、人数、数量和广告年龄显示整数;两个“裂变系数-总裂变UV/…”比率列固定显示两位小数。“传播裂变系数匹配”保留审计数据但默认隐藏。
  • “审批选择”默认隐藏,需取消隐藏后审批;创意级“当前创意状态”只对关停建议只读腾讯状态,显示正常、已停止或读取失败,其他行留空。
  • 完整主报表保存后,流程会额外按“小程序投流”渠道的“代理名称”生成一代理一份调控建议工作簿;文件名为 YYYYMMDD_代理名称_调控建议.xlsx。代理版只包含小程序创意级和广告级三日汇总,广告级 Sheet 继续隐藏,不包含每日明细。包名、广告age、日均首层UV、建议说明、收入、预测总效率ROI、P20/P80/P30、排名、两个裂变系数、日均T0裂变人数/率、审批、执行状态和幂等键均不会写入代理文件;内部“当日效率ROI”仅改名为两位小数的“评分”展示,建议动作仍按预测总效率ROI计算并保留“关停创意/关停广告/扩量/观察”。代理表默认只落本地;开启 ROI_AGENCY_WEBHOOK_ENABLED 后,飞书应用先上传在线表,再由 ROI_AGENCY_WEBHOOKS_JSON 中精确匹配的代理机器人发送卡片。未配置代理直接跳过,不回退总群;完整 webhook 只能放在真实 .env 或密钥系统,数据库和日志只保存哈希指纹。
  • 可选内部测试任务每天北京时间15:30执行独立复算,只将“自动化投放”分表发送到“内部”Webhook,不发送完整主表、正式总群或代理群,也不生成可审批腾讯动作。缺少该分表时任务失败并告警。正式任务始终去重;内部测试使用 ROI_INTERNAL_TEST_DEDUP_ENABLED 控制,设为0时每次显式触发都发送新的测试批次。内部任务无startup入口,重启服务不会自动补发。
  • 09:00正式任务或15:30内部测试执行失败时,调度服务通过飞书应用向 ROI_FAILURE_FEISHU_CHAT_ID 发送红色告警卡片;未配置时回退 FEISHU_OPERATOR_CHAT_ID。告警失败只记日志,不会掩盖原任务失败。

离线复算不发送飞书:

.venv/bin/python examples/auto_put_ad_mini/run_daily_roi.py \
  --end-date YYYYMMDD \
  --source-revision <稳定修订标识>

只有显式增加 --send-feishu 才会发布飞书表格;该命令本身不会直接执行腾讯写操作。

环境变量

变量名 说明 默认值 必需
WHITELIST_ENABLED 启用账户白名单 true
WHITELIST_ACCOUNTS 白名单账户ID(逗号分隔) - 是(启用白名单时)
EXECUTION_ENABLED 启用实际执行 false
HTTP_PROXY HTTP 代理地址 -
HTTPS_PROXY HTTPS 代理地址 -
TZ 时区 UTC
CRON_SCHEDULE 定时表达式 0 2 * * *
RUN_ON_STARTUP 启动时立即执行 false
PORT FastAPI 端口 8080
FEISHU_APP_ID 飞书应用ID -
FEISHU_APP_SECRET 飞书应用密钥 -
TENCENT_AD_ACCOUNT_ID 腾讯广告账户ID -
ODPS_ACCESS_ID ODPS 访问ID -
ODPS_ACCESS_SECRET ODPS 访问密钥 -
OPEN_ROUTER_API_KEY OpenRouter API Key -
EXTERNAL_RECALL_SOURCE_LABEL 外部素材召回源标签 外部合作
EXTERNAL_RECALL_CANDIDATE_LIMIT 外部素材进入 UV 排序的候选上限 300
EXTERNAL_RECALL_EDIT_LIMIT_PER_LANDING 单个承接视频最多尝试清理的外部素材数 3
EXTERNAL_RECALL_UV_WINDOW_DAYS 外部素材访问 UV 汇总窗口天数 90
EXTERNAL_IMAGE_MODEL 外部素材参考图编辑模型 复用 OPENROUTER_IMAGE_MODEL

白名单配置

方式 1:环境变量(推荐)

# .env 或 k8s/secret.yaml
WHITELIST_ENABLED=true
WHITELIST_ACCOUNTS=80769799,71305011,12345678

方式 2:配置文件

编辑 whitelist.json

{
  "accounts": [80769799, 71305011],
  "description": "生产环境白名单账户列表",
  "last_updated": "2026-04-22"
}

定时调度配置

Cron 表达式格式分 时 日 月 周

示例:

  • 0 2 * * * - 每天凌晨 2 点(UTC)
  • 30 1 * * * - 每天凌晨 1:30(UTC)
  • 0 */6 * * * - 每 6 小时执行一次
  • 0 9 * * 1-5 - 工作日上午 9 点

修改定时:

# Kubernetes ConfigMap
kubectl patch configmap ad-config -n ad-automation \
  --patch '{"data":{"CRON_SCHEDULE":"0 3 * * *"}}'

kubectl rollout restart deployment/auto-put-ad-mini -n ad-automation

监控和运维

健康检查

# 本地
curl http://localhost:8080/health

# Kubernetes
kubectl exec -n ad-automation <pod-name> -- curl -f http://localhost:8080/health

返回示例:

{
  "status": "healthy",
  "timestamp": "2026-04-22T10:00:00Z",
  "scheduler_running": true,
  "latest_report": "llm_decisions_20260422.csv",
  "jobs": [
    {
      "id": "decision_pipeline",
      "name": "广告决策流程",
      "next_run": "2026-04-23T02:00:00Z"
    }
  ]
}

日志查看

Docker

docker logs -f auto-put-ad-mini

Kubernetes

# 实时日志
kubectl logs -f -n ad-automation deployment/auto-put-ad-mini

# 最近 100 行
kubectl logs -n ad-automation deployment/auto-put-ad-mini --tail=100

# 查看多个 Pod 日志
kubectl logs -n ad-automation -l app=auto-put-ad-mini --all-containers=true

查看输出文件

Docker

docker exec -it auto-put-ad-mini ls -lh /app/outputs/reports/
docker exec -it auto-put-ad-mini cat /app/outputs/reports/llm_decisions_*.csv

Kubernetes

POD_NAME=$(kubectl get pods -n ad-automation -l app=auto-put-ad-mini -o jsonpath='{.items[0].metadata.name}')
kubectl exec -n ad-automation $POD_NAME -- ls -lh /app/outputs/reports/
kubectl exec -n ad-automation $POD_NAME -- cat /app/outputs/reports/llm_decisions_*.csv

Prometheus 监控(可选)

如果启用了 Prometheus metrics:

# 查看 metrics 文件
kubectl exec -n ad-automation $POD_NAME -- cat /app/outputs/metrics.prom

配置 Prometheus 抓取:

scrape_configs:
  - job_name: 'auto-put-ad-mini'
    file_sd_configs:
      - files:
        - /app/outputs/metrics.prom

故障排查

问题 1:容器启动失败

# 查看 Pod 状态
kubectl describe pod <pod-name> -n ad-automation

# 查看事件
kubectl get events -n ad-automation --sort-by='.lastTimestamp'

# 查看日志
kubectl logs <pod-name> -n ad-automation --previous

常见原因:

  • Secret 未配置或配置错误
  • PVC 未创建或无法挂载
  • 镜像拉取失败

问题 2:定时任务未执行

# 检查调度器状态
curl http://localhost:8080/health | jq .scheduler_running

# 查看下次执行时间
curl http://localhost:8080/health | jq .jobs

# 手动触发测试
curl -X POST http://localhost:8080/trigger

问题 3:白名单过滤异常

# 查看日志,搜索白名单相关信息
kubectl logs -n ad-automation deployment/auto-put-ad-mini | grep "白名单"

# 检查配置
kubectl get secret ad-secrets -n ad-automation -o jsonpath='{.data.WHITELIST_ACCOUNTS}' | base64 -d

问题 4:代理连接失败

# 检查代理配置
kubectl get configmap ad-config -n ad-automation -o yaml | grep PROXY

# 测试代理连接
kubectl exec -n ad-automation $POD_NAME -- curl -x $HTTP_PROXY https://api.e.qq.com

回滚和恢复

回滚到上一个版本

# Deployment 模式
kubectl rollout undo deployment/auto-put-ad-mini -n ad-automation

# CronJob 模式
kubectl set image cronjob/auto-put-ad-mini \
  decision-engine=your-registry/auto-put-ad-mini:v0.9.0 \
  -n ad-automation

暂停服务

# Deployment 模式
kubectl scale deployment auto-put-ad-mini --replicas=0 -n ad-automation

# CronJob 模式
kubectl patch cronjob auto-put-ad-mini -n ad-automation -p '{"spec":{"suspend":true}}'

恢复服务

# Deployment 模式
kubectl scale deployment auto-put-ad-mini --replicas=1 -n ad-automation

# CronJob 模式
kubectl patch cronjob auto-put-ad-mini -n ad-automation -p '{"spec":{"suspend":false}}'

安全最佳实践

1. Secret 管理

  • 不要将真实 Secret 提交到 Git
  • ✅ 使用 Kubernetes External Secrets 或 Sealed Secrets
  • ✅ 定期轮换敏感凭据
  • ✅ 限制 Secret 访问权限

2. 网络安全

  • ✅ 启用 NetworkPolicy 限制出入站流量
  • ✅ 仅允许必要的外部连接(腾讯 API、飞书 API)
  • ✅ 使用代理服务访问外部资源

3. 资源隔离

  • ✅ 使用独立命名空间(ad-automation
  • ✅ 设置 CPU 和内存 limits
  • ✅ 使用 LimitRange 和 ResourceQuota

4. 运行时安全

  • ✅ 非 root 用户运行(UID 1000)
  • ✅ 禁用特权容器
  • ✅ 使用 readOnlyRootFilesystem(输出目录除外)

性能优化

资源配置建议

环境 CPU Request CPU Limit Memory Request Memory Limit
测试 250m 500m 512Mi 1Gi
生产 500m 1 1Gi 2Gi
高负载 1 2 2Gi 4Gi

并发控制

  • APScheduler max_instances=1 防止任务并发
  • Kubernetes CronJob concurrencyPolicy: Forbid

日志轮转

# 输出目录定期清理
find /app/outputs -name "cron_*.log" -mtime +30 -delete

升级策略

滚动更新

# 更新镜像
kubectl set image deployment/auto-put-ad-mini \
  decision-engine=your-registry/auto-put-ad-mini:v1.1.0 \
  -n ad-automation

# 查看更新状态
kubectl rollout status deployment/auto-put-ad-mini -n ad-automation

灰度发布

# 创建 Canary Deployment
kubectl apply -f k8s/deployment-canary.yaml

# 验证 Canary 版本
kubectl logs -n ad-automation deployment/auto-put-ad-mini-canary

# 全量发布
kubectl set image deployment/auto-put-ad-mini \
  decision-engine=your-registry/auto-put-ad-mini:v1.1.0 \
  -n ad-automation

# 删除 Canary
kubectl delete deployment auto-put-ad-mini-canary -n ad-automation

附录

A. 两种部署模式对比

特性 Deployment + APScheduler CronJob
资源占用 常驻 Pod(低) 每次启动新 Pod
启动速度 快(任务触发即执行) 慢(需启动容器)
健康检查 ✅ HTTP 端点 ❌ 需额外脚本
手动触发 ✅ HTTP API ⚠️ 需创建 Job
日志查看 ✅ 持续输出 ⚠️ 分散在多个 Job
监控集成 ✅ Prometheus metrics ⚠️ 需额外配置
适用场景 生产环境、频繁调度 简单定时任务

推荐:生产环境使用 Deployment + APScheduler 模式。

B. 常用命令速查

# 快速重启
kubectl rollout restart deployment/auto-put-ad-mini -n ad-automation

# 查看最近事件
kubectl get events -n ad-automation --sort-by='.lastTimestamp' | tail -20

# 进入 Pod Shell
kubectl exec -it -n ad-automation <pod-name> -- bash

# 复制文件到本地
kubectl cp ad-automation/<pod-name>:/app/outputs/reports/llm_decisions_*.csv ./local-reports/

# 查看资源使用
kubectl top pod -n ad-automation

C. 联系支持

  • 文档问题:查看 k8s/README.md 和本文档
  • 代码问题:查看 CLAUDE.md 和源码注释
  • 配置问题:查看 .env.examplek8s/configmap.yaml

文档版本:v1.0.0 最后更新:2026-04-22 维护者:auto_put_ad_mini team