- Remove all hardcoded credentials and config from Python source code:
- db.py: DB host/user/password/name/port → env vars with connection retry support
- cm_bot_hal.py: prefix, agent_id, agent_password, security_pin → env vars
- cm_bot.py: base_url → env var, fix register_user return values
- cm_web_view.py: hardcoded '13c' prefix → configurable CM_PREFIX_PATTERN
- cm_telegram.py: hardcoded 'Sky533535' pin → env var CM_SECURITY_PIN
- Parameterize docker-compose.yml for multi-deployment on same host:
- Container names use ${CM_DEPLOY_NAME} prefix (e.g. rex-cm-*, siong-cm-*)
- Network name uses ${CM_DEPLOY_NAME}-network
- Web view port configurable via ${CM_WEB_HOST_PORT}
- All service config passed as env vars (not baked into image)
- Add per-deployment env configs:
- envs/rex/.env (port 8001, prefix 13c, DB rex_cm)
- envs/siong/.env (port 8005, prefix 13sa, DB siong_cm)
- .env.example as template for new deployments
- Remove .env from .gitignore (local server, safe to commit)
- Improve telegram bot reliability:
- Add retry logic for polling with exponential backoff
- Add error handlers for Conflict, RetryAfter, NetworkError, TimedOut
- Add /9 command to show chat ID
- Add telegram_notifier.py for alert notifications
- Fix error handling in /2 and /3 command handlers
- Fix db.py cursor cleanup (close cursor before connection in finally blocks)
- Fix docker-compose.override.yml environment syntax (list → mapping)
- Update README with multi-deployment instructions
- Add AGENTS.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
112 lines
3.4 KiB
YAML
112 lines
3.4 KiB
YAML
services:
|
|
# Telegram Bot Service
|
|
telegram-bot:
|
|
image: "${CM_IMAGE_PREFIX:-your-registry/namespace}/cm-telegram:${DOCKER_IMAGE_TAG:-latest}"
|
|
container_name: ${CM_DEPLOY_NAME:-cm}-telegram-bot
|
|
restart: unless-stopped
|
|
environment:
|
|
PYTHONUNBUFFERED: "1"
|
|
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN}
|
|
TELEGRAM_ALERT_CHAT_ID: ${TELEGRAM_ALERT_CHAT_ID:-}
|
|
TELEGRAM_ALERT_BOT_TOKEN: ${TELEGRAM_ALERT_BOT_TOKEN:-}
|
|
CM_PREFIX_PATTERN: ${CM_PREFIX_PATTERN}
|
|
CM_AGENT_ID: ${CM_AGENT_ID}
|
|
CM_AGENT_PASSWORD: ${CM_AGENT_PASSWORD}
|
|
CM_SECURITY_PIN: ${CM_SECURITY_PIN}
|
|
CM_BOT_BASE_URL: ${CM_BOT_BASE_URL}
|
|
DB_HOST: ${DB_HOST}
|
|
DB_USER: ${DB_USER}
|
|
DB_PASSWORD: ${DB_PASSWORD}
|
|
DB_NAME: ${DB_NAME}
|
|
DB_PORT: ${DB_PORT}
|
|
DB_CONNECTION_TIMEOUT: ${DB_CONNECTION_TIMEOUT}
|
|
DB_CONNECT_RETRIES: ${DB_CONNECT_RETRIES}
|
|
DB_CONNECT_RETRY_DELAY: ${DB_CONNECT_RETRY_DELAY}
|
|
volumes:
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
networks:
|
|
- bot-network
|
|
depends_on:
|
|
- api-server
|
|
|
|
# API Server Service
|
|
api-server:
|
|
image: "${CM_IMAGE_PREFIX:-your-registry/namespace}/cm-api:${DOCKER_IMAGE_TAG:-latest}"
|
|
container_name: ${CM_DEPLOY_NAME:-cm}-api-server
|
|
restart: unless-stopped
|
|
ports:
|
|
- "3000"
|
|
environment:
|
|
PYTHONUNBUFFERED: "1"
|
|
DB_HOST: ${DB_HOST}
|
|
DB_USER: ${DB_USER}
|
|
DB_PASSWORD: ${DB_PASSWORD}
|
|
DB_NAME: ${DB_NAME}
|
|
DB_PORT: ${DB_PORT}
|
|
DB_CONNECTION_TIMEOUT: ${DB_CONNECTION_TIMEOUT}
|
|
DB_CONNECT_RETRIES: ${DB_CONNECT_RETRIES}
|
|
DB_CONNECT_RETRY_DELAY: ${DB_CONNECT_RETRY_DELAY}
|
|
volumes:
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
networks:
|
|
- bot-network
|
|
|
|
# Web View Service
|
|
web-view:
|
|
image: "${CM_IMAGE_PREFIX:-your-registry/namespace}/cm-web:${DOCKER_IMAGE_TAG:-latest}"
|
|
container_name: ${CM_DEPLOY_NAME:-cm}-web-view
|
|
restart: unless-stopped
|
|
ports:
|
|
- "${CM_WEB_HOST_PORT:-8001}:8000"
|
|
environment:
|
|
PYTHONUNBUFFERED: "1"
|
|
API_BASE_URL: http://api-server:3000
|
|
CM_PREFIX_PATTERN: ${CM_PREFIX_PATTERN}
|
|
volumes:
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
networks:
|
|
- bot-network
|
|
depends_on:
|
|
- api-server
|
|
|
|
transfer-bot:
|
|
image: "${CM_IMAGE_PREFIX:-your-registry/namespace}/cm-transfer:${DOCKER_IMAGE_TAG:-latest}"
|
|
container_name: ${CM_DEPLOY_NAME:-cm}-transfer-bot
|
|
restart: unless-stopped
|
|
environment:
|
|
PYTHONUNBUFFERED: "1"
|
|
API_BASE_URL: http://api-server:3000
|
|
CM_TRANSFER_MAX_THREADS: "20"
|
|
CM_PREFIX_PATTERN: ${CM_PREFIX_PATTERN}
|
|
CM_AGENT_ID: ${CM_AGENT_ID}
|
|
CM_AGENT_PASSWORD: ${CM_AGENT_PASSWORD}
|
|
CM_SECURITY_PIN: ${CM_SECURITY_PIN}
|
|
CM_BOT_BASE_URL: ${CM_BOT_BASE_URL}
|
|
DB_HOST: ${DB_HOST}
|
|
DB_USER: ${DB_USER}
|
|
DB_PASSWORD: ${DB_PASSWORD}
|
|
DB_NAME: ${DB_NAME}
|
|
DB_PORT: ${DB_PORT}
|
|
DB_CONNECTION_TIMEOUT: ${DB_CONNECTION_TIMEOUT}
|
|
DB_CONNECT_RETRIES: ${DB_CONNECT_RETRIES}
|
|
DB_CONNECT_RETRY_DELAY: ${DB_CONNECT_RETRY_DELAY}
|
|
volumes:
|
|
- /etc/timezone:/etc/timezone:ro
|
|
- /etc/localtime:/etc/localtime:ro
|
|
mem_limit: 6g
|
|
cpus: 2
|
|
networks:
|
|
- bot-network
|
|
depends_on:
|
|
- api-server
|
|
- web-view
|
|
|
|
|
|
networks:
|
|
bot-network:
|
|
name: ${CM_DEPLOY_NAME:-cm}-network
|
|
driver: bridge
|