Files
pyrogram-bridge/dockercompose.yml
T
claude code agent 03d1de2954 fix(stability): declare pytest-asyncio, bound /raw_json RPC, assert FloodWait backoff, dedupe gate+timeout (review round 1)
F1 [WARNING] pytest-asyncio was not declared, so the 6 new async stage-1 tests
ERROR on a clean checkout (async def not natively supported) — zero regression
protection, masked by a globally-installed plugin. Added pytest-asyncio to
requirements.txt + asyncio_mode=auto to tests/pytest.ini. Verified on a fresh venv
from requirements alone: the tests collect and run (180 passed).

F2 [WARNING] The /raw_json endpoint's get_messages was the one remaining live RPC
without a timeout, violating the stage-1 DoD ('every Telegram RPC is bounded').
Wrapped it in asyncio.wait_for(..., 30) mirroring PostParser.get_post. (It is not
under the tg_rpc gate, so its blast radius was one request, not the app.)

F3 [WARNING] The worker test globally no-op'd asyncio.sleep, so the dedicated
except FloodWait branch was indistinguishable from the generic handler — deleting
it kept the test green. The sleep stub now records delays and the test asserts the
FloodWait backoff of 6 (=min(1+5,900)), distinct from the success path's 2.

F5 [low] The tricky 'gate outside, timeout inside' nesting was open-coded at 3
sites (each re-deriving the invariant). Extracted tg_rpc_bounded(timeout) into
tg_throttle (using asyncio.timeout()); the 3 sites now use it, so a future call
site cannot silently wrap the gate entry and reopen the hang-under-backpressure.

F4 [low] Documented TG_RPC_TIMEOUT in the dockercompose.yml environment block
next to the other TG_RPC_* knobs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 07:12:10 +03:00

59 lines
2.8 KiB
YAML

volumes:
pyrogram_bridge:
services:
pyrogram_bridge:
image: ghcr.io/vvzvlad/pyrogram-bridge:latest
container_name: pyrogram-bridge
environment:
TG_API_ID: XXX
TG_API_HASH: XXX
# TG_PROXY_HOST: 10.0.0.1 # MTProto proxy host (SOCKS5). Prefer a literal IP over a hostname:
# # a hostname is re-resolved on every reconnect, so flaky DNS during a
# # network blip can wedge Pyrogram's reconnect.
# TG_PROXY_PORT: 1080 # MTProto proxy SOCKS5 port (default: 1080)
# TG_PROXY_USERNAME: XXX # SOCKS5 username (optional)
# TG_PROXY_PASSWORD: XXX # SOCKS5 password (optional)
# TG_WATCHDOG_ENABLED: "True" # Active liveness watchdog: detects 'zombie' sessions and restarts in-process (default: True)
# TG_WATCHDOG_INTERVAL: 60 # Seconds between liveness probes (default: 60)
# TG_WATCHDOG_TIMEOUT: 10 # Seconds to wait for each get_me probe (default: 10)
# TG_WATCHDOG_FAILURES: 3 # Consecutive failed probes before restart (default: 3)
# TG_WATCHDOG_HEARTBEAT_EVERY: 30 # Emit an INFO watchdog heartbeat every N successful probes (default: 30)
# TG_DISCONNECT_FLAP_LIMIT: 3 # Disconnect events within the flap window before an in-process restart (default: 3)
# TG_DISCONNECT_FLAP_WINDOW: 120 # Flap detection window in seconds (default: 120)
# TG_CHAT_CACHE_TTL_HOURS: 12 # TTL for cached channel info (title/username/id); removes GetFullChannel from the poll hot path (default: 12)
# TG_RPC_CONCURRENCY: 1 # Max concurrent live Telegram RPC calls — global throttle (default: 1)
# TG_RPC_MIN_INTERVAL_MS: 500 # Minimum gap between live Telegram RPC starts, ms (default: 500)
# TG_RPC_TIMEOUT: 60 # Max seconds a single live Telegram RPC may run before timing out (default: 60)
PYROGRAM_BRIDGE_URL: https://pgbridge.example.com
API_PORT: 80
TOKEN: ХХХ
TIME_BASED_MERGE: True
SHOW_BRIDGE_LINK: True
SHOW_POST_FLAGS: True
TZ: Europe/Moscow
restart: always
volumes:
- pyrogram_bridge:/app/data
logging:
driver: "json-file"
options:
max-file: 5
max-size: 10m
labels:
traefik.enable: "true"
traefik.http.routers.pgbridge.rule: Host(`pgbridge.example.com`)
traefik.http.services.pgbridge.loadBalancer.server.port: 80
traefik.http.routers.pgbridge.entrypoints: websecure
traefik.http.routers.pgbridge.tls: true
com.centurylinklabs.watchtower.enable: "true"
autoheal: true
healthcheck:
test: ["CMD", "curl", "-s", "-f", "-o", "/dev/null", "http://127.0.0.1:80/rss/vvzvlad_lytdybr?limit=1"]
interval: 30m
timeout: 5s
retries: 2
start_period: 30s
start_interval: 5s