# 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//.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//.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-:` 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`).