End-state: a single web service (Next.js dashboard) per deployment, no
side-by-side Flask UI. The image name 'cm-web' now points at the Next.js
build; the legacy 'cm-web-next' tag is no longer published.
Changes:
- Delete app/cm_web_view.py and the Flask docker/web/Dockerfile.
- Rename docker/web-next/ → docker/web/ (Next.js Dockerfile takes the
cm-web slot).
- docker-compose.yml: drop the web-view service. Rename web-next → web,
container ${CM_DEPLOY_NAME}-web-next → ${CM_DEPLOY_NAME}-web, image
cm-web-next → cm-web, named volume web-next-auth-data → web-auth-data.
transfer-bot's depends_on no longer references web-view (vestigial
startup ordering, never a runtime dependency).
- docker-compose.override.yml: same rename, dockerfile path updated.
- envs: drop CM_WEB_NEXT_HOST_PORT. Repurpose CM_WEB_HOST_PORT for the
Next.js port (8010 dev, 8011 rex, 8012 siong) — same numeric values
formerly held by CM_WEB_NEXT_HOST_PORT, so aaPanel routes don't move.
- scripts/dev.sh: drops web-view + web-next from up/reset-db/logs;
--remove-orphans still cleans up legacy containers from before cutover.
- scripts/publish.sh: drop the cm-web-next build target.
- tests/test_debug_enabled.py: drop app.cm_web_view from the helper
matrix (cm_api is now the only Flask entrypoint with _debug_enabled).
- AGENTS.md / README.md / docs/aapanel-hardening.md: rewrite Flask-era
references; add migration steps for existing stacks; update aaPanel
port references (8000/8001/8005 → 8010/8011/8012).
- .gitignore: add .env, .venv/, .playwright-mcp/, node_modules/, .next/
so 'git add -A' can't accidentally stage secrets or build artifacts.
Operator action required to upgrade an existing deployment:
1. .env: drop CM_WEB_NEXT_HOST_PORT line. Set CM_WEB_HOST_PORT to
what CM_WEB_NEXT_HOST_PORT was. Make sure CM_AUTH_SECRET is set.
2. aaPanel: if proxy_pass pointed at the legacy Flask port
(8000/8001/8005), switch it to the new one (8010/8011/8012).
3. Pull the new cm-web image (Next.js) and redeploy the stack. The
old ${CM_DEPLOY_NAME}-web-view and ${CM_DEPLOY_NAME}-web-next
containers will be replaced by a single ${CM_DEPLOY_NAME}-web.
Verified locally: docker-compose YAML parses; transfer-bot runtime is
unchanged (only depends_on tidied); 38-test python suite passes.
3.9 KiB
3.9 KiB
CM Bot v2 – Portainer Setup (Gitea Registry)
Brief, copy/paste-ready steps to run the published images from gitea.04080616.xyz using Portainer.
What gets deployed
cm-api(port 3000, internal-only),cm-web(Next.js dashboard, container port 3000 → hostCM_WEB_HOST_PORT),cm-telegram,cm-transfer- Container names prefixed with
CM_DEPLOY_NAME(e.g.rex-cm-telegram-bot) - Docker network:
${CM_DEPLOY_NAME}-network(bridge) - Named volume:
${CM_DEPLOY_NAME}-web-auth-datafor/data/auth(passkey JSON store)
Environment configs
Per-deployment templates live in envs/<name>/.env.example (committed). Each operator copies the example to a sibling .env (gitignored — never committed) and fills in the real secrets:
envs/
├── dev/.env.example # Local development tier (port 8010)
├── rex/.env.example # Rex deployment (port 8011)
└── siong/.env.example # Siong deployment (port 8012)
For Portainer-hosted deployments (rex/siong):
cp envs/rex/.env.example envs/rex/.env
# Fill in DB_PASSWORD, CM_AGENT_*, CM_SECURITY_PIN, TELEGRAM_BOT_TOKEN, etc.
# Then load the variables into the Portainer stack environment.
For local development, see the dev tier flow:
cp envs/dev/.env.example .env
bash scripts/dev.sh up
Key variables
| Variable | Description |
|---|---|
CM_DEPLOY_NAME |
Unique prefix for containers/network (e.g. rex-cm, siong-cm) |
CM_WEB_HOST_PORT |
Host port for the Next.js dashboard (unique per deployment; e.g. 8010/8011/8012) |
CM_AUTH_SECRET |
64-hex session signing secret (bash scripts/gen_auth_secret.sh --write) |
TELEGRAM_BOT_TOKEN |
Your Telegram bot token |
DB_HOST / DB_USER / DB_PASSWORD / DB_NAME |
Database connection |
CM_PREFIX_PATTERN |
Username prefix pattern |
CM_AGENT_ID / CM_AGENT_PASSWORD / CM_SECURITY_PIN |
Agent credentials (also used as the dashboard sign-in identity) |
CM_BOT_BASE_URL |
Bot API base URL |
One-time: add the registry in Portainer
- Portainer → Registries → Add registry → Custom.
- Name:
gitea-prod(any) - Registry URL:
gitea.04080616.xyz - Username: your Gitea username; Password: the PAT. Save.
Deploy the stack (fast path)
- Portainer → Stacks → Add stack → Web editor.
- Paste the contents of
docker-compose.ymlfrom this repo (not the override). - Load all variables from the appropriate
envs/<name>/.envinto the stack environment variables. Make sureCM_AUTH_SECRETis present (generate withbash scripts/gen_auth_secret.sh). - Click Deploy the stack. Portainer will pull
cm-<service>:<tag>fromgitea.04080616.xyz/yiekhengand start all four containers.
Migrating an existing pre-B4 stack
The Flask web (port 8000-range) was retired and replaced by the Next.js dashboard. To upgrade:
- In your stack
.env, dropCM_WEB_NEXT_HOST_PORT. SetCM_WEB_HOST_PORTto whatCM_WEB_NEXT_HOST_PORTwas (e.g. 8011/8012). AddCM_AUTH_SECRET=$(openssl rand -hex 32). - Update aaPanel
proxy_passif it pointed to the old Flask port (8001/8005) — switch it to the new one (8011/8012). - Redeploy the stack. The old
${CM_DEPLOY_NAME}-web-viewand${CM_DEPLOY_NAME}-web-nextcontainers go away; a single${CM_DEPLOY_NAME}-webtakes over.
Updating to a new image tag
- Edit the stack → change
DOCKER_IMAGE_TAG→ Update the stack. - Portainer re-pulls and recreates the services with the new tag.
Running multiple deployments on same host
Each deployment needs unique values for:
CM_DEPLOY_NAME– avoids container/network name conflictsCM_WEB_HOST_PORT– avoids port conflicts
Common issues
- Pull denied: PAT missing
read:packageor wrong username/PAT in the registry entry. - Port already allocated: check
CM_WEB_HOST_PORTis unique across deployments. - No port bindings applied: ensure network driver stays
bridge(nothostormacvlan).