Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
2d4bbbf4
Commit
2d4bbbf4
authored
Feb 06, 2026
by
yangjianbo
Browse files
feat: 优化codex冷启动, 还有连接池数据库配置信息
parent
ee01f80d
Changes
9
Hide whitespace changes
Inline
Side-by-side
backend/internal/config/config.go
View file @
2d4bbbf4
...
@@ -789,8 +789,8 @@ func setDefaults() {
...
@@ -789,8 +789,8 @@ func setDefaults() {
viper
.
SetDefault
(
"redis.dial_timeout_seconds"
,
5
)
viper
.
SetDefault
(
"redis.dial_timeout_seconds"
,
5
)
viper
.
SetDefault
(
"redis.read_timeout_seconds"
,
3
)
viper
.
SetDefault
(
"redis.read_timeout_seconds"
,
3
)
viper
.
SetDefault
(
"redis.write_timeout_seconds"
,
3
)
viper
.
SetDefault
(
"redis.write_timeout_seconds"
,
3
)
viper
.
SetDefault
(
"redis.pool_size"
,
1
28
)
viper
.
SetDefault
(
"redis.pool_size"
,
1
024
)
viper
.
SetDefault
(
"redis.min_idle_conns"
,
1
0
)
viper
.
SetDefault
(
"redis.min_idle_conns"
,
1
28
)
viper
.
SetDefault
(
"redis.enable_tls"
,
false
)
viper
.
SetDefault
(
"redis.enable_tls"
,
false
)
// Ops (vNext)
// Ops (vNext)
...
@@ -888,7 +888,7 @@ func setDefaults() {
...
@@ -888,7 +888,7 @@ func setDefaults() {
// HTTP 上游连接池配置(针对 5000+ 并发用户优化)
// HTTP 上游连接池配置(针对 5000+ 并发用户优化)
viper
.
SetDefault
(
"gateway.max_idle_conns"
,
240
)
// 最大空闲连接总数(HTTP/2 场景默认)
viper
.
SetDefault
(
"gateway.max_idle_conns"
,
240
)
// 最大空闲连接总数(HTTP/2 场景默认)
viper
.
SetDefault
(
"gateway.max_idle_conns_per_host"
,
120
)
// 每主机最大空闲连接(HTTP/2 场景默认)
viper
.
SetDefault
(
"gateway.max_idle_conns_per_host"
,
120
)
// 每主机最大空闲连接(HTTP/2 场景默认)
viper
.
SetDefault
(
"gateway.max_conns_per_host"
,
2
40
)
// 每主机最大连接数(含活跃
,HTTP/2 场景默认
)
viper
.
SetDefault
(
"gateway.max_conns_per_host"
,
40
96
)
// 每主机最大连接数(含活跃
;流式/HTTP1.1 可调大
)
viper
.
SetDefault
(
"gateway.idle_conn_timeout_seconds"
,
90
)
// 空闲连接超时(秒)
viper
.
SetDefault
(
"gateway.idle_conn_timeout_seconds"
,
90
)
// 空闲连接超时(秒)
viper
.
SetDefault
(
"gateway.max_upstream_clients"
,
5000
)
viper
.
SetDefault
(
"gateway.max_upstream_clients"
,
5000
)
viper
.
SetDefault
(
"gateway.client_idle_ttl_seconds"
,
900
)
viper
.
SetDefault
(
"gateway.client_idle_ttl_seconds"
,
900
)
...
...
backend/internal/service/openai_codex_transform.go
View file @
2d4bbbf4
...
@@ -9,12 +9,29 @@ import (
...
@@ -9,12 +9,29 @@ import (
"os"
"os"
"path/filepath"
"path/filepath"
"strings"
"strings"
"sync"
"time"
"time"
)
)
const
(
const
(
opencodeCodexHeaderURL
=
"https://raw.githubusercontent.com/anomalyco/opencode/dev/packages/opencode/src/session/prompt/codex_header.txt"
opencodeCodexHeaderURL
=
"https://raw.githubusercontent.com/anomalyco/opencode/dev/packages/opencode/src/session/prompt/codex_header.txt"
codexCacheTTL
=
15
*
time
.
Minute
codexCacheTTL
=
15
*
time
.
Minute
// 避免冷启动首请求被外网/ DNS / GitHub 卡死。
// http.DefaultClient 默认无超时,网络异常时可能阻塞很久。
opencodeFetchTimeout
=
3
*
time
.
Second
// 本地缓存为空时,最小回源间隔(防止并发下反复打 GitHub)。
opencodeEmptyCacheRefreshInterval
=
1
*
time
.
Minute
// 防抖:防止短时间内重复触发异步回源。
opencodeFetchDebounce
=
3
*
time
.
Second
)
var
opencodeFetchHTTPClient
=
&
http
.
Client
{
Timeout
:
opencodeFetchTimeout
}
var
(
opencodeFetchMu
sync
.
Mutex
opencodeFetchInFlight
bool
opencodeFetchLastStart
time
.
Time
)
)
//go:embed prompts/codex_cli_instructions.md
//go:embed prompts/codex_cli_instructions.md
...
@@ -230,30 +247,74 @@ func getOpenCodeCachedPrompt(url, cacheFileName, metaFileName string) string {
...
@@ -230,30 +247,74 @@ func getOpenCodeCachedPrompt(url, cacheFileName, metaFileName string) string {
}
}
var
meta
opencodeCacheMetadata
var
meta
opencodeCacheMetadata
if
loadJSON
(
metaFile
,
&
meta
)
&&
meta
.
LastChecked
>
0
&&
cachedContent
!=
""
{
_
=
loadJSON
(
metaFile
,
&
meta
)
if
time
.
Since
(
time
.
UnixMilli
(
meta
.
LastChecked
))
<
codexCacheTTL
{
if
meta
.
LastChecked
>
0
{
return
cachedContent
lastCheckedAt
:=
time
.
UnixMilli
(
meta
.
LastChecked
)
}
if
cachedContent
!=
""
{
}
if
time
.
Since
(
lastCheckedAt
)
<
codexCacheTTL
{
return
cachedContent
content
,
etag
,
status
,
err
:=
fetchWithETag
(
url
,
meta
.
ETag
)
}
if
err
==
nil
&&
status
==
http
.
StatusNotModified
&&
cachedContent
!=
""
{
}
else
{
return
cachedContent
// 没有任何缓存内容时,回源失败也不应影响请求链路;这里做节流,避免并发下反复回源。
}
if
time
.
Since
(
lastCheckedAt
)
<
opencodeEmptyCacheRefreshInterval
{
if
err
==
nil
&&
status
>=
200
&&
status
<
300
&&
content
!=
""
{
return
""
_
=
writeFile
(
cacheFile
,
content
)
}
meta
=
opencodeCacheMetadata
{
ETag
:
etag
,
LastFetch
:
time
.
Now
()
.
UTC
()
.
Format
(
time
.
RFC3339
),
LastChecked
:
time
.
Now
()
.
UnixMilli
(),
}
}
_
=
writeJSON
(
metaFile
,
meta
)
return
content
}
}
// 不在请求链路内同步拉取(GitHub/DNS/网络异常会导致冷启动首请求卡 1 分钟+)。
// 直接返回当前缓存(可为空),并异步刷新缓存。
scheduleOpencodeCacheRefresh
(
url
,
cacheFile
,
metaFile
,
meta
.
ETag
)
return
cachedContent
return
cachedContent
}
}
func
scheduleOpencodeCacheRefresh
(
url
,
cacheFile
,
metaFile
,
etag
string
)
{
opencodeFetchMu
.
Lock
()
if
opencodeFetchInFlight
{
opencodeFetchMu
.
Unlock
()
return
}
if
!
opencodeFetchLastStart
.
IsZero
()
&&
time
.
Since
(
opencodeFetchLastStart
)
<
opencodeFetchDebounce
{
opencodeFetchMu
.
Unlock
()
return
}
opencodeFetchInFlight
=
true
opencodeFetchLastStart
=
time
.
Now
()
opencodeFetchMu
.
Unlock
()
go
func
()
{
defer
func
()
{
opencodeFetchMu
.
Lock
()
opencodeFetchInFlight
=
false
opencodeFetchMu
.
Unlock
()
}()
now
:=
time
.
Now
()
content
,
newETag
,
status
,
err
:=
fetchWithETag
(
url
,
etag
)
var
meta
opencodeCacheMetadata
_
=
loadJSON
(
metaFile
,
&
meta
)
meta
.
LastChecked
=
now
.
UnixMilli
()
switch
{
case
err
==
nil
&&
status
==
http
.
StatusNotModified
:
// 304 表示无需更新缓存文件,只更新检查时间。
if
newETag
!=
""
{
meta
.
ETag
=
newETag
}
_
=
writeJSON
(
metaFile
,
meta
)
case
err
==
nil
&&
status
>=
200
&&
status
<
300
&&
strings
.
TrimSpace
(
content
)
!=
""
:
_
=
writeFile
(
cacheFile
,
content
)
meta
.
ETag
=
newETag
meta
.
LastFetch
=
now
.
UTC
()
.
Format
(
time
.
RFC3339
)
_
=
writeJSON
(
metaFile
,
meta
)
default
:
// 拉取失败也记录检查时间,避免高并发下持续回源。
_
=
writeJSON
(
metaFile
,
meta
)
}
}()
}
func
getOpenCodeCodexHeader
()
string
{
func
getOpenCodeCodexHeader
()
string
{
// 优先从 opencode 仓库缓存获取指令。
// 优先从 opencode 仓库缓存获取指令。
opencodeInstructions
:=
getOpenCodeCachedPrompt
(
opencodeCodexHeaderURL
,
"opencode-codex-header.txt"
,
"opencode-codex-header-meta.json"
)
opencodeInstructions
:=
getOpenCodeCachedPrompt
(
opencodeCodexHeaderURL
,
"opencode-codex-header.txt"
,
"opencode-codex-header-meta.json"
)
...
@@ -598,7 +659,7 @@ func fetchWithETag(url, etag string) (string, string, int, error) {
...
@@ -598,7 +659,7 @@ func fetchWithETag(url, etag string) (string, string, int, error) {
if
etag
!=
""
{
if
etag
!=
""
{
req
.
Header
.
Set
(
"If-None-Match"
,
etag
)
req
.
Header
.
Set
(
"If-None-Match"
,
etag
)
}
}
resp
,
err
:=
http
.
Default
Client
.
Do
(
req
)
resp
,
err
:=
opencodeFetchHTTP
Client
.
Do
(
req
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
""
,
0
,
err
return
""
,
""
,
0
,
err
}
}
...
...
deploy/.env.example
View file @
2d4bbbf4
...
@@ -59,12 +59,59 @@ POSTGRES_USER=sub2api
...
@@ -59,12 +59,59 @@ POSTGRES_USER=sub2api
POSTGRES_PASSWORD=change_this_secure_password
POSTGRES_PASSWORD=change_this_secure_password
POSTGRES_DB=sub2api
POSTGRES_DB=sub2api
# -----------------------------------------------------------------------------
# PostgreSQL 服务端参数(可选;主要用于 deploy/docker-compose-aicodex.yml)
# -----------------------------------------------------------------------------
# POSTGRES_MAX_CONNECTIONS:PostgreSQL 服务端允许的最大连接数。
# 必须 >=(所有 Sub2API 实例的 DATABASE_MAX_OPEN_CONNS 之和)+ 预留余量(例如 20%)。
POSTGRES_MAX_CONNECTIONS=1024
# POSTGRES_SHARED_BUFFERS:PostgreSQL 用于缓存数据页的共享内存。
# 常见建议:物理内存的 10%~25%(容器内存受限时请按实际限制调整)。
POSTGRES_SHARED_BUFFERS=256MB
# POSTGRES_EFFECTIVE_CACHE_SIZE:查询规划器“假设可用的 OS 缓存大小”(不等于实际分配)。
# 常见建议:物理内存的 50%~75%。
POSTGRES_EFFECTIVE_CACHE_SIZE=768MB
# POSTGRES_MAINTENANCE_WORK_MEM:维护操作内存(VACUUM/CREATE INDEX 等)。
# 值越大维护越快,但会占用更多内存。
POSTGRES_MAINTENANCE_WORK_MEM=64MB
# -----------------------------------------------------------------------------
# PostgreSQL 连接池参数(可选,默认与程序内置一致)
# -----------------------------------------------------------------------------
# 说明:
# - 这些参数控制 Sub2API 进程到 PostgreSQL 的连接池大小(不是 PostgreSQL 自身的 max_connections)。
# - 多实例/多副本部署时,总连接上限约等于:实例数 * DATABASE_MAX_OPEN_CONNS。
# - 连接池过大可能导致:数据库连接耗尽、内存占用上升、上下文切换增多,反而变慢。
# - 建议结合 PostgreSQL 的 max_connections 与机器规格逐步调优:
# 通常把应用总连接上限控制在 max_connections 的 50%~80% 更稳妥。
#
# DATABASE_MAX_OPEN_CONNS:最大打开连接数(活跃+空闲),达到后新请求会等待可用连接。
# 典型范围:50~500(取决于 DB 规格、实例数、SQL 复杂度)。
DATABASE_MAX_OPEN_CONNS=50
# DATABASE_MAX_IDLE_CONNS:最大空闲连接数(热连接),建议 <= MAX_OPEN。
# 太小会频繁建连增加延迟;太大会长期占用数据库资源。
DATABASE_MAX_IDLE_CONNS=10
# DATABASE_CONN_MAX_LIFETIME_MINUTES:单个连接最大存活时间。
# 用于避免连接长期不重建导致的中间件/LB/NAT 异常或服务端重启后的“僵尸连接”。
# 设置为 0 表示不限制(一般不建议生产环境)。
DATABASE_CONN_MAX_LIFETIME_MINUTES=30
# DATABASE_CONN_MAX_IDLE_TIME_MINUTES:空闲连接最大存活时间。
# 超过该时间的空闲连接会被回收,防止长时间闲置占用连接数。
# 设置为 0 表示不限制(一般不建议生产环境)。
DATABASE_CONN_MAX_IDLE_TIME_MINUTES=5
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Redis Configuration
# Redis Configuration
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# Leave empty for no password (default for local development)
# Leave empty for no password (default for local development)
REDIS_PASSWORD=
REDIS_PASSWORD=
REDIS_DB=0
REDIS_DB=0
# Redis 服务端最大客户端连接数(可选;主要用于 deploy/docker-compose-aicodex.yml)
REDIS_MAXCLIENTS=50000
# Redis 连接池大小(默认 1024)
REDIS_POOL_SIZE=1024
# Redis 最小空闲连接数(默认 10)
REDIS_MIN_IDLE_CONNS=10
REDIS_ENABLE_TLS=false
REDIS_ENABLE_TLS=false
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
...
@@ -119,6 +166,8 @@ RATE_LIMIT_OVERLOAD_COOLDOWN_MINUTES=10
...
@@ -119,6 +166,8 @@ RATE_LIMIT_OVERLOAD_COOLDOWN_MINUTES=10
# Gateway Scheduling (Optional)
# Gateway Scheduling (Optional)
# 调度缓存与受控回源配置(缓存就绪且命中时不读 DB)
# 调度缓存与受控回源配置(缓存就绪且命中时不读 DB)
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------
# 上游连接池:每主机最大连接数(默认 1024;流式/HTTP1.1 可调大)
GATEWAY_MAX_CONNS_PER_HOST=4096
# 粘性会话最大排队长度
# 粘性会话最大排队长度
GATEWAY_SCHEDULING_STICKY_SESSION_MAX_WAITING=3
GATEWAY_SCHEDULING_STICKY_SESSION_MAX_WAITING=3
# 粘性会话等待超时(时间段,例如 45s)
# 粘性会话等待超时(时间段,例如 45s)
...
...
deploy/config.example.yaml
View file @
2d4bbbf4
...
@@ -161,7 +161,7 @@ gateway:
...
@@ -161,7 +161,7 @@ gateway:
max_idle_conns_per_host
:
120
max_idle_conns_per_host
:
120
# Max connections per host
# Max connections per host
# 每个主机的最大连接数
# 每个主机的最大连接数
max_conns_per_host
:
2
40
max_conns_per_host
:
40
96
# Idle connection timeout (seconds)
# Idle connection timeout (seconds)
# 空闲连接超时时间(秒)
# 空闲连接超时时间(秒)
idle_conn_timeout_seconds
:
90
idle_conn_timeout_seconds
:
90
...
@@ -384,6 +384,18 @@ database:
...
@@ -384,6 +384,18 @@ database:
# SSL mode: disable, require, verify-ca, verify-full
# SSL mode: disable, require, verify-ca, verify-full
# SSL 模式:disable(禁用), require(要求), verify-ca(验证CA), verify-full(完全验证)
# SSL 模式:disable(禁用), require(要求), verify-ca(验证CA), verify-full(完全验证)
sslmode
:
"
disable"
sslmode
:
"
disable"
# Max open connections
# 最大打开连接数
max_open_conns
:
50
# Max idle connections
# 最大空闲连接数
max_idle_conns
:
10
# Connection max lifetime (minutes)
# 连接最大存活时间(分钟)
conn_max_lifetime_minutes
:
30
# Connection max idle time (minutes)
# 空闲连接最大存活时间(分钟)
conn_max_idle_time_minutes
:
5
# =============================================================================
# =============================================================================
# Redis Configuration
# Redis Configuration
...
@@ -402,6 +414,12 @@ redis:
...
@@ -402,6 +414,12 @@ redis:
# Database number (0-15)
# Database number (0-15)
# 数据库编号(0-15)
# 数据库编号(0-15)
db
:
0
db
:
0
# Connection pool size (max concurrent connections)
# 连接池大小(最大并发连接数)
pool_size
:
1024
# Minimum number of idle connections
# 最小空闲连接数
min_idle_conns
:
10
# Enable TLS/SSL connection
# Enable TLS/SSL connection
# 是否启用 TLS/SSL 连接
# 是否启用 TLS/SSL 连接
enable_tls
:
false
enable_tls
:
false
...
...
deploy/docker-compose-aicodex.yml
0 → 100644
View file @
2d4bbbf4
# =============================================================================
# Sub2API Docker Compose Host Configuration (Local Build)
# =============================================================================
# Quick Start:
# 1. Copy .env.example to .env and configure
# 2. docker-compose -f docker-compose-host.yml up -d --build
# 3. Check logs: docker-compose -f docker-compose-host.yml logs -f sub2api
# 4. Access: http://localhost:8080
#
# This configuration builds the image from source (Dockerfile in project root).
# All configuration is done via environment variables.
# No Setup Wizard needed - the system auto-initializes on first run.
# =============================================================================
services
:
# ===========================================================================
# Sub2API Application
# ===========================================================================
sub2api
:
#image: weishaw/sub2api:latest
image
:
yangjianbo/aicodex2api:latest
build
:
context
:
..
dockerfile
:
Dockerfile
container_name
:
sub2api
restart
:
unless-stopped
network_mode
:
host
ulimits
:
nofile
:
soft
:
800000
hard
:
800000
volumes
:
# Data persistence (config.yaml will be auto-generated here)
-
sub2api_data:/app/data
# Mount custom config.yaml (optional, overrides auto-generated config)
#- ./config.yaml:/app/data/config.yaml:ro
environment
:
# =======================================================================
# Auto Setup (REQUIRED for Docker deployment)
# =======================================================================
-
AUTO_SETUP=true
# =======================================================================
# Server Configuration
# =======================================================================
-
SERVER_HOST=0.0.0.0
-
SERVER_PORT=8080
-
SERVER_MODE=${SERVER_MODE:-release}
-
RUN_MODE=${RUN_MODE:-standard}
# =======================================================================
# Database Configuration (PostgreSQL)
# =======================================================================
# Using host network: point to host/external DB by DATABASE_HOST/DATABASE_PORT
-
DATABASE_HOST=${DATABASE_HOST:-127.0.0.1}
-
DATABASE_PORT=${DATABASE_PORT:-5432}
-
DATABASE_USER=${POSTGRES_USER:-sub2api}
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_SSLMODE=disable
-
DATABASE_MAX_OPEN_CONNS=${DATABASE_MAX_OPEN_CONNS:-50}
-
DATABASE_MAX_IDLE_CONNS=${DATABASE_MAX_IDLE_CONNS:-10}
-
DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
-
DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
# =======================================================================
# Gateway Configuration
# =======================================================================
-
GATEWAY_MAX_CONNS_PER_HOST=${GATEWAY_MAX_CONNS_PER_HOST:-1024}
# =======================================================================
# Redis Configuration
# =======================================================================
# Using host network: point to host/external Redis by REDIS_HOST/REDIS_PORT
-
REDIS_HOST=${REDIS_HOST:-127.0.0.1}
-
REDIS_PORT=${REDIS_PORT:-6379}
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_POOL_SIZE=${REDIS_POOL_SIZE:-1024}
-
REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
# =======================================================================
# Admin Account (auto-created on first run)
# =======================================================================
-
ADMIN_EMAIL=${ADMIN_EMAIL:-admin@sub2api.local}
-
ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
# =======================================================================
# JWT Configuration
# =======================================================================
# Leave empty to auto-generate (recommended)
-
JWT_SECRET=${JWT_SECRET:-}
-
JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24}
# =======================================================================
# TOTP (2FA) Configuration
# =======================================================================
# IMPORTANT: Set a fixed encryption key for TOTP secrets. If left empty,
# a random key will be generated on each startup, causing all existing
# TOTP configurations to become invalid (users won't be able to login
# with 2FA).
# Generate a secure key: openssl rand -hex 32
-
TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY:-}
# =======================================================================
# Timezone Configuration
# This affects ALL time operations in the application:
# - Database timestamps
# - Usage statistics "today" boundary
# - Subscription expiry times
# - Log timestamps
# Common values: Asia/Shanghai, America/New_York, Europe/London, UTC
# =======================================================================
-
TZ=${TZ:-Asia/Shanghai}
# =======================================================================
# Gemini OAuth Configuration (for Gemini accounts)
# =======================================================================
-
GEMINI_OAUTH_CLIENT_ID=${GEMINI_OAUTH_CLIENT_ID:-}
-
GEMINI_OAUTH_CLIENT_SECRET=${GEMINI_OAUTH_CLIENT_SECRET:-}
-
GEMINI_OAUTH_SCOPES=${GEMINI_OAUTH_SCOPES:-}
-
GEMINI_QUOTA_POLICY=${GEMINI_QUOTA_POLICY:-}
# =======================================================================
# Security Configuration (URL Allowlist)
# =======================================================================
# Allow private IP addresses for CRS sync (for internal deployments)
-
SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS=${SECURITY_URL_ALLOWLIST_ALLOW_PRIVATE_HOSTS:-true}
depends_on
:
postgres
:
condition
:
service_healthy
redis
:
condition
:
service_healthy
healthcheck
:
test
:
[
"
CMD"
,
"
curl"
,
"
-f"
,
"
http://localhost:8080/health"
]
interval
:
30s
timeout
:
10s
retries
:
3
start_period
:
30s
# ===========================================================================
# PostgreSQL Database
# ===========================================================================
postgres
:
image
:
postgres:18-alpine
container_name
:
sub2api-postgres
restart
:
unless-stopped
network_mode
:
host
ulimits
:
nofile
:
soft
:
800000
hard
:
800000
volumes
:
-
postgres_data:/var/lib/postgresql/data
environment
:
-
POSTGRES_USER=${POSTGRES_USER:-sub2api}
-
POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
POSTGRES_DB=${POSTGRES_DB:-sub2api}
-
TZ=${TZ:-Asia/Shanghai}
command
:
-
"
postgres"
-
"
-c"
-
"
listen_addresses=127.0.0.1"
# 连接数上限:需要结合应用侧 DATABASE_MAX_OPEN_CONNS 调整。
# 注意:max_connections 过大可能导致内存占用与上下文切换开销显著上升。
-
"
-c"
-
"
max_connections=${POSTGRES_MAX_CONNECTIONS:-1024}"
# 典型内存参数(建议结合机器内存调优;不确定就保持默认或小步调大)。
-
"
-c"
-
"
shared_buffers=${POSTGRES_SHARED_BUFFERS:-1GB}"
-
"
-c"
-
"
effective_cache_size=${POSTGRES_EFFECTIVE_CACHE_SIZE:-4GB}"
-
"
-c"
-
"
maintenance_work_mem=${POSTGRES_MAINTENANCE_WORK_MEM:-128MB}"
healthcheck
:
test
:
[
"
CMD-SHELL"
,
"
pg_isready
-U
${POSTGRES_USER:-sub2api}
-d
${POSTGRES_DB:-sub2api}"
]
interval
:
10s
timeout
:
5s
retries
:
5
start_period
:
10s
# Note: bound to localhost only; not exposed to external network by default.
# ===========================================================================
# Redis Cache
# ===========================================================================
redis
:
image
:
redis:8-alpine
container_name
:
sub2api-redis
restart
:
unless-stopped
network_mode
:
host
ulimits
:
nofile
:
soft
:
100000
hard
:
100000
volumes
:
-
redis_data:/data
command
:
>
redis-server
--bind 127.0.0.1
--maxclients ${REDIS_MAXCLIENTS:-50000}
--save 60 1
--appendonly yes
--appendfsync everysec
${REDIS_PASSWORD:+--requirepass ${REDIS_PASSWORD}}
environment
:
-
TZ=${TZ:-Asia/Shanghai}
# REDISCLI_AUTH is used by redis-cli for authentication (safer than -a flag)
-
REDISCLI_AUTH=${REDIS_PASSWORD:-}
healthcheck
:
test
:
[
"
CMD"
,
"
redis-cli"
,
"
ping"
]
interval
:
10s
timeout
:
5s
retries
:
5
start_period
:
5s
# =============================================================================
# Volumes
# =============================================================================
volumes
:
sub2api_data
:
driver
:
local
postgres_data
:
driver
:
local
redis_data
:
driver
:
local
deploy/docker-compose-test.yml
View file @
2d4bbbf4
...
@@ -57,6 +57,10 @@ services:
...
@@ -57,6 +57,10 @@ services:
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_SSLMODE=disable
-
DATABASE_SSLMODE=disable
-
DATABASE_MAX_OPEN_CONNS=${DATABASE_MAX_OPEN_CONNS:-50}
-
DATABASE_MAX_IDLE_CONNS=${DATABASE_MAX_IDLE_CONNS:-10}
-
DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
-
DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
# =======================================================================
# =======================================================================
# Redis Configuration
# Redis Configuration
...
@@ -65,6 +69,8 @@ services:
...
@@ -65,6 +69,8 @@ services:
-
REDIS_PORT=6379
-
REDIS_PORT=6379
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_POOL_SIZE=${REDIS_POOL_SIZE:-1024}
-
REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
# =======================================================================
# =======================================================================
# Admin Account (auto-created on first run)
# Admin Account (auto-created on first run)
...
...
deploy/docker-compose.local.yml
View file @
2d4bbbf4
...
@@ -62,6 +62,10 @@ services:
...
@@ -62,6 +62,10 @@ services:
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_SSLMODE=disable
-
DATABASE_SSLMODE=disable
-
DATABASE_MAX_OPEN_CONNS=${DATABASE_MAX_OPEN_CONNS:-50}
-
DATABASE_MAX_IDLE_CONNS=${DATABASE_MAX_IDLE_CONNS:-10}
-
DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
-
DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
# =======================================================================
# =======================================================================
# Redis Configuration
# Redis Configuration
...
@@ -70,6 +74,8 @@ services:
...
@@ -70,6 +74,8 @@ services:
-
REDIS_PORT=6379
-
REDIS_PORT=6379
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_POOL_SIZE=${REDIS_POOL_SIZE:-1024}
-
REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
# =======================================================================
# =======================================================================
...
...
deploy/docker-compose.standalone.yml
View file @
2d4bbbf4
...
@@ -48,6 +48,10 @@ services:
...
@@ -48,6 +48,10 @@ services:
-
DATABASE_PASSWORD=${DATABASE_PASSWORD:?DATABASE_PASSWORD is required}
-
DATABASE_PASSWORD=${DATABASE_PASSWORD:?DATABASE_PASSWORD is required}
-
DATABASE_DBNAME=${DATABASE_DBNAME:-sub2api}
-
DATABASE_DBNAME=${DATABASE_DBNAME:-sub2api}
-
DATABASE_SSLMODE=${DATABASE_SSLMODE:-disable}
-
DATABASE_SSLMODE=${DATABASE_SSLMODE:-disable}
-
DATABASE_MAX_OPEN_CONNS=${DATABASE_MAX_OPEN_CONNS:-50}
-
DATABASE_MAX_IDLE_CONNS=${DATABASE_MAX_IDLE_CONNS:-10}
-
DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
-
DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
# =======================================================================
# =======================================================================
# Redis Configuration - Required
# Redis Configuration - Required
...
@@ -56,6 +60,8 @@ services:
...
@@ -56,6 +60,8 @@ services:
-
REDIS_PORT=${REDIS_PORT:-6379}
-
REDIS_PORT=${REDIS_PORT:-6379}
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_POOL_SIZE=${REDIS_POOL_SIZE:-1024}
-
REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
# =======================================================================
# =======================================================================
...
...
deploy/docker-compose.yml
View file @
2d4bbbf4
...
@@ -54,6 +54,10 @@ services:
...
@@ -54,6 +54,10 @@ services:
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_DBNAME=${POSTGRES_DB:-sub2api}
-
DATABASE_SSLMODE=disable
-
DATABASE_SSLMODE=disable
-
DATABASE_MAX_OPEN_CONNS=${DATABASE_MAX_OPEN_CONNS:-50}
-
DATABASE_MAX_IDLE_CONNS=${DATABASE_MAX_IDLE_CONNS:-10}
-
DATABASE_CONN_MAX_LIFETIME_MINUTES=${DATABASE_CONN_MAX_LIFETIME_MINUTES:-30}
-
DATABASE_CONN_MAX_IDLE_TIME_MINUTES=${DATABASE_CONN_MAX_IDLE_TIME_MINUTES:-5}
# =======================================================================
# =======================================================================
# Redis Configuration
# Redis Configuration
...
@@ -62,6 +66,8 @@ services:
...
@@ -62,6 +66,8 @@ services:
-
REDIS_PORT=6379
-
REDIS_PORT=6379
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_PASSWORD=${REDIS_PASSWORD:-}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_DB=${REDIS_DB:-0}
-
REDIS_POOL_SIZE=${REDIS_POOL_SIZE:-1024}
-
REDIS_MIN_IDLE_CONNS=${REDIS_MIN_IDLE_CONNS:-10}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
-
REDIS_ENABLE_TLS=${REDIS_ENABLE_TLS:-false}
# =======================================================================
# =======================================================================
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment