services: tts-api: build: . container_name: tts-api ports: # 本机/局域网直连:http://localhost:8880/index.html - "8880:8880" environment: # 单次合成最大文本长度(字符);留空或删除本行即用后端默认值 100000。 - MAX_TEXT_LENGTH=100000 # 浏览器跨域来源白名单;本地/内网开放使用 *,公网部署建议改成实际域名,多个来源用英文逗号分隔。 - TTS_CORS_ALLOW_ORIGINS=* # Edge 在线音色列表缓存时间(有限非负秒数);0 不跨刷新批次保留,并发刷新仍会合并。 - EDGE_VOICES_CACHE_TTL_SECONDS=86400 # Edge 网络调用总尝试次数;1 表示关闭应用层重试。 - EDGE_RETRY_MAX_ATTEMPTS=2 # Edge 重试基础退避时间(有限非负秒数),后续重试按指数增加;0 表示不等待。 - EDGE_RETRY_BASE_DELAY_SECONDS=0.25 # Edge 音色列表刷新连续失败后的冷却时间(有限非负秒数);0 表示不跨刷新批次冷却。 - EDGE_VOICES_FAILURE_COOLDOWN_SECONDS=5 # Edge 音色列表每次上游请求的超时(有限非负秒数);0 表示关闭。 - EDGE_VOICES_REQUEST_TIMEOUT_SECONDS=5 # 合成超时(秒);预流阶段为总 deadline,流开始后为逐块空闲期限;0 表示关闭。 # 公网/多用户部署建议根据最长允许静默设置为非 0。 - TTS_SYNTHESIS_TIMEOUT_SECONDS=0 # ffmpeg 子进程并发上限;超限显式拒绝请求,避免 CPU/内存被打满。 - TTS_MAX_FFMPEG_PROCESSES=2 # Kokoro 推理并发上限(REST/WS 共用);超限的请求排队等待,避免线程池被占满。 # WS 的 Kokoro 不产生 ffmpeg,此闸门是其唯一并发保护,公网/多用户建议按 CPU 核数调小。 - TTS_MAX_SYNTHESIS_CONCURRENCY=2 # Kokoro 等待队列上限(不含正在推理者);队满时显式拒绝,避免请求无限堆积。 - TTS_MAX_SYNTHESIS_WAITERS=16 # HTTP 请求体上限(字节),同时约束 Content-Length 与 chunked 实际累计大小。 - TTS_MAX_REQUEST_BODY_BYTES=1048576 # 单次 HTTP response body 写入的空闲超时(秒);0 表示关闭慢读保护。 - TTS_RESPONSE_WRITE_TIMEOUT_SECONDS=30 # Kokoro 单次内部推理片段的最大字符数;长单元仍被接受并按序内部切分。 - KOKORO_MAX_UNIT_CHARS=2000 # 对外 API 鉴权密钥:留空 = 完全开放(仅本地/内网直连时用); # 设为非空即对外部程序化客户端(如浏览器扩展)启用鉴权。同源自有页面(/index.html、/api)始终免密。 # 【部署前请务必改成你自己的随机长密钥】,例如 openssl rand -hex 32 生成。 - TTS_API_KEY=change-me-to-a-long-random-secret volumes: - ./models:/app/models # 默认使用 compose 自建网络,无需预先创建任何 external 网络即可 up。 # 若前面挂了 Caddy 等反代,取消下面两行注释,并确保已创建该网络: # docker network create caddy_net # networks: # - caddy_net restart: unless-stopped # 后端内存上限:PyTorch CPU 运行时 + 两个 Kokoro pipeline,峰值约 2~2.5GB,4G 留足余量。 # 注意:浏览器端长文本累积 PCM 的内存增长不受此限制约束(那是客户端的事)。 deploy: resources: limits: memory: 4G reservations: memory: 1G healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8880/')"] interval: 30s timeout: 5s retries: 3 start_period: 60s # 仅在启用上方 caddy_net 注释块时取消本节注释: # networks: # caddy_net: # external: true