feat(deploy): 阿里云ECS+1Panel 服务器部署方案落地
- docker-compose.server.yml:生产编排(复用 1Panel MySQL、去 mysql/redis、 端口仅绑 127.0.0.1、TZ=Asia/Shanghai、MYSQL_HOST 必填守卫) - 两份 Dockerfile 内置国内构建源:apt/pip→阿里云,npm/playwright→npmmirror (ECS 上直连官方源慢/超时;对本地构建同样可用) - DEPLOY.md 重写为 v2 runbook:单站点反代架构、mysqldump+media 搬迁管道 (ngram 索引导入重建 ~12min)、验收清单、运维表、本地停 scheduler 收尾 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# docker-compose.server.yml — 服务器(阿里云 ECS + 1Panel)专用生产编排。
|
||||
#
|
||||
# 与 docker-compose.yml(本地五服务开发栈)的差异:
|
||||
# - 不含 mysql/redis:MySQL 复用 1Panel 已装实例(已建 yunke 库,用户权限
|
||||
# 「所有区域(%)」,容器经宿主机内网 IP 访问,3306 不对公网);redis 应用
|
||||
# 尚未接线(config 里只有一个默认 URL),省一份常驻内存——app 将来接
|
||||
# redis 时记得同步回这里。
|
||||
# - DB_URL 主机/端口走 MYSQL_HOST / MYSQL_PORT 环境变量(.env 里填宿主机
|
||||
# 内网 IP,如 172.19.x.x;容器→宿主机内网 IP 是 docker bridge 默认可达)。
|
||||
# - 端口只绑 127.0.0.1:frontend 供 1Panel OpenResty(host 网络)反代;
|
||||
# backend 不映射宿主机(/api 由 frontend 容器内 nginx 反代,见
|
||||
# yunkes/nginx.conf)。
|
||||
# - TZ=Asia/Shanghai:调度按北京时间触发(FULL_SYNC_HOUR=2 即北京 02:00)。
|
||||
#
|
||||
# 用法(服务器仓库根目录,完整步骤见 docs/DEPLOY.md):
|
||||
# docker compose -f docker-compose.server.yml --env-file .env up -d --build
|
||||
# docker compose -f docker-compose.server.yml logs -f scheduler
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./yunke-server
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- uvicorn
|
||||
- app.api.main:app
|
||||
- --host
|
||||
- 0.0.0.0
|
||||
- --port
|
||||
- "8000"
|
||||
environment:
|
||||
DB_URL: mysql+asyncmy://${MYSQL_USER:-yunke}:${MYSQL_PASSWORD}@${MYSQL_HOST:?set MYSQL_HOST in .env}:${MYSQL_PORT:-3306}/${MYSQL_DATABASE:-yunke}
|
||||
MEDIA_DIR: /data/media
|
||||
YUNKE_BASE_URL: ${YUNKE_BASE_URL:-https://crm2.yunkecn.com}
|
||||
YUNKE_USERNAME: ${YUNKE_USERNAME:-}
|
||||
YUNKE_PASSWORD: ${YUNKE_PASSWORD:-}
|
||||
YK_USERID: ${YK_USERID:-}
|
||||
YK_COMPANY: ${YK_COMPANY:-}
|
||||
YK_COOKIE: ${YK_COOKIE:-}
|
||||
API_TOKEN: ${API_TOKEN:-}
|
||||
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-}
|
||||
TZ: Asia/Shanghai
|
||||
volumes:
|
||||
# 媒体 bind mount:服务器上 ./yunke-server/media 数据直观可见、好备份
|
||||
- ./yunke-server/media:/data/media
|
||||
|
||||
scheduler:
|
||||
build:
|
||||
context: ./yunke-server
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- python
|
||||
- -m
|
||||
- app.sync.cli
|
||||
- scheduler
|
||||
environment:
|
||||
DB_URL: mysql+asyncmy://${MYSQL_USER:-yunke}:${MYSQL_PASSWORD}@${MYSQL_HOST:?set MYSQL_HOST in .env}:${MYSQL_PORT:-3306}/${MYSQL_DATABASE:-yunke}
|
||||
MEDIA_DIR: /data/media
|
||||
YUNKE_BASE_URL: ${YUNKE_BASE_URL:-https://crm2.yunkecn.com}
|
||||
YUNKE_USERNAME: ${YUNKE_USERNAME:-}
|
||||
YUNKE_PASSWORD: ${YUNKE_PASSWORD:-}
|
||||
YK_USERID: ${YK_USERID:-}
|
||||
YK_COMPANY: ${YK_COMPANY:-}
|
||||
YK_COOKIE: ${YK_COOKIE:-}
|
||||
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-}
|
||||
# 调度节奏(北京时间):每晚全量 + 每 4h 消息增量
|
||||
FULL_SYNC_HOUR: ${FULL_SYNC_HOUR:-2}
|
||||
MESSAGE_INTERVAL_HOURS: ${MESSAGE_INTERVAL_HOURS:-4}
|
||||
TZ: Asia/Shanghai
|
||||
volumes:
|
||||
- ./yunke-server/media:/data/media
|
||||
|
||||
frontend:
|
||||
build:
|
||||
context: ./yunkes
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- backend
|
||||
ports:
|
||||
# 只绑 127.0.0.1:公网流量一律走 1Panel OpenResty 反代(80/443),
|
||||
# 5173 不暴露到安全组
|
||||
- "127.0.0.1:5173:80"
|
||||
Reference in New Issue
Block a user