gpt2api-openai-gateway
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesegpt2api OpenAI Gateway
gpt2api OpenAI 网关
Skill by ara.so — Daily 2026 Skills collection.
gpt2apichatgpt.com/v1/images/generations/v1/images/edits/v1/chat/completions由 ara.so 开发的Skill — 每日2026技能合集。
gpt2apichatgpt.com/v1/images/generations/v1/images/edits/v1/chat/completionsInstallation & Deployment
安装与部署
Docker Compose (Recommended)
Docker Compose(推荐)
bash
git clone https://github.com/432539/gpt2api.git
cd gpt2api/deploy
cp .env.example .envEdit — these three are required:
.envenv
JWT_SECRET=<generate with: openssl rand -base64 48 | tr -d '=/+' | cut -c1-48>
CRYPTO_AES_KEY=<generate with: openssl rand -hex 32>
MYSQL_ROOT_PASSWORD=<strong-password>
MYSQL_PASSWORD=<strong-password>Generate secrets:
bash
undefinedbash
git clone https://github.com/432539/gpt2api.git
cd gpt2api/deploy
cp .env.example .env编辑文件 — 以下三项为必填项:
.envenv
JWT_SECRET=<使用以下命令生成: openssl rand -base64 48 | tr -d '=/+' | cut -c1-48>
CRYPTO_AES_KEY=<使用以下命令生成: openssl rand -hex 32>
MYSQL_ROOT_PASSWORD=<强密码>
MYSQL_PASSWORD=<强密码>生成密钥:
bash
undefinedCRYPTO_AES_KEY (must be exactly 64 hex chars = 32 bytes AES-256)
CRYPTO_AES_KEY(必须恰好64个十六进制字符 = 32字节AES-256)
openssl rand -hex 32
openssl rand -hex 32
JWT_SECRET (>=32 chars)
JWT_SECRET(≥32个字符)
openssl rand -base64 48 | tr -d '=/+' | cut -c1-48
Start services:
```bash
docker compose up -d --build
docker compose logs -f serverOn startup the server automatically:
- Waits for MySQL health check
- Runs database migrations
goose up - Starts HTTP on
:8080
Default admin credentials (change immediately):
- URL:
http://<server-ip>:8080/ - Email:
admin@example.com - Password:
admin123
openssl rand -base64 48 | tr -d '=/+' | cut -c1-48
启动服务:
```bash
docker compose up -d --build
docker compose logs -f server启动时服务器会自动执行以下操作:
- 等待MySQL健康检查通过
- 运行数据库迁移
goose up - 在端口启动HTTP服务
:8080
默认管理员凭据(请立即修改):
- 地址:
http://<服务器IP>:8080/ - 邮箱:
admin@example.com - 密码:
admin123
Configuration
配置
Main config file: (override with env vars in Docker).
configs/config.yamlGPT2API_*yaml
app:
listen: ":8080"
base_url: "https://your-domain.com" # used for signed image proxy URLs
mysql:
dsn: "user:pass@tcp(mysql:3306)/gpt2api?parseTime=true"
max_open_conns: 500
redis:
addr: "redis:6379"
pool_size: 500 # needed for distributed locks & rate limiting
jwt:
secret: "${JWT_SECRET}"
access_ttl_sec: 7200
refresh_ttl_sec: 604800
crypto:
aes_key: "${CRYPTO_AES_KEY}" # 64-char hex, encrypts account AT/cookies
scheduler:
min_interval_sec: 10 # minimum seconds between uses of same account
daily_usage_ratio: 0.8 # daily usage cap ratio before circuit break
cooldown_429_sec: 300 # backoff when upstream returns 429Environment variable override pattern (Docker):
env
GPT2API_APP_BASE_URL=https://api.example.com
GPT2API_SCHEDULER_MIN_INTERVAL_SEC=15
GPT2API_SCHEDULER_COOLDOWN_429_SEC=600主配置文件:(可通过Docker中的环境变量覆盖)。
configs/config.yamlGPT2API_*yaml
app:
listen: ":8080"
base_url: "https://your-domain.com" # 用于生成签名图片代理URL
mysql:
dsn: "user:pass@tcp(mysql:3306)/gpt2api?parseTime=true"
max_open_conns: 500
redis:
addr: "redis:6379"
pool_size: 500 # 分布式锁和速率限制所需
jwt:
secret: "${JWT_SECRET}"
access_ttl_sec: 7200
refresh_ttl_sec: 604800
crypto:
aes_key: "${CRYPTO_AES_KEY}" # 64字符十六进制字符串,用于加密账号AT/cookies
scheduler:
min_interval_sec: 10 # 同一账号两次使用的最小间隔秒数
daily_usage_ratio: 0.8 # 达到每日限额的该比例后触发熔断
cooldown_429_sec: 300 # 上游返回429错误后的冷却时间环境变量覆盖规则(Docker):
env
GPT2API_APP_BASE_URL=https://api.example.com
GPT2API_SCHEDULER_MIN_INTERVAL_SEC=15
GPT2API_SCHEDULER_COOLDOWN_429_SEC=600Quick Start: First Image Generation
快速开始:首次图片生成
1. Add a Proxy
1. 添加代理
Via admin dashboard → Proxy Management → New Proxy, or via API:
bash
curl -X POST http://localhost:8080/api/admin/proxies \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "proxy-us-01",
"url": "http://user:pass@proxy.example.com:8080",
"type": "http"
}'SOCKS5 example:
bash
-d '{"name":"socks-01","url":"socks5://user:pass@proxy.example.com:1080","type":"socks5"}'通过管理控制台 → 代理管理 → 新增代理,或通过API:
bash
curl -X POST http://localhost:8080/api/admin/proxies \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "proxy-us-01",
"url": "http://user:pass@proxy.example.com:8080",
"type": "http"
}'SOCKS5示例:
bash
-d '{"name":"socks-01","url":"socks5://user:pass@proxy.example.com:1080","type":"socks5"}'2. Import ChatGPT Accounts
2. 导入ChatGPT账号
Batch import via admin dashboard → GPT Accounts → Batch Import.
Supported formats — JSON session:
json
[
{
"email": "user@example.com",
"access_token": "$CHATGPT_ACCESS_TOKEN",
"refresh_token": "$CHATGPT_REFRESH_TOKEN",
"proxy_id": 1
}
]Or AT/RT/ST plain text (one per line in the UI).
通过管理控制台 → GPT账号 → 批量导入。
支持的格式 — JSON会话:
json
[
{
"email": "user@example.com",
"access_token": "$CHATGPT_ACCESS_TOKEN",
"refresh_token": "$CHATGPT_REFRESH_TOKEN",
"proxy_id": 1
}
]或AT/RT/ST纯文本(UI中每行一个)。
3. Create an API Key
3. 创建API密钥
Admin dashboard → User Management → select user → API Keys → Create Key.
Or programmatically:
bash
curl -X POST http://localhost:8080/api/user/apikeys \
-H "Authorization: Bearer $USER_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "my-app-key",
"rpm_limit": 60,
"daily_quota": 1000,
"model_whitelist": ["gpt-image-2", "picture_v2"]
}'管理控制台 → 用户管理 → 选择用户 → API密钥 → 创建密钥。
或通过编程方式:
bash
curl -X POST http://localhost:8080/api/user/apikeys \
-H "Authorization: Bearer $USER_JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "my-app-key",
"rpm_limit": 60,
"daily_quota": 1000,
"model_whitelist": ["gpt-image-2", "picture_v2"]
}'4. Generate an Image
4. 生成图片
bash
curl -X POST http://localhost:8080/v1/images/generations \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A serene mountain lake at sunset, photorealistic",
"n": 2,
"size": "1024x1024"
}'Response:
json
{
"created": 1713456789,
"data": [
{
"url": "https://your-domain.com/p/img/task123/0?exp=1713460389&sig=abc123"
},
{
"url": "https://your-domain.com/p/img/task123/1?exp=1713460389&sig=def456"
}
]
}bash
curl -X POST http://localhost:8080/v1/images/generations \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A serene mountain lake at sunset, photorealistic",
"n": 2,
"size": "1024x1024"
}'响应:
json
{
"created": 1713456789,
"data": [
{
"url": "https://your-domain.com/p/img/task123/0?exp=1713460389&sig=abc123"
},
{
"url": "https://your-domain.com/p/img/task123/1?exp=1713460389&sig=def456"
}
]
}API Reference
API参考
Image Generation
图片生成
POST /v1/images/generationsjson
{
"model": "gpt-image-2", // or "picture_v2" for IMG2 grayscale
"prompt": "your prompt",
"n": 1, // number of images (1-4 recommended)
"size": "1024x1024", // "1024x1024" | "1792x1024" | "1024x1792"
"response_format": "url" // "url" | "b64_json"
}POST /v1/images/generationsjson
{
"model": "gpt-image-2", // 或使用"picture_v2"生成IMG2灰度图
"prompt": "your prompt",
"n": 1, // 图片数量(推荐1-4)
"size": "1024x1024", // "1024x1024" | "1792x1024" | "1024x1792"
"response_format": "url" // "url" | "b64_json"
}Image Edit (img2img)
图片编辑(img2img)
POST /v1/images/edits
Content-Type: multipart/form-databash
curl -X POST http://localhost:8080/v1/images/edits \
-H "Authorization: Bearer sk-your-api-key" \
-F "image=@input.png" \
-F "prompt=Make the sky more dramatic" \
-F "model=gpt-image-2" \
-F "n=1"POST /v1/images/edits
Content-Type: multipart/form-databash
curl -X POST http://localhost:8080/v1/images/edits \
-H "Authorization: Bearer sk-your-api-key" \
-F "image=@input.png" \
-F "prompt=Make the sky more dramatic" \
-F "model=gpt-image-2" \
-F "n=1"Check Task Status
检查任务状态
GET /v1/images/tasks/:id
Authorization: Bearer sk-your-api-keyGET /v1/images/tasks/:id
Authorization: Bearer sk-your-api-keyList Models
列出模型
GET /v1/models
Authorization: Bearer sk-your-api-keyGET /v1/models
Authorization: Bearer sk-your-api-keyChat Completions (preserved, UI disabled)
聊天补全(已实现,UI入口禁用)
POST /v1/chat/completionsjson
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}POST /v1/chat/completionsjson
{
"model": "gpt-4o",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}Using with OpenAI SDK
与OpenAI SDK配合使用
Python
Python
python
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["GPT2API_KEY"], # your sk- key from the dashboard
base_url="http://localhost:8080/v1" # or your production domain
)python
from openai import OpenAI
import os
client = OpenAI(
api_key=os.environ["GPT2API_KEY"], # 从控制台获取的sk-密钥
base_url="http://localhost:8080/v1" # 或你的生产域名
)Single image
单张图片
response = client.images.generate(
model="gpt-image-2",
prompt="A futuristic city skyline at night, cyberpunk style",
n=1,
size="1024x1024"
)
print(response.data[0].url)
response = client.images.generate(
model="gpt-image-2",
prompt="A futuristic city skyline at night, cyberpunk style",
n=1,
size="1024x1024"
)
print(response.data[0].url)
Batch images
批量图片
response = client.images.generate(
model="gpt-image-2",
prompt="Abstract watercolor painting, vibrant colors",
n=4,
size="1024x1792" # 9:16 portrait
)
for img in response.data:
print(img.url)
undefinedresponse = client.images.generate(
model="gpt-image-2",
prompt="Abstract watercolor painting, vibrant colors",
n=4,
size="1024x1792" # 9:16竖版
)
for img in response.data:
print(img.url)
undefinedNode.js / TypeScript
Node.js / TypeScript
typescript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.GPT2API_KEY,
baseURL: process.env.GPT2API_BASE_URL ?? "http://localhost:8080/v1",
});
async function generateImages(prompt: string, count: number = 2) {
const response = await client.images.generate({
model: "gpt-image-2",
prompt,
n: count,
size: "1024x1024",
});
return response.data.map((img) => img.url);
}
// Image edit
async function editImage(imagePath: string, prompt: string) {
const fs = await import("fs");
const response = await client.images.edit({
image: fs.createReadStream(imagePath),
prompt,
model: "gpt-image-2",
});
return response.data[0].url;
}typescript
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.GPT2API_KEY,
baseURL: process.env.GPT2API_BASE_URL ?? "http://localhost:8080/v1",
});
async function generateImages(prompt: string, count: number = 2) {
const response = await client.images.generate({
model: "gpt-image-2",
prompt,
n: count,
size: "1024x1024",
});
return response.data.map((img) => img.url);
}
// 图片编辑
async function editImage(imagePath: string, prompt: string) {
const fs = await import("fs");
const response = await client.images.edit({
image: fs.createReadStream(imagePath),
prompt,
model: "gpt-image-2",
});
return response.data[0].url;
}Go
Go
go
package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
cfg := openai.DefaultConfig(os.Getenv("GPT2API_KEY"))
cfg.BaseURL = os.Getenv("GPT2API_BASE_URL") // e.g. "http://localhost:8080/v1"
client := openai.NewClientWithConfig(cfg)
resp, err := client.CreateImage(context.Background(), openai.ImageRequest{
Model: "gpt-image-2",
Prompt: "A tranquil Japanese garden with cherry blossoms",
N: 2,
Size: openai.CreateImageSize1024x1024,
})
if err != nil {
panic(err)
}
for _, img := range resp.Data {
fmt.Println(img.URL)
}
}go
package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
cfg := openai.DefaultConfig(os.Getenv("GPT2API_KEY"))
cfg.BaseURL = os.Getenv("GPT2API_BASE_URL") // 例如 "http://localhost:8080/v1"
client := openai.NewClientWithConfig(cfg)
resp, err := client.CreateImage(context.Background(), openai.ImageRequest{
Model: "gpt-image-2",
Prompt: "A tranquil Japanese garden with cherry blossoms",
N: 2,
Size: openai.CreateImageSize1024x1024,
})
if err != nil {
panic(err)
}
for _, img := range resp.Data {
fmt.Println(img.URL)
}
}Key Concepts
核心概念
IMG2 Grayscale Hit
IMG2灰度图命中
IMG2 is a grayscale (A/B test) feature on that returns multiple high-res final images in a single call. The gateway:
chatgpt.com- Sends the generation request
- Detects in the tool message response
preview_only - Automatically retries up to 3 times within the same conversation to capture IMG2 output
- Returns all signed image URLs aggregated
Use model to specifically target the IMG2 grayscale path:
picture_v2json
{ "model": "picture_v2", "prompt": "...", "n": 1 }Successful IMG2 hit shows in logs:
image runner result summary turns_used=1 is_preview=false signed_count=2IMG2是上的灰度图(A/B测试)功能,单次调用可返回多张高清最终图片。网关的处理流程:
chatgpt.com- 发送生成请求
- 检测工具消息响应中的标记
preview_only - 在同一会话中自动重试最多3次以捕获IMG2输出
- 返回所有聚合后的签名图片URL
使用模型可专门针对IMG2灰度图路径:
picture_v2json
{ "model": "picture_v2", "prompt": "...", "n": 1 }成功命中IMG2会在日志中显示:
image runner result summary turns_used=1 is_preview=false signed_count=2Account Pool Scheduling
账号池调度
The scheduler uses Redis distributed locks to serialize account usage:
- : minimum gap between consecutive uses of the same account
min_interval_sec - : if an account hits this fraction of its daily limit, it's circuit-broken
daily_usage_ratio - : account is cooled down after receiving a 429 from upstream
cooldown_429_sec - Accounts are bound 1:1 to /
oai-device-idfingerprints (stored in DB)oai-session-id
调度器使用Redis分布式锁来序列化账号使用:
- : 同一账号连续使用的最小间隔秒数
min_interval_sec - : 账号使用量达到每日限额的该比例后触发熔断
daily_usage_ratio - : 账号收到上游429错误后的冷却时间
cooldown_429_sec - 账号与/
oai-device-id指纹一对一绑定(存储在数据库中)oai-session-id
Image Proxy & Anti-Hotlink
图片代理与防盗链
All returned image URLs go through the built-in HMAC-signed proxy:
/p/img/:task_id/:index?exp=<unix_timestamp>&sig=<hmac_sha256>This bypasses 's 403 hotlink protection. The proxy fetches and streams the image server-side when accessed.
chatgpt.comestuary/content所有返回的图片URL都经过内置的HMAC签名代理:
/p/img/:task_id/:index?exp=<unix_timestamp>&sig=<hmac_sha256>这绕过了的 403防盗链限制。代理会在访问时从服务器端获取并流式传输图片。
chatgpt.comestuary/contentCredit Billing System
信用计费系统
- Users have a credit wallet; credits are pre-deducted before generation
- Group multipliers allow VIP / internal / reseller pricing tiers
- Billing settled after successful generation; failed calls are refunded
- EPay (易支付) integration for recharge
- 用户拥有信用钱包;生成前预扣除信用
- 分组倍率支持VIP/内部/经销商等不同定价层级
- 生成成功后结算账单;调用失败则退款
- 集成易支付(EPay)用于充值
Admin Operations
管理员操作
Account Pool Management
账号池管理
bash
undefinedbash
undefinedCheck account statuses via API
通过API检查账号状态
curl http://localhost:8080/api/admin/accounts
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
curl http://localhost:8080/api/admin/accounts
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
Manually trigger account token refresh
手动触发账号令牌刷新
curl -X POST http://localhost:8080/api/admin/accounts/123/refresh
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
curl -X POST http://localhost:8080/api/admin/accounts/123/refresh
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
Bulk import accounts (JSON body)
批量导入账号(JSON请求体)
curl -X POST http://localhost:8080/api/admin/accounts/batch
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d @accounts.json
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d @accounts.json
undefinedcurl -X POST http://localhost:8080/api/admin/accounts/batch
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d @accounts.json
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d @accounts.json
undefinedDatabase Backup & Restore
数据库备份与恢复
Via admin dashboard → Data Backup, or:
bash
undefined通过管理控制台 → 数据备份,或使用命令:
bash
undefinedTrigger backup
触发备份
curl -X POST http://localhost:8080/api/admin/backups
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
curl -X POST http://localhost:8080/api/admin/backups
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
List backups
列出备份
curl http://localhost:8080/api/admin/backups
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
curl http://localhost:8080/api/admin/backups
-H "Authorization: Bearer $ADMIN_JWT"
-H "Authorization: Bearer $ADMIN_JWT"
Download backup
下载备份
curl http://localhost:8080/api/admin/backups/backup-2026-04-21.sql.gz
-H "Authorization: Bearer $ADMIN_JWT"
-o backup.sql.gz
-H "Authorization: Bearer $ADMIN_JWT"
-o backup.sql.gz
undefinedcurl http://localhost:8080/api/admin/backups/backup-2026-04-21.sql.gz
-H "Authorization: Bearer $ADMIN_JWT"
-o backup.sql.gz
-H "Authorization: Bearer $ADMIN_JWT"
-o backup.sql.gz
undefinedUser Credit Management
用户信用管理
bash
undefinedbash
undefinedAdd credits to a user
为用户添加信用
curl -X POST http://localhost:8080/api/admin/users/42/credits
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d '{"amount": 10000, "note": "Manual top-up"}'
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d '{"amount": 10000, "note": "Manual top-up"}'
---curl -X POST http://localhost:8080/api/admin/users/42/credits
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d '{"amount": 10000, "note": "Manual top-up"}'
-H "Authorization: Bearer $ADMIN_JWT"
-H "Content-Type: application/json"
-d '{"amount": 10000, "note": "Manual top-up"}'
---Directory Structure
目录结构
gpt2api/
├── cmd/server/ # main entry point
├── configs/
│ ├── config.yaml # main config
│ └── config.example.yaml
├── deploy/
│ ├── docker-compose.yml
│ ├── .env.example
│ └── README.md # horizontal scaling guide
├── internal/
│ ├── api/ # Gin route handlers
│ ├── chatgpt/ # upstream client (utls, sentinel, SSE parser)
│ ├── scheduler/ # account pool scheduler + Redis leases
│ ├── billing/ # credit wallet + EPay integration
│ ├── proxy/ # proxy pool health checks
│ ├── imgproxy/ # HMAC-signed image proxy
│ └── model/ # DB models + migrations (goose)
├── web/ # Vue 3 frontend source
└── docs/screenshots/gpt2api/
├── cmd/server/ # 主入口
├── configs/
│ ├── config.yaml # 主配置文件
│ └── config.example.yaml
├── deploy/
│ ├── docker-compose.yml
│ ├── .env.example
│ └── README.md # 水平扩展指南
├── internal/
│ ├── api/ # Gin路由处理器
│ ├── chatgpt/ # 上游客户端(utls、sentinel、SSE解析器)
│ ├── scheduler/ # 账号池调度器 + Redis租赁
│ ├── billing/ # 信用钱包 + EPay集成
│ ├── proxy/ # 代理池健康检查
│ ├── imgproxy/ # HMAC签名图片代理
│ └── model/ # 数据库模型 + 迁移(goose)
├── web/ # Vue 3前端源码
└── docs/screenshots/Enabling Chat Completions
启用聊天补全
The route is fully implemented but the UI entry is disabled via a feature flag due to upstream sentinel instability. To re-enable:
/v1/chat/completionsgo
// internal/api/routes.go — find the feature flag:
const enableChatCompletions = false // change to trueRebuild and redeploy:
bash
docker compose up -d --build server/v1/chat/completionsgo
// internal/api/routes.go — 找到功能标志:
const enableChatCompletions = false // 修改为true重新构建并部署:
bash
docker compose up -d --build serverTroubleshooting
故障排查
No accounts available / all accounts idle
无可用账号 / 所有账号闲置
bash
undefinedbash
undefinedCheck account pool status
检查账号池状态
docker compose logs server | grep "scheduler"
docker compose logs server | grep "scheduler"
Common causes:
常见原因:
1. min_interval_sec too high — reduce in config
1. min_interval_sec设置过高 — 在配置中降低
2. All accounts in cooldown — check for 429s upstream
2. 所有账号处于冷却状态 — 检查上游是否返回429错误
3. Proxy unhealthy — verify proxy health score in dashboard
3. 代理不健康 — 在控制台中查看代理健康评分
undefinedundefinedImages return 403 when accessed directly
直接访问图片返回403
Expected behavior — all image URLs must go through the proxy. Ensure in config matches your actual domain so signed URLs are correct.
/p/img/base_url预期行为 — 所有图片URL必须通过代理访问。确保配置中的与实际域名一致,以便生成正确的签名URL。
/p/img/base_urlis_preview=true
in logs (IMG2 not hitting)
is_preview=true日志中显示is_preview=true
(未命中IMG2)
is_preview=trueThe account doesn't have IMG2 grayscale enabled. Either:
- Try different accounts (grayscale is account-specific)
- Use model instead of
gpt-image-2picture_v2 - The gateway retries up to 3 times automatically
该账号未启用IMG2灰度图功能。可尝试:
- 使用其他账号(灰度图功能是账号专属的)
- 使用模型而非
gpt-image-2picture_v2 - 网关会自动重试最多3次
Redis lock timeout errors
Redis锁超时错误
yaml
redis:
pool_size: 500 # increase if seeing lock contention under high concurrencyyaml
redis:
pool_size: 500 # 高并发下出现锁竞争时可增大该值Database migration fails on startup
启动时数据库迁移失败
bash
docker compose exec server goose -dir /app/migrations mysql "$DSN" status
docker compose exec server goose -dir /app/migrations mysql "$DSN" upbash
docker compose exec server goose -dir /app/migrations mysql "$DSN" status
docker compose exec server goose -dir /app/migrations mysql "$DSN" upTLS fingerprint / JA3 detection
TLS指纹 / JA3检测
The gateway uses to mimic Edge 143 browser TLS fingerprint. If accounts are getting flagged:
refraction-networking/utls- Ensure each account is bound to a dedicated proxy (avoid IP mixing)
- Check binding is consistent (stored per-account in DB)
oai-device-id - Rotate accounts that have been flagged
网关使用模拟Edge 143浏览器的TLS指纹。如果账号被标记:
refraction-networking/utls- 确保每个账号绑定专属代理(避免IP混用)
- 检查绑定是否一致(存储在数据库的账号记录中)
oai-device-id - 更换已被标记的账号
High memory usage
内存占用过高
Reduce connection pool sizes for smaller deployments:
yaml
mysql:
max_open_conns: 50
redis:
pool_size: 50对于小型部署,可减小连接池大小:
yaml
mysql:
max_open_conns: 50
redis:
pool_size: 50Security Checklist
安全检查清单
- Change default admin password immediately after first login
- Set strong (≥32 chars random)
JWT_SECRET - Set to exactly 64 hex chars
CRYPTO_AES_KEY - Set strong MySQL passwords
- Configure to your HTTPS domain
base_url - Set up nginx reverse proxy with TLS in front of
:8080 - Configure API key IP whitelists for sensitive keys
- Enable audit log review in admin dashboard
- 首次登录后立即修改默认管理员密码
- 设置强(≥32位随机字符)
JWT_SECRET - 设置为恰好64位十六进制字符
CRYPTO_AES_KEY - 设置强MySQL密码
- 将配置为HTTPS域名
base_url - 在前端配置带TLS的nginx反向代理
:8080 - 为敏感API密钥配置IP白名单
- 在管理控制台中启用审计日志查看