omx(team): auto-checkpoint worker-5 [unknown]
This commit is contained in:
@@ -16,6 +16,8 @@ VM_USER="${VM_USER:-azureuser}"
|
|||||||
REMOTE_DIR="${REMOTE_DIR:-/opt/heicode/heicode}"
|
REMOTE_DIR="${REMOTE_DIR:-/opt/heicode/heicode}"
|
||||||
IMAGE_TAG="${IMAGE_TAG:-heicode-manager:local}"
|
IMAGE_TAG="${IMAGE_TAG:-heicode-manager:local}"
|
||||||
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:3000/api/status}"
|
HEALTH_URL="${HEALTH_URL:-http://127.0.0.1:3000/api/status}"
|
||||||
|
COMPOSE_FILES="${COMPOSE_FILES:--f docker-compose.azure-vm.yml -f docker-compose.override.yml}"
|
||||||
|
ENV_FILE="${ENV_FILE:-.env}"
|
||||||
SSH_OPTS="${SSH_OPTS:-}"
|
SSH_OPTS="${SSH_OPTS:-}"
|
||||||
|
|
||||||
if [[ -z "${VM_HOST}" ]]; then
|
if [[ -z "${VM_HOST}" ]]; then
|
||||||
@@ -30,6 +32,8 @@ echo "== Azure VM deploy start =="
|
|||||||
echo "remote=${REMOTE}"
|
echo "remote=${REMOTE}"
|
||||||
echo "dir=${REMOTE_DIR}"
|
echo "dir=${REMOTE_DIR}"
|
||||||
echo "image=${IMAGE_TAG}"
|
echo "image=${IMAGE_TAG}"
|
||||||
|
echo "compose_files=${COMPOSE_FILES}"
|
||||||
|
echo "env_file=${ENV_FILE}"
|
||||||
|
|
||||||
# Persist previous image for rollback.
|
# Persist previous image for rollback.
|
||||||
${SSH} "cd '${REMOTE_DIR}' && \
|
${SSH} "cd '${REMOTE_DIR}' && \
|
||||||
@@ -39,8 +43,8 @@ ${SSH} "cd '${REMOTE_DIR}' && \
|
|||||||
|
|
||||||
# Update compose image tag and redeploy.
|
# Update compose image tag and redeploy.
|
||||||
${SSH} "cd '${REMOTE_DIR}' && \
|
${SSH} "cd '${REMOTE_DIR}' && \
|
||||||
docker compose pull || true && \
|
ENV_FILE='${ENV_FILE}' docker compose ${COMPOSE_FILES} --env-file '${ENV_FILE}' pull heicode || true && \
|
||||||
IMAGE_TAG='${IMAGE_TAG}' docker compose up -d --force-recreate"
|
ENV_FILE='${ENV_FILE}' IMAGE_TAG='${IMAGE_TAG}' docker compose ${COMPOSE_FILES} --env-file '${ENV_FILE}' up -d --build --force-recreate heicode"
|
||||||
|
|
||||||
echo "Waiting for health endpoint..."
|
echo "Waiting for health endpoint..."
|
||||||
for i in {1..20}; do
|
for i in {1..20}; do
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ version: '3.4'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
heicode:
|
heicode:
|
||||||
image: heicode-manager:local
|
image: ${IMAGE_TAG:-heicode-manager:local}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
@@ -36,7 +36,7 @@ services:
|
|||||||
- ${HEICODE_DATA_ROOT}/data:/data
|
- ${HEICODE_DATA_ROOT}/data:/data
|
||||||
- ${HEICODE_DATA_ROOT}/logs:/app/logs
|
- ${HEICODE_DATA_ROOT}/logs:/app/logs
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- ${ENV_FILE:-.env}
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
- ERROR_LOG_ENABLED=true
|
- ERROR_LOG_ENABLED=true
|
||||||
|
|||||||
@@ -10,8 +10,8 @@
|
|||||||
services:
|
services:
|
||||||
heicode:
|
heicode:
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- ${ENV_FILE:-.env}
|
||||||
image: heicode-manager:local
|
image: ${IMAGE_TAG:-heicode-manager:local}
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
# NewAPI / Heicode Manager Rebuild and Deploy Runbook
|
||||||
|
|
||||||
|
Date: 2026-05-03
|
||||||
|
Scope: rebuild and deploy the `heicode` Manager service on an Azure VM while keeping NewAPI as an independent model gateway.
|
||||||
|
Security rule: never put real passwords, tokens, SSH keys, Redis keys, PostgreSQL DSNs, NewAPI keys, or cloud credentials in Git, Markdown, shell history, tickets, or logs. Use environment variables, `.env` on the VM, Secret Store references, or `REDACTED` placeholders only.
|
||||||
|
|
||||||
|
## 1. Current repo deployment surfaces
|
||||||
|
|
||||||
|
| Surface | Purpose | Notes |
|
||||||
|
|---|---|---|
|
||||||
|
| `heicode/Dockerfile` | Production image build | Builds default and classic web assets, then compiles the Go binary. |
|
||||||
|
| `heicode/docker-compose.azure-vm.yml` | Azure VM Manager service | Runs only `heicode`; PostgreSQL and Redis are expected to be managed Azure services. |
|
||||||
|
| `heicode/docker-compose.override.yml` | Local-source image override | Builds `heicode-manager:local` from the checked-out repo. Keep it in the compose file list when deploying this repo state. |
|
||||||
|
| `heicode/bin/azure_vm_deploy.sh` | SSH deployment helper | Uses env vars only; performs remote compose up, health gate, and rollback pointer capture. |
|
||||||
|
| `heicode/bin/acceptance_agnet_local.sh` | Local Agnet control-plane smoke/acceptance probe | Requires an admin session cookie supplied via env; does not store credentials. |
|
||||||
|
| `heicode/.env.example` | Env-var reference | Placeholder-only reference; production `.env` must stay on the VM and out of Git. |
|
||||||
|
|
||||||
|
## 2. Required VM inputs
|
||||||
|
|
||||||
|
Prepare these values outside the repo, for example in a secret manager, CI secret store, or an uncommitted VM-local `.env`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
VM_HOST=<azure-vm-host-or-ip>
|
||||||
|
VM_USER=<ssh-user>
|
||||||
|
REMOTE_DIR=/opt/heicode/heicode
|
||||||
|
HEICODE_DATA_ROOT=/var/lib/heicode/heicode
|
||||||
|
SQL_DSN=postgresql://<user>:REDACTED@<azure-postgres-host>:5432/heicode?sslmode=require
|
||||||
|
REDIS_CONN_STRING=rediss://:REDACTED@<azure-redis-host>:6380
|
||||||
|
SESSION_SECRET=REDACTED
|
||||||
|
HEICODE_AUTH_BASE_URL=https://apimtaiji.azure-api.net/api/mcp
|
||||||
|
HEICODE_ROOT_EMAILS=<comma-separated-admin-emails-if-needed>
|
||||||
|
HEICODE_ADMIN_EMAILS=<comma-separated-admin-emails-if-needed>
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not paste real values into this document, commits, chat, or terminal transcripts that will be saved.
|
||||||
|
|
||||||
|
## 3. Pre-deploy checklist
|
||||||
|
|
||||||
|
Run locally from the repo root unless stated otherwise:
|
||||||
|
|
||||||
|
1. Confirm mainline docs boundary:
|
||||||
|
- `docs/heicode.md`
|
||||||
|
- `docs/plan.md`
|
||||||
|
- `docs/README.md`
|
||||||
|
2. Confirm worktree state:
|
||||||
|
- `git status --short`
|
||||||
|
3. Validate compose syntax without exposing secrets:
|
||||||
|
- `cd heicode`
|
||||||
|
- `cat > /tmp/heicode.deploy.env <<'EOF_ENV'`
|
||||||
|
- `HEICODE_DATA_ROOT=/tmp/heicode-data`
|
||||||
|
- `SQL_DSN=REDACTED`
|
||||||
|
- `REDIS_CONN_STRING=REDACTED`
|
||||||
|
- `SESSION_SECRET=REDACTED`
|
||||||
|
- `EOF_ENV`
|
||||||
|
- `ENV_FILE=/tmp/heicode.deploy.env IMAGE_TAG=heicode-manager:local docker compose -f docker-compose.azure-vm.yml -f docker-compose.override.yml --env-file /tmp/heicode.deploy.env config --quiet`
|
||||||
|
- `rm -f /tmp/heicode.deploy.env`
|
||||||
|
4. Build verification options:
|
||||||
|
- Preferred full image check: `cd heicode && docker compose -f docker-compose.azure-vm.yml -f docker-compose.override.yml build heicode`
|
||||||
|
- Backend slice check when full image build is too slow: `cd heicode && go test -count=1 ./controller ./model ./router`
|
||||||
|
5. Confirm no secrets are staged:
|
||||||
|
- `git diff --cached -- . ':!*.jpg' ':!*.png'`
|
||||||
|
- Search for known real secret fragments only locally; never copy matches into reports.
|
||||||
|
|
||||||
|
## 4. VM preparation checklist
|
||||||
|
|
||||||
|
Run on the Azure VM:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export HEICODE_DATA_ROOT=/var/lib/heicode/heicode
|
||||||
|
sudo mkdir -p "$HEICODE_DATA_ROOT"/data "$HEICODE_DATA_ROOT"/logs
|
||||||
|
sudo chown -R "$USER":"$USER" "$HEICODE_DATA_ROOT"
|
||||||
|
cd /opt/heicode/heicode
|
||||||
|
```
|
||||||
|
|
||||||
|
Create or update VM-local `.env` in `REMOTE_DIR`; keep it untracked:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > .env <<'EOF_ENV'
|
||||||
|
HEICODE_DATA_ROOT=/var/lib/heicode/heicode
|
||||||
|
SQL_DSN=postgresql://<user>:REDACTED@<azure-postgres-host>:5432/heicode?sslmode=require
|
||||||
|
REDIS_CONN_STRING=rediss://:REDACTED@<azure-redis-host>:6380
|
||||||
|
SESSION_SECRET=REDACTED
|
||||||
|
HEICODE_AUTH_BASE_URL=https://apimtaiji.azure-api.net/api/mcp
|
||||||
|
HEICODE_ROOT_EMAILS=
|
||||||
|
HEICODE_ADMIN_EMAILS=
|
||||||
|
EOF_ENV
|
||||||
|
chmod 600 .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace `REDACTED` placeholders through a secure VM-local editor or secret injection mechanism only.
|
||||||
|
|
||||||
|
## 5. Rebuild and deploy procedure
|
||||||
|
|
||||||
|
From the local control machine, after the VM repo has the intended commit:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd heicode
|
||||||
|
VM_HOST=<azure-vm-host-or-ip> \
|
||||||
|
VM_USER=<ssh-user> \
|
||||||
|
REMOTE_DIR=/opt/heicode/heicode \
|
||||||
|
HEALTH_URL=http://127.0.0.1:3000/api/status \
|
||||||
|
./bin/azure_vm_deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
The script will:
|
||||||
|
|
||||||
|
1. SSH to the VM.
|
||||||
|
2. Record the currently running container image in `.last_success_image` when available.
|
||||||
|
3. Run `ENV_FILE=.env docker compose -f docker-compose.azure-vm.yml -f docker-compose.override.yml --env-file .env up -d --build --force-recreate heicode`.
|
||||||
|
4. Poll `/api/status` through the VM-local health URL.
|
||||||
|
5. Update `.last_success_image` only after the health gate passes.
|
||||||
|
|
||||||
|
## 6. Post-deploy verification checklist
|
||||||
|
|
||||||
|
Run on the VM or through secure operator access:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/heicode/heicode
|
||||||
|
ENV_FILE=.env docker compose -f docker-compose.azure-vm.yml -f docker-compose.override.yml --env-file .env ps
|
||||||
|
ENV_FILE=.env docker compose -f docker-compose.azure-vm.yml -f docker-compose.override.yml --env-file .env logs --tail=100 heicode
|
||||||
|
curl -fsS http://127.0.0.1:3000/api/status
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected health response includes `"success":true`.
|
||||||
|
|
||||||
|
Optional Manager / Agnet smoke probe after obtaining a safe admin session cookie without logging it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
AUTH_COOKIE='REDACTED_SESSION_COOKIE' \
|
||||||
|
BASE_URL='http://127.0.0.1:3000' \
|
||||||
|
TENANT_ID='tenant_smoke' \
|
||||||
|
PROJECT_ID='project_smoke' \
|
||||||
|
./bin/acceptance_agnet_local.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not commit or report the real cookie.
|
||||||
|
|
||||||
|
## 7. Rollback checklist
|
||||||
|
|
||||||
|
If the health gate fails or post-deploy checks fail:
|
||||||
|
|
||||||
|
1. Keep the failed container logs for local VM inspection only; redact before sharing.
|
||||||
|
2. Inspect `.last_success_image` on the VM.
|
||||||
|
3. Re-run compose with the last known good image or revert the repo commit, then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ENV_FILE=.env docker compose -f docker-compose.azure-vm.yml --env-file .env up -d --force-recreate heicode
|
||||||
|
curl -fsS http://127.0.0.1:3000/api/status
|
||||||
|
```
|
||||||
|
|
||||||
|
4. If database migrations were applied by the app, do not manually mutate production data without an explicit backup and approval.
|
||||||
|
|
||||||
|
## 8. Known risks / open items
|
||||||
|
|
||||||
|
- `go test ./...` can be blocked by missing embedded frontend build artifacts or pre-existing relay tests; use focused checks for the changed slice and a full Docker image build before production.
|
||||||
|
- Production PostgreSQL and Redis are external managed services; the compose file intentionally does not start local database/cache containers for Azure VM deployment.
|
||||||
|
- NewAPI remains an independent model gateway and should not be exposed as a normal SaaS user backend.
|
||||||
|
- Long-lived secrets must move toward Secret Store / Secret Broker; current VM `.env` usage is an operational bridge, not the final P2 target.
|
||||||
Reference in New Issue
Block a user