MYVMS v2 · Runbook

Vận hành

Lifecycle, logs, scale, troubleshooting, secret rotation.

Lifecycle

cd /root/MYVMS-v2

# Start / restart toàn bộ
docker compose up -d

# Build lại sau khi sửa code
docker compose build --no-cache core worker recorder
docker compose up -d core worker recorder

# Stop
docker compose down

# Stop + xoá data (cẩn thận)
docker compose down -v

Trạng thái nhanh

docker compose ps
curl -s https://vmsclient.vnso.vn/v2/health/ready | jq
set -a; . ./.env; set +a
JWT=$(python3 scripts/make_jwt.py)
curl -s https://vmsclient.vnso.vn/v2/api/cameras -H "Authorization: Bearer $JWT" | jq 'length'

Logs

docker compose logs -f core
docker compose logs -f --tail 200 worker recorder
docker compose logs --since 1h | grep -iE 'error|warn'

Scale worker

Worker stateless · scale theo số camera (rule of thumb: 1 worker / 30 luồng 5 fps trên CPU 4 core).

docker compose up -d --scale worker=3
Lưu ý: dedupe key dùng redis (SET NX EX 2s mặc định) → an toàn khi scale ngang.

Troubleshooting

Triệu chứngKiểm traHành động
/v2/api/cameras trả 502docker compose ps coreRestart core, xem log: docker compose logs core --tail 100
WebSocket không connectCurl /v2/health/ready; check cấu hình Nginx Upgrade headersReload nginx nginx -t && nginx -s reload
Worker không phát eventKiểm tra AI server: curl 103.9.156.56:8088/healthXem log worker; verify AI_TIMEOUT_S
Recorder không tạo HLSFFmpeg log có lỗi RTSP không?Test RTSP bằng ffprobe; check chmod 755 trên thư mục recordings
HLS 401/403 từ /v2/hls/JWT thiếu scope playback:readTạo token đúng tenant/scope, sau đó gọi lại playlist.

Rotate secrets

# JWT
sed -i "s/^JWT_SECRET=.*/JWT_SECRET=$(openssl rand -hex 32)/" /root/MYVMS-v2/.env
docker compose up -d core

# Postgres password
docker compose exec postgres psql -U vms -d vms -c "ALTER USER vms WITH PASSWORD 'NEW_PW';"
sed -i 's|vms_v2_pw_2026|NEW_PW|' /root/MYVMS-v2/.env
docker compose up -d core worker recorder

Backup & Restore (Postgres)

# Backup
docker compose exec postgres pg_dump -U vms vms | gzip > backup-$(date +%F).sql.gz

# Restore
gunzip -c backup-2026-04-30.sql.gz | docker compose exec -T postgres psql -U vms -d vms