auto-save 2026-05-15 14:47 (+6, ~5)
This commit is contained in:
23
.dockerignore
Normal file
23
.dockerignore
Normal file
@@ -0,0 +1,23 @@
|
||||
.git
|
||||
.gitignore
|
||||
.memory
|
||||
.logs
|
||||
.pids
|
||||
.playwright-mcp
|
||||
.DS_Store
|
||||
*.log
|
||||
|
||||
node_modules
|
||||
web/node_modules
|
||||
web/.next
|
||||
web/out
|
||||
|
||||
api/.venv
|
||||
api/jobs
|
||||
jobs
|
||||
data
|
||||
|
||||
.env
|
||||
.env.local
|
||||
.env.production
|
||||
deploy/.env.production
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,6 +14,7 @@ __pycache__/
|
||||
*.log
|
||||
.logs/
|
||||
.pids/
|
||||
deploy/.env.production
|
||||
|
||||
# api
|
||||
api/.venv/
|
||||
|
||||
@@ -1,18 +1,5 @@
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"files_changed": 2,
|
||||
"hash": "dd2e8c9",
|
||||
"message": "auto-save 2026-05-13 23:17 (~2)",
|
||||
"ts": "2026-05-13T23:18:31+08:00",
|
||||
"type": "commit"
|
||||
},
|
||||
{
|
||||
"files_changed": 1,
|
||||
"message": "Claude 会话活跃 · 最近命令:claude · 1 项未提交变更 · 最近提交:auto-save 2026-05-13 23:17 (~2)",
|
||||
"ts": "2026-05-13T15:23:08Z",
|
||||
"type": "session-heartbeat"
|
||||
},
|
||||
{
|
||||
"files_changed": 1,
|
||||
"hash": "38091d3",
|
||||
@@ -3251,6 +3238,19 @@
|
||||
"message": "auto-save 2026-05-15 14:33 (~1)",
|
||||
"hash": "8090674",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-15T14:42:29+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-05-15 14:42 (~1)",
|
||||
"hash": "ce04cf4",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-15T06:44:46Z",
|
||||
"type": "session-heartbeat",
|
||||
"message": "Codex 会话活跃 · 最近命令:codex · 5 项未提交变更 · 最近提交:auto-save 2026-05-15 14:42 (~1)",
|
||||
"files_changed": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,16 +2,28 @@
|
||||
"company" : "SKG",
|
||||
"created" : "2026-05-12",
|
||||
"credentials" : [
|
||||
{
|
||||
"description" : "SKG AI 网关 API Key,生产只放服务器 deploy/.env.production 的 LLM_API_KEY,本地开发放 api/.env,不入库",
|
||||
"name" : "LLM_API_KEY",
|
||||
"storage" : "api/.env / deploy/.env.production",
|
||||
"type" : "api_key"
|
||||
},
|
||||
{
|
||||
"description" : "MiniMax T2A 配音 API Key,本地开发只放 api/.env 的 MINIMAX_API_KEY,不入库",
|
||||
"name" : "MINIMAX_API_KEY",
|
||||
"storage" : "api/.env",
|
||||
"type" : "api_key"
|
||||
},
|
||||
{
|
||||
"description" : "SKG 豆包 / Seedance 视频生成 API Key,生产只放服务器 deploy/.env.production 的 VIDEO_API_KEY,本地开发放 api/.env,不入库",
|
||||
"name" : "VIDEO_API_KEY",
|
||||
"storage" : "api/.env / deploy/.env.production",
|
||||
"type" : "api_key"
|
||||
}
|
||||
],
|
||||
"description" : "SKG AI 素材生产管线第二条思路验证:TK 链接 → 拆轨 → 目标化关键帧 + ASR\/翻译 → 接 SKG 产品信息改写口播 → MiniMax 配音 → nano-banana-pro\/GPT Image 生图 → Seedance\/Kling\/Veo3 多模型生视频 → 合成带文案成品",
|
||||
"kind" : "app",
|
||||
"name" : "SKG AI 素材管线 - TK 二创验证",
|
||||
"name" : "SKG Marketing Studio / SKG 营销内容工作台",
|
||||
"ownership" : "company",
|
||||
"pin_order" : 1778664997,
|
||||
"pinned" : true,
|
||||
@@ -32,7 +44,21 @@
|
||||
],
|
||||
"status" : "active",
|
||||
"urls" : [
|
||||
|
||||
{
|
||||
"label" : "production",
|
||||
"type" : "app",
|
||||
"url" : "https://marketing.skg.com"
|
||||
},
|
||||
{
|
||||
"label" : "production-api",
|
||||
"type" : "backend",
|
||||
"url" : "https://marketing.skg.com/api"
|
||||
},
|
||||
{
|
||||
"label" : "source-analysis",
|
||||
"type" : "docs",
|
||||
"url" : "docs/source-analysis.html"
|
||||
}
|
||||
],
|
||||
"worklog" : {
|
||||
"auto" : true,
|
||||
|
||||
22
Dockerfile.api
Normal file
22
Dockerfile.api
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM python:3.12-slim
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PIP_NO_CACHE_DIR=1 \
|
||||
JOBS_DIR=/data/jobs
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends ffmpeg ca-certificates curl \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY api/requirements.txt /app/requirements.txt
|
||||
RUN pip install --no-cache-dir -r /app/requirements.txt
|
||||
|
||||
COPY api /app
|
||||
RUN mkdir -p /data/jobs
|
||||
|
||||
EXPOSE 4291
|
||||
|
||||
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "4291", "--proxy-headers"]
|
||||
22
Dockerfile.web
Normal file
22
Dockerfile.web
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM node:22-bookworm-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable && corepack prepare pnpm@10.28.2 --activate
|
||||
|
||||
COPY web/package.json web/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
COPY web ./
|
||||
|
||||
ARG NEXT_PUBLIC_API_BASE=/api
|
||||
ENV NEXT_PUBLIC_API_BASE=${NEXT_PUBLIC_API_BASE}
|
||||
|
||||
RUN pnpm build
|
||||
|
||||
FROM nginx:1.27-alpine
|
||||
|
||||
COPY deploy/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=builder /app/out /usr/share/nginx/html
|
||||
|
||||
EXPOSE 80
|
||||
15
RULES.md
15
RULES.md
@@ -13,12 +13,16 @@
|
||||
- 第一冲刺:步骤 1-4(下载 / 拆轨 / 关键帧 / ASR+翻译)
|
||||
|
||||
## 部署事实
|
||||
- 平台:待定
|
||||
- 发布状态:未部署
|
||||
- 主站 / 前端:待定
|
||||
- API / 后端:待定
|
||||
- 文档 / 解析:待定
|
||||
- 平台:VPS `76.13.31.179`(Ubuntu 24.04 / Docker Compose / Coolify Traefik)
|
||||
- 发布状态:生产部署配置已生成;公司域名 `marketing.skg.com` 已解析到 VPS,待执行 Compose 上线和 HTTPS 验证
|
||||
- 主站 / 前端:`https://marketing.skg.com`
|
||||
- API / 后端:`https://marketing.skg.com/api`
|
||||
- 文档 / 解析:`docs/source-analysis.html`(项目内独立文档,不公开挂主应用路由)
|
||||
- 管理后台:待定
|
||||
- 服务器目录:`/opt/skg-marketing-studio`
|
||||
- 生产启动:`docker compose -f docker-compose.prod.yml --env-file deploy/.env.production up -d --build`
|
||||
- 生产架构:`web` 容器用 Nginx 承载 Next 静态导出并反代 `/api/`,`api` 容器跑 FastAPI 4291;Traefik 通过 `coolify` 外部网络接入 80/443
|
||||
- 持久化目录:服务器 `./data/jobs` 挂载到后端 `/data/jobs`
|
||||
|
||||
## 快捷登录
|
||||
- 登录地址:待补充
|
||||
@@ -45,6 +49,7 @@
|
||||
- `MINIMAX_TTS_BASE_URL` / `MINIMAX_TTS_MODEL` / `MINIMAX_TTS_VOICE_ID`:MiniMax 配音端点、模型和兜底音色配置
|
||||
- `MINIMAX_TTS_VOICE_POOL`:MiniMax 英文随机音色池;当前默认男声 `English_magnetic_voiced_man`、女声 `English_Upbeat_Woman`、成熟声 `English_MaturePartner`
|
||||
- `POE_API_KEY` / `VIDEO_API_KEY`:视频生成通道 Key,只能放本地环境变量
|
||||
- 生产环境变量:服务器只使用 `deploy/.env.production`,模板为 `deploy/.env.production.example`;真实 Key 不入库
|
||||
|
||||
## 规则
|
||||
- 不允许编造不存在的部署域名、账号、密码
|
||||
|
||||
43
deploy/.env.production.example
Normal file
43
deploy/.env.production.example
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copy this file to deploy/.env.production on the VPS.
|
||||
# Keep real API keys out of git.
|
||||
|
||||
# Runtime
|
||||
JOBS_DIR=/data/jobs
|
||||
KEYFRAME_COUNT=12
|
||||
CORS_ORIGINS=https://marketing.skg.com
|
||||
API_PORT=4291
|
||||
|
||||
# SKG AI gateway, OpenAI-compatible
|
||||
LLM_BASE_URL=https://ai.skg.com/ezlink/v1
|
||||
LLM_API_KEY=
|
||||
|
||||
# Model routing
|
||||
ASR_MODEL=whisper-1
|
||||
ASR_FALLBACK_MODEL=gemini-2.5-flash
|
||||
TRANSLATE_MODEL=gemini-2.5-flash
|
||||
REWRITE_MODEL=gemini-2.5-pro
|
||||
IMAGE_MODEL=gemini-3-pro-image-preview
|
||||
|
||||
# Audio rewrite and MiniMax TTS
|
||||
AUDIO_REWRITE_MODEL=gemini-2.5-pro
|
||||
AUDIO_PRODUCT_BRIEF="SKG smart massage products for daily neck, shoulder, back, eye, knee, and foot relaxation. Keep claims premium, clean, credible, and non-medical."
|
||||
MINIMAX_API_KEY=
|
||||
MINIMAX_TTS_BASE_URL=https://api.minimax.io
|
||||
MINIMAX_TTS_MODEL=speech-2.8-turbo
|
||||
MINIMAX_TTS_VOICE_ID=English_expressive_narrator
|
||||
MINIMAX_TTS_VOICE_POOL=English_magnetic_voiced_man,English_Upbeat_Woman,English_MaturePartner
|
||||
|
||||
# Video generation. Use SKG Doubao / Seedance gateway in production.
|
||||
POE_API_BASE_URL=https://api.poe.com/v1
|
||||
POE_API_KEY=
|
||||
VIDEO_API_BASE_URL=https://ai.skg.com/doubao
|
||||
VIDEO_API_KEY=
|
||||
VIDEO_MODEL=seedance
|
||||
VIDEO_MODEL_SEEDANCE=doubao-seedance-2-0-fast-260128
|
||||
VIDEO_MODEL_KLING=kling-omni
|
||||
VIDEO_MODEL_VEO3=veo-3.1-fast
|
||||
VIDEO_CREATE_PATHS=/api/v3/contents/generations/tasks
|
||||
VIDEO_STATUS_PATH=/api/v3/contents/generations/tasks/{id}
|
||||
VIDEO_CONTENT_PATH=/api/v3/contents/generations/tasks/{id}/content
|
||||
VIDEO_DURATION_FIELD=seconds
|
||||
VIDEO_POLL_TIMEOUT_SECONDS=900
|
||||
32
deploy/nginx.conf
Normal file
32
deploy/nginx.conf
Normal file
@@ -0,0 +1,32 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
client_max_body_size 2g;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript application/xml image/svg+xml;
|
||||
|
||||
location = /api {
|
||||
return 308 /api/;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://api:4291/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_request_buffering off;
|
||||
proxy_buffering off;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_read_timeout 1800s;
|
||||
proxy_send_timeout 1800s;
|
||||
proxy_connect_timeout 60s;
|
||||
}
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
55
docker-compose.prod.yml
Normal file
55
docker-compose.prod.yml
Normal file
@@ -0,0 +1,55 @@
|
||||
name: skg-marketing-studio
|
||||
|
||||
services:
|
||||
api:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.api
|
||||
container_name: skg-marketing-api
|
||||
env_file:
|
||||
- ./deploy/.env.production
|
||||
environment:
|
||||
JOBS_DIR: /data/jobs
|
||||
CORS_ORIGINS: https://marketing.skg.com
|
||||
volumes:
|
||||
- ./data/jobs:/data/jobs
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- skg-marketing-internal
|
||||
|
||||
web:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.web
|
||||
args:
|
||||
NEXT_PUBLIC_API_BASE: /api
|
||||
container_name: skg-marketing-web
|
||||
depends_on:
|
||||
- api
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- skg-marketing-internal
|
||||
- coolify
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.docker.network=coolify"
|
||||
- "traefik.http.middlewares.skg-marketing-gzip.compress=true"
|
||||
- "traefik.http.middlewares.skg-marketing-redirect.redirectscheme.scheme=https"
|
||||
- "traefik.http.routers.skg-marketing-http.entryPoints=http"
|
||||
- "traefik.http.routers.skg-marketing-http.rule=Host(`marketing.skg.com`) && PathPrefix(`/`)"
|
||||
- "traefik.http.routers.skg-marketing-http.middlewares=skg-marketing-redirect"
|
||||
- "traefik.http.routers.skg-marketing-http.service=skg-marketing-http"
|
||||
- "traefik.http.routers.skg-marketing-https.entryPoints=https"
|
||||
- "traefik.http.routers.skg-marketing-https.rule=Host(`marketing.skg.com`) && PathPrefix(`/`)"
|
||||
- "traefik.http.routers.skg-marketing-https.middlewares=skg-marketing-gzip"
|
||||
- "traefik.http.routers.skg-marketing-https.tls=true"
|
||||
- "traefik.http.routers.skg-marketing-https.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.routers.skg-marketing-https.service=skg-marketing-https"
|
||||
- "traefik.http.services.skg-marketing-http.loadbalancer.server.port=80"
|
||||
- "traefik.http.services.skg-marketing-https.loadbalancer.server.port=80"
|
||||
|
||||
networks:
|
||||
skg-marketing-internal:
|
||||
name: skg-marketing-internal
|
||||
coolify:
|
||||
external: true
|
||||
63
docs/deploy-vps.md
Normal file
63
docs/deploy-vps.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# SKG Marketing Studio VPS Deployment
|
||||
|
||||
Production domain:
|
||||
|
||||
- App: `https://marketing.skg.com`
|
||||
- API: `https://marketing.skg.com/api`
|
||||
|
||||
Current VPS target:
|
||||
|
||||
- Host: `76.13.31.179`
|
||||
- OS: Ubuntu 24.04
|
||||
- Runtime: Docker Compose
|
||||
- Public ingress: existing Coolify Traefik on ports 80/443
|
||||
|
||||
DNS:
|
||||
|
||||
```text
|
||||
marketing.skg.com A 76.13.31.179
|
||||
```
|
||||
|
||||
Do not run a host Nginx on ports 80/443. Those ports are already owned by Coolify / Traefik. This project publishes through Docker labels on the external `coolify` network.
|
||||
|
||||
## First Deploy
|
||||
|
||||
On the VPS:
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/skg-marketing-studio
|
||||
cd /opt/skg-marketing-studio
|
||||
cp deploy/.env.production.example deploy/.env.production
|
||||
```
|
||||
|
||||
Fill `deploy/.env.production` with the real production keys. Keep this file out of git.
|
||||
|
||||
Then start:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml --env-file deploy/.env.production up -d --build
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
curl -I https://marketing.skg.com
|
||||
curl https://marketing.skg.com/api/health
|
||||
docker compose -f docker-compose.prod.yml ps
|
||||
```
|
||||
|
||||
## Update
|
||||
|
||||
Sync the repo to `/opt/skg-marketing-studio`, then run:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.prod.yml --env-file deploy/.env.production up -d --build
|
||||
```
|
||||
|
||||
## Runtime Notes
|
||||
|
||||
- `web` is a static Next export served by Nginx.
|
||||
- `web` proxies `/api/` to `api:4291`.
|
||||
- `api` is only on the internal project network and stores jobs under `/data/jobs`.
|
||||
- Server-side job files persist in `./data/jobs` on the VPS.
|
||||
- Large uploads are allowed up to `2g` at the Nginx proxy layer.
|
||||
@@ -533,6 +533,16 @@
|
||||
<td><code>./scripts/stop-dev-background.sh</code></td>
|
||||
<td>按 <code>.pids/</code> 里的 PID 停止后台前端 / 后端进程。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>生产站点</td>
|
||||
<td><code>https://marketing.skg.com</code></td>
|
||||
<td>公司域名已解析到 VPS <code>76.13.31.179</code>。线上由既有 Coolify / Traefik 负责 HTTPS 入口,项目 <code>web</code> 容器用 Nginx 承载静态前端并把 <code>/api/</code> 反代到 FastAPI。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>生产部署</td>
|
||||
<td><code>docker compose -f docker-compose.prod.yml --env-file deploy/.env.production up -d --build</code></td>
|
||||
<td>服务器目录为 <code>/opt/skg-marketing-studio</code>;后端任务文件挂载到 <code>./data/jobs</code>,真实 Key 只放服务器 <code>deploy/.env.production</code>。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>前端开发服务</td>
|
||||
<td><code>cd web && pnpm dev</code></td>
|
||||
@@ -929,6 +939,17 @@ SubjectAsset {
|
||||
<h2>变更记录</h2>
|
||||
<p>这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。</p>
|
||||
<div class="changelog">
|
||||
<article class="change">
|
||||
<header>
|
||||
<h3>2026-05-15 · 公司域名生产部署配置</h3>
|
||||
<span class="tag gray">Runtime</span>
|
||||
<span class="tag blue">Deploy</span>
|
||||
</header>
|
||||
<div class="body">
|
||||
<p><strong>改动:</strong>把生产入口确定为 <code>https://marketing.skg.com</code>,DNS 已解析到 VPS <code>76.13.31.179</code>。新增 Docker Compose 生产配置:前端用 Next 静态导出 + Nginx,<code>/api/</code> 反代到 FastAPI;后端任务目录持久化到服务器 <code>./data/jobs</code>;Traefik 通过既有 <code>coolify</code> 外部网络接管 80/443。</p>
|
||||
<p><strong>影响:</strong><code>Dockerfile.web</code>、<code>Dockerfile.api</code>、<code>docker-compose.prod.yml</code>、<code>deploy/nginx.conf</code>、<code>deploy/.env.production.example</code>、<code>docs/deploy-vps.md</code>、<code>.project.json</code>、<code>RULES.md</code>、<code>docs/source-analysis.html</code>。</p>
|
||||
</div>
|
||||
</article>
|
||||
<article class="change">
|
||||
<header>
|
||||
<h3>2026-05-15 · 本地启动改为后台不弹 Terminal</h3>
|
||||
|
||||
Reference in New Issue
Block a user