Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/bosens-china_blog.json
T
OpenCode 68a9071cf1 feat: reconcile local master with origin (exa/hot-platform hunters, leaks ledger, latest results)
Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
2026-08-07 12:53:47 +08:00

1 line
23 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "bosens-china/blog", "files": {"apps/blog-server/.env.example": {"c93b26461d32bb4a85ea1744ee9f6bfd4a0a7414": {"t": 1785746730.6179855, "n": 982, "h": "1c36dfd5aa99d7bf", "c": "APP_NAME=\"Blog AI Server\"\nDEBUG=false\n\n# 登录用户限额\nENABLE_AI_RATE_LIMIT=true\nAI_DAILY_LIMIT_PER_USER=10\nCOMMENT_HOURLY_LIMIT_PER_USER=10\nCOMMENT_MODERATION_INTERVAL_SECONDS=3600\n\n# 输入与聊天历史\nMAX_MESSAGE_LENGTH=10000\nMAX_HISTORY_ROUNDS=10\nMAX_COMMENT_LENGTH=2000\n\n# 博客与请求来源\nALLOWED_ORIGINS=[\"http://localhost:4321\",\"http://127.0.0.1:4321\"]\nBLOG_FRONTEND_URL=http://localhost:4321\nBLOG_POSTS_BASE_URL=https://static.example.com/_posts/\nSESSION_COOKIE_SECURE=false\n\n# GitHub OAuth\nGITHUB_CLIENT_ID=\nGITHUB_CLIENT_SECRET=\nGITHUB_OAUTH_CALLBACK_URL=http://localhost:8000/api/auth/github/callback\nBLOG_AUTHOR_GITHUB_ID=\n\n# PostgreSQL 与 Redis\nPOSTGRES_PASSWORD=change-me\nDATABASE_URL=postgresql+asyncpg://blog:change-me@localhost:5543/blog\nREDIS_URL=redis://localhost:6380/0\n\n# 在线 LLM\nLLM_API_KEY=sk-xxxx\nLLM_API_BASE=https://api.deepseek.com\nLLM_API_MODEL=deepseek-v4-flash\nLLM_MAX_CONCURRENCY=200\n\n# Chrome Web Push\nVAPID_PUBLIC_KEY=\nVAPID_PRIVATE_KEY=\nVAPID_SUBJECT=mailto:admin@example.com\n"}, "f07934f70dffd655e9f364a7e6cb70bf5f36ac16": {"t": 1785767358.576812, "n": 982, "h": "1c36dfd5aa99d7bf", "c": "APP_NAME=\"Blog AI Server\"\nDEBUG=false\n\n# 登录用户限额\nENABLE_AI_RATE_LIMIT=true\nAI_DAILY_LIMIT_PER_USER=10\nCOMMENT_HOURLY_LIMIT_PER_USER=10\nCOMMENT_MODERATION_INTERVAL_SECONDS=3600\n\n# 输入与聊天历史\nMAX_MESSAGE_LENGTH=10000\nMAX_HISTORY_ROUNDS=10\nMAX_COMMENT_LENGTH=2000\n\n# 博客与请求来源\nALLOWED_ORIGINS=[\"http://localhost:4321\",\"http://127.0.0.1:4321\"]\nBLOG_FRONTEND_URL=http://localhost:4321\nBLOG_POSTS_BASE_URL=https://static.example.com/_posts/\nSESSION_COOKIE_SECURE=false\n\n# GitHub OAuth\nGITHUB_CLIENT_ID=\nGITHUB_CLIENT_SECRET=\nGITHUB_OAUTH_CALLBACK_URL=http://localhost:8000/api/auth/github/callback\nBLOG_AUTHOR_GITHUB_ID=\n\n# PostgreSQL 与 Redis\nPOSTGRES_PASSWORD=change-me\nDATABASE_URL=postgresql+asyncpg://blog:change-me@localhost:5543/blog\nREDIS_URL=redis://localhost:6380/0\n\n# 在线 LLM\nLLM_API_KEY=sk-xxxx\nLLM_API_BASE=https://api.deepseek.com\nLLM_API_MODEL=deepseek-v4-flash\nLLM_MAX_CONCURRENCY=200\n\n# Chrome Web Push\nVAPID_PUBLIC_KEY=\nVAPID_PRIVATE_KEY=\nVAPID_SUBJECT=mailto:admin@example.com\n"}, "19d8a30957226d5e0476922ba9405c031f816daf": {"t": 1785767360.2613735, "n": 892, "h": "364d72c84cb26bb4", "c": "APP_NAME=\"Blog AI Server\"\n# 生产环境必须为 false:DEBUG=true 会跳过所有 Origin/Referer 来源校验\nDEBUG=false\n\n# ===== 分层限流 =====\n# 生产环境必须为 true\nENABLE_RATE_LIMIT=true\n# 单 IP 每个窗口内的免费提问次数\nRATE_LIMIT_FREE_TIER=5\n# 配额窗口(秒),3600 = 每人每小时 5 次\nRATE_LIMIT_WINDOW=3600\n# 两次提问最小间隔(秒),0 关闭\nRATE_LIMIT_BURST_INTERVAL=3\n# 全站每日提问总上限(兜底 LLM 成本),按预算调整,0 关闭\nGLOBAL_DAILY_CAP=2000\n\n# ===== 输入约束 =====\n# 单条消息最大字符数\nMAX_MESSAGE_LENGTH=10000\n# 注入给 LLM 的最近历史轮数(1 轮 = 用户 + 助手 2 条)\nMAX_HISTORY_ROUNDS=10\n\n# 允许访问的域名,生产环境务必填写具体的博客域名,多个域名用逗号分隔\n# 示例: [\"https://blog.example.com\", \"http://localhost:4321\"]\nALLOWED_ORIGINS=[\"http://localhost:4321\"]\n\nREDIS_URL=\"redis://localhost:6379/0\"\n\n# OSS Data Source (AI 专用)\n# 必须配置,指向 OSS 上存储 posts/{id}.json 的基础路径\n# 请务必以斜杠结尾\nBLOG_POSTS_BASE_URL=\"https://static.your-blog.com/_posts/\"\n\nLLM_API_KEY=\"sk-xxxx\"\nLLM_API_BASE=\"https://api.deepseek.com\"\nLLM_API_MODEL=\"deepseek-chat\"\nLLM_MAX_CONCURRENCY=200\n"}, "00d6d7b52cd673ced30001025d2c7fee85446f60": {"t": 1785767361.4645653, "n": 868, "h": "b1d6c4c98f9285b2", "c": "APP_NAME=\"Blog AI Server\"\n# 生产环境必须为 false:DEBUG=true 会跳过所有 Origin/Referer 来源校验\nDEBUG=false\n\n# ===== 分层限流 =====\n# 生产环境必须为 true\nENABLE_RATE_LIMIT=true\n# 单 IP 每个窗口内的免费提问次数\nRATE_LIMIT_FREE_TIER=5\n# 配额窗口(秒),3600 = 每人每小时 5 次\nRATE_LIMIT_WINDOW=3600\n# 两次提问最小间隔(秒),0 关闭\nRATE_LIMIT_BURST_INTERVAL=3\n# 全站每日提问总上限(兜底 LLM 成本),按预算调整,0 关闭\nGLOBAL_DAILY_CAP=2000\n\n# ===== 输入约束 =====\n# 单条消息最大字符数\nMAX_MESSAGE_LENGTH=10000\n# 注入给 LLM 的最近历史轮数(1 轮 = 用户 + 助手 2 条)\nMAX_HISTORY_ROUNDS=10\n\n# 允许访问的域名,生产环境务必填写具体的博客域名,多个域名用逗号分隔\n# 示例: [\"https://blog.example.com\", \"http://localhost:4321\"]\nALLOWED_ORIGINS=[\"http://localhost:4321\"]\n\nREDIS_URL=\"redis://localhost:6379/0\"\n\n# OSS Data Source (AI 专用)\n# 必须配置,指向 OSS 上存储 posts/{id}.json 的基础路径\n# 请务必以斜杠结尾\nBLOG_POSTS_BASE_URL=\"https://static.your-blog.com/_posts/\"\n\nLLM_API_KEY=\"sk-xxxx\"\nLLM_API_BASE=\"https://api.deepseek.com\"\nLLM_API_MODEL=\"deepseek-chat\"\n"}, "43342d2487bfad3c60ab1a77af6793bbef286211": {"t": 1785767362.7511961, "n": 468, "h": "e194caa5f6127465", "c": "APP_NAME=\"Blog AI Server\"\nDEBUG=true\nENABLE_RATE_LIMIT=false\n\n# 允许访问的域名,生产环境务必填写具体的博客域名,多个域名用逗号分隔\n# 示例: [\"https://blog.example.com\", \"http://localhost:4321\"]\nALLOWED_ORIGINS=[\"http://localhost:4321\"]\n\nREDIS_URL=\"redis://localhost:6379/0\"\n\n# OSS Data Source (AI 专用)\n# 必须配置,指向 OSS 上存储 posts/{id}.json 的基础路径\n# 请务必以斜杠结尾\nBLOG_POSTS_BASE_URL=\"https://static.your-blog.com/_posts/\"\n\nLLM_API_KEY=\"sk-xxxx\"\nLLM_API_BASE=\"https://api.deepseek.com\"\nLLM_API_MODEL=\"deepseek-chat\"\n"}, "6fcb0ac0c0c267ecd5d7e4fd17f84791722b1bed": {"t": 1786067894.8851635, "n": 982, "h": "1c36dfd5aa99d7bf", "c": "APP_NAME=\"Blog AI Server\"\nDEBUG=false\n\n# 登录用户限额\nENABLE_AI_RATE_LIMIT=true\nAI_DAILY_LIMIT_PER_USER=10\nCOMMENT_HOURLY_LIMIT_PER_USER=10\nCOMMENT_MODERATION_INTERVAL_SECONDS=3600\n\n# 输入与聊天历史\nMAX_MESSAGE_LENGTH=10000\nMAX_HISTORY_ROUNDS=10\nMAX_COMMENT_LENGTH=2000\n\n# 博客与请求来源\nALLOWED_ORIGINS=[\"http://localhost:4321\",\"http://127.0.0.1:4321\"]\nBLOG_FRONTEND_URL=http://localhost:4321\nBLOG_POSTS_BASE_URL=https://static.example.com/_posts/\nSESSION_COOKIE_SECURE=false\n\n# GitHub OAuth\nGITHUB_CLIENT_ID=\nGITHUB_CLIENT_SECRET=\nGITHUB_OAUTH_CALLBACK_URL=http://localhost:8000/api/auth/github/callback\nBLOG_AUTHOR_GITHUB_ID=\n\n# PostgreSQL 与 Redis\nPOSTGRES_PASSWORD=change-me\nDATABASE_URL=postgresql+asyncpg://blog:change-me@localhost:5543/blog\nREDIS_URL=redis://localhost:6380/0\n\n# 在线 LLM\nLLM_API_KEY=sk-xxxx\nLLM_API_BASE=https://api.deepseek.com\nLLM_API_MODEL=deepseek-v4-flash\nLLM_MAX_CONCURRENCY=200\n\n# Chrome Web Push\nVAPID_PUBLIC_KEY=\nVAPID_PRIVATE_KEY=\nVAPID_SUBJECT=mailto:admin@example.com\n"}}, "apps/blog-server/docker-compose.yml": {"c93b26461d32bb4a85ea1744ee9f6bfd4a0a7414": {"t": 1785747419.0043972, "n": 2488, "h": "37187abad73ae41a", "c": "services:\n server:\n image: boses/ask-ai:latest\n networks:\n - web_network\n environment:\n - TZ=Asia/Shanghai\n - DEBUG=false\n - ENABLE_AI_RATE_LIMIT=true\n - REDIS_URL=redis://redis:6379/0\n - DATABASE_URL=postgresql+asyncpg://blog:${POSTGRES_PASSWORD}@postgres:5432/blog\n # 下面这些变量会自动读取同级目录下的 .env 文件\n - LLM_API_KEY=${LLM_API_KEY}\n - LLM_API_BASE=${LLM_API_BASE:-https://api.deepseek.com}\n - LLM_API_MODEL=${LLM_API_MODEL:-deepseek-v4-flash}\n - LLM_MAX_CONCURRENCY=${LLM_MAX_CONCURRENCY:-200}\n - AI_DAILY_LIMIT_PER_USER=${AI_DAILY_LIMIT_PER_USER:-10}\n - COMMENT_HOURLY_LIMIT_PER_USER=${COMMENT_HOURLY_LIMIT_PER_USER:-10}\n - COMMENT_MODERATION_INTERVAL_SECONDS=${COMMENT_MODERATION_INTERVAL_SECONDS:-3600}\n - VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}\n - VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}\n - VAPID_SUBJECT=${VAPID_SUBJECT}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}\n - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}\n - GITHUB_OAUTH_CALLBACK_URL=${GITHUB_OAUTH_CALLBACK_URL}\n - BLOG_AUTHOR_GITHUB_ID=${BLOG_AUTHOR_GITHUB_ID}\n - BLOG_FRONTEND_URL=${BLOG_FRONTEND_URL}\n - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}\n labels:\n caddy: ask-ai.xiaowo.live\n caddy.reverse_proxy: '{{upstreams 8000}}'\n # 用 Caddy 看到的真实对端 IP 覆写 X-Real-IP,限流据此识别客户端。\n # 服务无对外端口、仅内网可达,客户端无法伪造此头。\n caddy.reverse_proxy.header_up: 'X-Real-IP {remote_host}'\n depends_on:\n redis:\n condition: service_healthy\n postgres:\n condition: service_healthy\n restart: always # 服务器重启后自动拉起\n\n redis:\n image: redis:7.2-alpine\n environment:\n - TZ=Asia/Shanghai\n volumes:\n - redis_data:/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 10s\n timeout: 3s\n retries: 5\n\n postgres:\n image: postgres:17-alpine\n environment:\n - POSTGRES_DB=blog\n - POSTGRES_USER=blog\n - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U blog -d blog']\n interval: 10s\n timeout: 5s\n retries: 5\n\nvolumes:\n redis_data:\n postgres_data:\n\nnetworks:\n web_network:\n external: true\n"}, "f07934f70dffd655e9f364a7e6cb70bf5f36ac16": {"t": 1785767358.2733836, "n": 2488, "h": "37187abad73ae41a", "c": "services:\n server:\n image: boses/ask-ai:latest\n networks:\n - web_network\n environment:\n - TZ=Asia/Shanghai\n - DEBUG=false\n - ENABLE_AI_RATE_LIMIT=true\n - REDIS_URL=redis://redis:6379/0\n - DATABASE_URL=postgresql+asyncpg://blog:${POSTGRES_PASSWORD}@postgres:5432/blog\n # 下面这些变量会自动读取同级目录下的 .env 文件\n - LLM_API_KEY=${LLM_API_KEY}\n - LLM_API_BASE=${LLM_API_BASE:-https://api.deepseek.com}\n - LLM_API_MODEL=${LLM_API_MODEL:-deepseek-v4-flash}\n - LLM_MAX_CONCURRENCY=${LLM_MAX_CONCURRENCY:-200}\n - AI_DAILY_LIMIT_PER_USER=${AI_DAILY_LIMIT_PER_USER:-10}\n - COMMENT_HOURLY_LIMIT_PER_USER=${COMMENT_HOURLY_LIMIT_PER_USER:-10}\n - COMMENT_MODERATION_INTERVAL_SECONDS=${COMMENT_MODERATION_INTERVAL_SECONDS:-3600}\n - VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}\n - VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}\n - VAPID_SUBJECT=${VAPID_SUBJECT}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}\n - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}\n - GITHUB_OAUTH_CALLBACK_URL=${GITHUB_OAUTH_CALLBACK_URL}\n - BLOG_AUTHOR_GITHUB_ID=${BLOG_AUTHOR_GITHUB_ID}\n - BLOG_FRONTEND_URL=${BLOG_FRONTEND_URL}\n - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}\n labels:\n caddy: ask-ai.xiaowo.live\n caddy.reverse_proxy: '{{upstreams 8000}}'\n # 用 Caddy 看到的真实对端 IP 覆写 X-Real-IP,限流据此识别客户端。\n # 服务无对外端口、仅内网可达,客户端无法伪造此头。\n caddy.reverse_proxy.header_up: 'X-Real-IP {remote_host}'\n depends_on:\n redis:\n condition: service_healthy\n postgres:\n condition: service_healthy\n restart: always # 服务器重启后自动拉起\n\n redis:\n image: redis:7.2-alpine\n environment:\n - TZ=Asia/Shanghai\n volumes:\n - redis_data:/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 10s\n timeout: 3s\n retries: 5\n\n postgres:\n image: postgres:17-alpine\n environment:\n - POSTGRES_DB=blog\n - POSTGRES_USER=blog\n - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U blog -d blog']\n interval: 10s\n timeout: 5s\n retries: 5\n\nvolumes:\n redis_data:\n postgres_data:\n\nnetworks:\n web_network:\n external: true\n"}, "19d8a30957226d5e0476922ba9405c031f816daf": {"t": 1785767359.486189, "n": 2268, "h": "83b48cae2d71bbfd", "c": "services:\n server:\n image: boses/ask-ai:latest\n networks:\n - web_network\n environment:\n - TZ=Asia/Shanghai\n - REDIS_URL=redis://redis:6379/0\n - DATABASE_URL=postgresql+asyncpg://blog:${POSTGRES_PASSWORD}@postgres:5432/blog\n # 下面这些变量会自动读取同级目录下的 .env 文件\n - LLM_API_KEY=${LLM_API_KEY}\n - LLM_API_MODEL=${LLM_API_MODEL:-deepseek-v4-flash}\n - LLM_MAX_CONCURRENCY=${LLM_MAX_CONCURRENCY:-200}\n - COMMENT_HOURLY_LIMIT=${COMMENT_HOURLY_LIMIT:-10}\n - COMMENT_MODERATION_INTERVAL_SECONDS=${COMMENT_MODERATION_INTERVAL_SECONDS:-3600}\n - VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}\n - VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}\n - VAPID_SUBJECT=${VAPID_SUBJECT}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}\n - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}\n - GITHUB_CALLBACK_URL=${GITHUB_CALLBACK_URL}\n - BLOG_AUTHOR_GITHUB_ID=${BLOG_AUTHOR_GITHUB_ID}\n - FRONTEND_URL=${FRONTEND_URL}\n - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}\n labels:\n caddy: ask-ai.xiaowo.live\n caddy.reverse_proxy: '{{upstreams 8000}}'\n # 用 Caddy 看到的真实对端 IP 覆写 X-Real-IP,限流据此识别客户端。\n # 服务无对外端口、仅内网可达,客户端无法伪造此头。\n caddy.reverse_proxy.header_up: 'X-Real-IP {remote_host}'\n depends_on:\n redis:\n condition: service_healthy\n postgres:\n condition: service_healthy\n restart: always # 服务器重启后自动拉起\n\n redis:\n image: redis:7.2-alpine\n environment:\n - TZ=Asia/Shanghai\n volumes:\n - redis_data:/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 10s\n timeout: 3s\n retries: 5\n\n postgres:\n image: postgres:17-alpine\n environment:\n - POSTGRES_DB=blog\n - POSTGRES_USER=blog\n - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U blog -d blog']\n interval: 10s\n timeout: 5s\n retries: 5\n\nvolumes:\n redis_data:\n postgres_data:\n\nnetworks:\n web_network:\n external: true\n"}, "0f06080ccc10bf897a1d70f8aa5e66deff0ff485": {"t": 1785767360.7744937, "n": 2212, "h": "b9da3047614176f9", "c": "services:\n server:\n image: boses/ask-ai:latest\n networks:\n - web_network\n environment:\n - TZ=Asia/Shanghai\n - REDIS_URL=redis://redis:6379/0\n - DATABASE_URL=postgresql+asyncpg://blog:${POSTGRES_PASSWORD}@postgres:5432/blog\n # 下面这些变量会自动读取同级目录下的 .env 文件\n - LLM_API_KEY=${LLM_API_KEY}\n - LLM_API_MODEL=${LLM_API_MODEL:-deepseek-v4-flash}\n - COMMENT_HOURLY_LIMIT=${COMMENT_HOURLY_LIMIT:-10}\n - COMMENT_MODERATION_INTERVAL_SECONDS=${COMMENT_MODERATION_INTERVAL_SECONDS:-3600}\n - VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}\n - VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}\n - VAPID_SUBJECT=${VAPID_SUBJECT}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}\n - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}\n - GITHUB_CALLBACK_URL=${GITHUB_CALLBACK_URL}\n - BLOG_AUTHOR_GITHUB_ID=${BLOG_AUTHOR_GITHUB_ID}\n - FRONTEND_URL=${FRONTEND_URL}\n - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}\n labels:\n caddy: ask-ai.xiaowo.live\n caddy.reverse_proxy: '{{upstreams 8000}}'\n # 用 Caddy 看到的真实对端 IP 覆写 X-Real-IP,限流据此识别客户端。\n # 服务无对外端口、仅内网可达,客户端无法伪造此头。\n caddy.reverse_proxy.header_up: 'X-Real-IP {remote_host}'\n depends_on:\n redis:\n condition: service_healthy\n postgres:\n condition: service_healthy\n restart: always # 服务器重启后自动拉起\n\n redis:\n image: redis:7.2-alpine\n environment:\n - TZ=Asia/Shanghai\n volumes:\n - redis_data:/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 10s\n timeout: 3s\n retries: 5\n\n postgres:\n image: postgres:17-alpine\n environment:\n - POSTGRES_DB=blog\n - POSTGRES_USER=blog\n - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U blog -d blog']\n interval: 10s\n timeout: 5s\n retries: 5\n\nvolumes:\n redis_data:\n postgres_data:\n\nnetworks:\n web_network:\n external: true\n"}, "00d6d7b52cd673ced30001025d2c7fee85446f60": {"t": 1785767362.0128858, "n": 907, "h": "30b62cbb3e84bcbe", "c": "services:\n server:\n image: boses/ask-ai:latest\n networks:\n - web_network\n environment:\n - TZ=Asia/Shanghai\n - REDIS_URL=redis://redis:6379/0\n # 下面这些变量会自动读取同级目录下的 .env 文件\n - LLM_API_KEY=${LLM_API_KEY}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n labels:\n caddy: ask-ai.xiaowo.live\n caddy.reverse_proxy: '{{upstreams 8000}}'\n # 用 Caddy 看到的真实对端 IP 覆写 X-Real-IP,限流据此识别客户端。\n # 服务无对外端口、仅内网可达,客户端无法伪造此头。\n caddy.reverse_proxy.header_up: 'X-Real-IP {remote_host}'\n depends_on:\n - redis\n restart: always # 服务器重启后自动拉起\n\n redis:\n image: redis:7.2-alpine\n # 不映射端口,仅内部 server 可访问,防止被外部直连\n environment:\n - TZ=Asia/Shanghai\n volumes:\n - redis_data:/data\n networks:\n - web_network\n restart: always\n\nvolumes:\n redis_data:\n\nnetworks:\n web_network:\n external: true\n"}, "d3e87470bb61406141904e0add627e1bc50de617": {"t": 1785767363.353377, "n": 525, "h": "61d2d6fd5d7f2542", "c": "version: '3.8'\n\nservices:\n server:\n image: boses/ask-ai:latest\n ports:\n - '8000:8000'\n environment:\n - REDIS_URL=redis://redis:6379/0\n - LLM_API_KEY=${LLM_API_KEY}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n\n depends_on:\n - redis\n volumes:\n - ./src:/app/src\n restart: on-failure\n\n redis:\n image: redis:7.2-alpine\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n restart: always\n\nvolumes:\n redis_data:\n"}, "43342d2487bfad3c60ab1a77af6793bbef286211": {"t": 1785767364.7419372, "n": 420, "h": "a0e29d27cc54ac8a", "c": "version: '3.8'\n\nservices:\n # server:\n # build: .\n # ports:\n # - \"8000:8000\"\n # environment:\n # - REDIS_URL=redis://redis:6379/0\n # - DEBUG=true\n # depends_on:\n # - redis\n # volumes:\n # - ./src:/app/src\n # restart: on-failure\n\n redis:\n image: redis:7.2-alpine\n ports:\n - '6379:6379'\n volumes:\n - redis_data:/data\n restart: always\n\nvolumes:\n redis_data:\n"}, "6fcb0ac0c0c267ecd5d7e4fd17f84791722b1bed": {"t": 1786068167.2082, "n": 2488, "h": "37187abad73ae41a", "c": "services:\n server:\n image: boses/ask-ai:latest\n networks:\n - web_network\n environment:\n - TZ=Asia/Shanghai\n - DEBUG=false\n - ENABLE_AI_RATE_LIMIT=true\n - REDIS_URL=redis://redis:6379/0\n - DATABASE_URL=postgresql+asyncpg://blog:${POSTGRES_PASSWORD}@postgres:5432/blog\n # 下面这些变量会自动读取同级目录下的 .env 文件\n - LLM_API_KEY=${LLM_API_KEY}\n - LLM_API_BASE=${LLM_API_BASE:-https://api.deepseek.com}\n - LLM_API_MODEL=${LLM_API_MODEL:-deepseek-v4-flash}\n - LLM_MAX_CONCURRENCY=${LLM_MAX_CONCURRENCY:-200}\n - AI_DAILY_LIMIT_PER_USER=${AI_DAILY_LIMIT_PER_USER:-10}\n - COMMENT_HOURLY_LIMIT_PER_USER=${COMMENT_HOURLY_LIMIT_PER_USER:-10}\n - COMMENT_MODERATION_INTERVAL_SECONDS=${COMMENT_MODERATION_INTERVAL_SECONDS:-3600}\n - VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}\n - VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}\n - VAPID_SUBJECT=${VAPID_SUBJECT}\n - ALLOWED_ORIGINS=${ALLOWED_ORIGINS}\n - BLOG_POSTS_BASE_URL=${BLOG_POSTS_BASE_URL}\n - GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}\n - GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}\n - GITHUB_OAUTH_CALLBACK_URL=${GITHUB_OAUTH_CALLBACK_URL}\n - BLOG_AUTHOR_GITHUB_ID=${BLOG_AUTHOR_GITHUB_ID}\n - BLOG_FRONTEND_URL=${BLOG_FRONTEND_URL}\n - SESSION_COOKIE_SECURE=${SESSION_COOKIE_SECURE:-true}\n labels:\n caddy: ask-ai.xiaowo.live\n caddy.reverse_proxy: '{{upstreams 8000}}'\n # 用 Caddy 看到的真实对端 IP 覆写 X-Real-IP,限流据此识别客户端。\n # 服务无对外端口、仅内网可达,客户端无法伪造此头。\n caddy.reverse_proxy.header_up: 'X-Real-IP {remote_host}'\n depends_on:\n redis:\n condition: service_healthy\n postgres:\n condition: service_healthy\n restart: always # 服务器重启后自动拉起\n\n redis:\n image: redis:7.2-alpine\n environment:\n - TZ=Asia/Shanghai\n volumes:\n - redis_data:/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD', 'redis-cli', 'ping']\n interval: 10s\n timeout: 3s\n retries: 5\n\n postgres:\n image: postgres:17-alpine\n environment:\n - POSTGRES_DB=blog\n - POSTGRES_USER=blog\n - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}\n volumes:\n - postgres_data:/var/lib/postgresql/data\n networks:\n - web_network\n restart: always\n healthcheck:\n test: ['CMD-SHELL', 'pg_isready -U blog -d blog']\n interval: 10s\n timeout: 5s\n retries: 5\n\nvolumes:\n redis_data:\n postgres_data:\n\nnetworks:\n web_network:\n external: true\n"}}}}