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.
79 lines
3.9 KiB
Markdown
79 lines
3.9 KiB
Markdown
# 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 → host `CM_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-data` for `/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):
|
||
```bash
|
||
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:
|
||
```bash
|
||
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
|
||
1) Portainer → **Registries** → **Add registry** → **Custom**.
|
||
2) Name: `gitea-prod` (any)
|
||
3) Registry URL: `gitea.04080616.xyz`
|
||
4) Username: your Gitea username; Password: the PAT. Save.
|
||
|
||
## Deploy the stack (fast path)
|
||
1) Portainer → **Stacks** → **Add stack** → **Web editor**.
|
||
2) Paste the contents of `docker-compose.yml` from this repo (not the override).
|
||
3) Load all variables from the appropriate `envs/<name>/.env` into the stack environment variables. Make sure `CM_AUTH_SECRET` is present (generate with `bash scripts/gen_auth_secret.sh`).
|
||
4) Click **Deploy the stack**. Portainer will pull `cm-<service>:<tag>` from `gitea.04080616.xyz/yiekheng` and 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:
|
||
1. In your stack `.env`, drop `CM_WEB_NEXT_HOST_PORT`. Set `CM_WEB_HOST_PORT` to what `CM_WEB_NEXT_HOST_PORT` was (e.g. 8011/8012). Add `CM_AUTH_SECRET=$(openssl rand -hex 32)`.
|
||
2. Update aaPanel `proxy_pass` if it pointed to the old Flask port (8001/8005) — switch it to the new one (8011/8012).
|
||
3. Redeploy the stack. The old `${CM_DEPLOY_NAME}-web-view` and `${CM_DEPLOY_NAME}-web-next` containers go away; a single `${CM_DEPLOY_NAME}-web` takes over.
|
||
|
||
## Updating to a new image tag
|
||
1) Edit the stack → change `DOCKER_IMAGE_TAG` → **Update the stack**.
|
||
2) 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 conflicts
|
||
- `CM_WEB_HOST_PORT` – avoids port conflicts
|
||
|
||
## Common issues
|
||
- **Pull denied**: PAT missing `read:package` or wrong username/PAT in the registry entry.
|
||
- **Port already allocated**: check `CM_WEB_HOST_PORT` is unique across deployments.
|
||
- **No port bindings applied**: ensure network driver stays `bridge` (not `host` or `macvlan`).
|