Vận hành & backup — deploy, rollback, restore, locking
Đối tượng: sysadmin/SRE trực production. Nguồn chi tiết:
RUNBOOK.mdtrong repo — trang này port nguyên văn §3–§5 + §7 (lệnh đã kiểm chứng).
Deploy (tay — CI cd.yml làm tự động khi push main)
ssh <server>
cd /opt/agentjira
# 1. Compose file + env (CD copy giúp; .env giữ secret, chmod 600)
# /opt/agentjira/docker-compose.prod.yml
# /opt/agentjira/.env chmod 600
# /opt/agentjira/arkon/.env.docker chmod 600
# 2. Không bao giờ ship giá trị ví dụ — fail build nếu còn
node ai-agent-board/scripts/check-placeholder-secrets.cjs
# 3. Pull và chạy
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d --remove-orphans
# 4. Xác minh — đừng tin `up -d`
curl -fsS http://127.0.0.1:8080/api/health
docker compose -f docker-compose.prod.yml ps # tất cả healthy
docker compose -f docker-compose.prod.yml logs --tail=50 agentjira_server | grep -i preflight
Deploy lần đầu — seed owner: fail-closed nên DB mới không có admin nào. Đặt
AGENTBOARD_BOOTSTRAP_OWNERS=lead@example.com trong /opt/agentjira/.env, up -d agentjira_server,
kiểm log [rbac]. Grant idempotent — để nguyên cũng là đường break-glass sau này.
Sau deploy — cấu hình trong Arkon: Arkon lưu API key AI trong database, không phải env.
Đăng nhập arkon_frontend bằng admin và đặt embedding provider + key — không thì semantic search tắt.
Rollback
Image tag theo short SHA — rollback bằng cách ghim tag cũ:
cd /opt/agentjira
docker compose -f docker-compose.prod.yml pull # đảm bảo tag local
# Sửa tag image từ :latest sang :sha-<short> của bản trước
docker compose -f docker-compose.prod.yml up -d
curl -fsS http://127.0.0.1:8080/api/health
Migration chỉ cộng thêm (additive-only) và chạy tự động lúc boot — image cũ chịu được schema mới (cột thừa bị bỏ qua). Rollback không cần down-migration. Nhưng restore dump DB cũ sẽ mất dữ liệu đã ghi từ đó — ưu tiên rollback image và để nguyên database.
Backup & restore — 3 stores độc lập
Cả 3 stores đều phải chụp mới restore nhất quán. Chạy thử restore trên dev (MT-95) trước khi cần thật.
BACKUP=/var/backups/agentjira/$(date +%F-%H%M)
mkdir -p "$BACKUP"
# 1. Board database
docker exec agentjira_db pg_dump -U agentboard -Fc agentboard > "$BACKUP/agentjira.dump"
# 2. Arkon knowledge database (pgvector)
docker exec arkon_postgres pg_dump -U arkon -Fc arkon > "$BACKUP/arkon.dump"
# 3. MinIO objects (wiki attachments/images)
docker run --rm -v arkon_minio_data:/data -v "$BACKUP":/backup alpine \
tar czf /backup/minio.tar.gz -C /data .
# 4. Worktree / repo clone — thường tái tạo được từ remote;
# chỉ chụp khi có Space dùng repo chỉ tồn tại trên host này
docker run --rm -v agentjira_projects:/data -v "$BACKUP":/backup alpine \
tar czf /backup/projects.tar.gz -C /data .
Restore:
docker compose -f docker-compose.prod.yml stop agentjira_server arkon_api arkon_worker arkon_worker_skills
docker exec -i agentjira_db pg_restore -U agentboard -d agentboard --clean < "$BACKUP/agentjira.dump"
docker exec -i arkon_postgres pg_restore -U arkon -d arkon --clean < "$BACKUP/arkon.dump"
docker run --rm -v arkon_minio_data:/data -v "$BACKUP":/backup alpine \
sh -c 'rm -rf /data/* && tar xzf /backup/minio.tar.gz -C /data'
docker compose -f docker-compose.prod.yml up -d
curl -fsS http://127.0.0.1:8080/api/health
Luân chuyển secret
| Secret | Xoay thì sao | Bước thêm bắt buộc |
|---|---|---|
ARKON_ENCRYPTION_KEY | MCP token mã hoá cũ không giải được | Mint lại MCP token các Space |
MCP_TOKEN_PEPPER | Vô hiệu mọi MCP token hiện có | Mint lại toàn bộ; làm trước khi có dữ liệu thật |
SECRET_KEY (Arkon JWT) | Mọi session Arkon văng | User đăng nhập lại |
POSTGRES_PASSWORD | ⚠️ Không đổi password trong volume cũ — app fail kết nối | ALTER USER … WITH PASSWORD trong container đang chạy trước, hoặc tạo lại volume |
MINIO_SECRET_KEY | Đổi root credentials MinIO | Cập nhật client ngoài |
SSO_SHARED_SECRET | Provisioning Space chết tới khi hai phía khớp | Xoay ARKON_SSO_SHARED_SECRET cùng deploy |
REDIS_PASSWORD | Đọc từ env lúc start | Restart Redis + client cùng lúc |
Git locking (withRepoLock) — luật vận hành
- Server serialize thao tác git cùng repo bằng mutex trong-process
withRepoLock(repoPath, fn)— chống race giữa dispatch task song song và merge. - Mutex này không biết terminal của bạn và các instance khác.
git checkout / merge / rebase / commit tay trong repo gốc khi agentđang chạy hoặc merge tự động diễn ra.
Hành vi merge theo chiến lược:
merge-local: checkoutbaseBranchtrongrepoPath→merge --no-ff→ ở lạibaseBranch. Conflict →merge --abortngay, cách ly vàotask.worktreePath(xem Từ chối, rework & xung đột merge).create-pr: push nhánh + tạo PR, không chạm repo local.manual: chỉ đánh dấudone, merge để cho dev/CI.- Rework (≤3 vòng) luôn tái dùng đúng worktree path + branch cũ.