Nâng cấp
English: upgrade.md. Nếu hai bản khác nhau, bản tiếng Anh là bản chính.
Áp dụng cho các stack compose: bản quick start (docker-compose.yml ở thư mục
gốc repository) và
compose production. Kubernetes:
docs/deploy/on-premise.md.
Có ba thứ có phiên bản, và mỗi thứ rollback độc lập:
| Thành phần | Ghim bằng | Thay đổi khi nâng cấp | Rollback |
|---|---|---|---|
| Image (gateway, control plane) | GUARDSPEC_VERSION trong .env |
Code | Tag trước đó |
| Schema database | migrations/ của bản checkout; được job migrate áp dụng ở mỗi lần up |
Chỉ tiến lên | Khôi phục bản backup trước khi nâng cấp |
| Model | models/manifest.yaml của mỗi image, hoặc L2_MODEL / L3_MODEL trong .env |
Một release có thể khuyến nghị model mới hơn | L2_MODEL=name@old-version |
Trước 1.0, một phiên bản minor có thể thay đổi schema và cấu hình: hãy đọc CHANGELOG của mọi phiên bản bạn bỏ qua.
Sao lưu
scripts/backup.sh lưu những gì cần để khôi phục, trong khi stack vẫn chạy:
scripts/backup.sh # quick start
scripts/backup.sh -f deploy/compose/production/docker-compose.yml # production
# backup: done: backups/guardspec-20261106T060839Z
| File | Nội dung | Tại sao quan trọng |
|---|---|---|
guardspec.dump |
pg_dump -Fc của database: organization, user, API key (dạng hash), policy, upstream, alert rule, các dòng audit, schema_migrations |
Dữ liệu |
guardspec.env |
File .env mà stack đã chạy cùng |
POSTGRES_PASSWORD và GUARDSPEC_APP_PASSWORD; JWT_SECRET (thiếu nó mọi phiên đăng nhập đều mất hiệu lực; người dùng phải đăng nhập lại); MFA_ENC_KEY, khóa duy nhất mã hóa dữ liệu lưu trữ (secret TOTP 2FA, AES-256-GCM): thiếu nó phải reset 2FA của mọi người dùng; và các secret mà database chỉ ghi tên chứ không giữ giá trị: UPSTREAM_KEY_* / UPSTREAM_LLM_KEY (upstream api_key_env), OIDC_SECRET_* (SSO client_secret_env), secret của kênh cảnh báo (secret_env), SMTP và token bot |
caddy-data.tgz |
/data của Caddy (chỉ có ở compose production) |
Certificate, tài khoản ACME, và với CADDY_TLS=internal là root CA mà các client của bạn tin cậy |
MANIFEST |
Thời điểm, image, phiên bản migration, số dòng, SHA-256 của từng file | Cho biết bản backup là gì, và dùng để kiểm tra toàn vẹn khi khôi phục |
Cố ý không bao gồm: model (được tải lại và kiểm tra với manifest, hoặc ghim
bằng L2_MODEL), image (tải theo tag), và các secret giữ ngoài .env (trong
secret manager: hãy sao lưu chúng ở đó).
Thư mục được tạo với mode 700 và chứa mọi secret: hãy mã hóa nó (age,
gpg, tính năng mã hóa của công cụ backup) và giữ nó ngoài host. API key được
lưu dưới dạng hash SHA-256, nên bản backup không thể làm lộ chúng; hash mật
khẩu dùng bcrypt.
Lên lịch bằng cron hoặc systemd timer, ví dụ hằng ngày:
15 3 * * * cd /opt/guard-spec && scripts/backup.sh -f deploy/compose/production/docker-compose.yml -o /var/backups/guardspec/$(date +\%F) && find /var/backups/guardspec -mindepth 1 -maxdepth 1 -mtime +14 -exec rm -rf {} +
Khôi phục
Chỉ khôi phục vào database trống (host mới, compose project mới, hoặc sau
docker compose down -v); database đã có bảng sẽ bị từ chối:
scripts/restore.sh -f deploy/compose/production/docker-compose.yml backups/guardspec-20261106T060839Z
Script kiểm tra SHA-256 của bản dump, ghi .env của bản backup nếu chưa có
(và từ chối nếu .env hiện có mang MFA_ENC_KEY khác), khởi động Postgres,
tạo role toàn cluster guardspec_app (bản dump database không mang theo
role), chạy pg_restore, đưa dữ liệu Caddy về chỗ cũ, rồi khởi động stack:
migrate áp dụng các migration mới hơn bản dump và db-roles đặt mật khẩu
guardspec_app từ .env. Đăng nhập, 2FA, API key và CA nội bộ vẫn hoạt
động.
Đã kiểm tra ngày 2026-11-06 (arm64, Docker Desktop): bản backup của một stack compose production (1 organization, 1 user, 1 API key, 1 policy, 26,004 dòng audit) được khôi phục vào một compose project riêng. Checksum của organization, user, API key, policy và các dòng audit đều khớp; mật khẩu admin và API key cũ vẫn dùng được; một injection bị chặn và một prompt vô hại được cho qua trên HTTPS, xác thực bằng root Caddy ban đầu.
Database managed: docs/managed-postgres.md.
Nâng cấp
scripts/backup.sh [-f ...] # 1. a backup to roll back to
git fetch --tags && git checkout v<new-version> # 2. new migrations/ and compose files
# 3. .env: GUARDSPEC_VERSION=<new-version>; compare .env.example for new settings
docker compose [-f ...] pull # 4. images first, so the switch is short
docker compose [-f ...] up -d --wait # 5. migrate and db-roles run before the services
curl -s localhost:8080/readyz | jq .detector # 6. or https://<GATEWAY_HOST>/readyz
- Bước 2 quan trọng: job
migrateáp dụng thư mụcmigrations/trong bản checkout của bạn, nên checkout vàGUARDSPEC_VERSIONphải cùng một release. Một archive mã nguồn của release cũng dùng được như một bản checkout. - Trong bước 5 gateway khởi động lại; các request đang xử lý sẽ lỗi và client thử lại. Với một host thì không tránh được điều này; để không có downtime, hãy chạy nhiều replica gateway sau một load balancer (Kubernetes, Helm chart).
- Model: nếu image mới khuyến nghị một phiên bản model mới,
models-inittải nó trước khi gateway khởi động (vớiDETECTOR_REQUIRE_ML=true, mặc định của production, một lần tải lỗi sẽ dừnguptrước khi gateway mới khởi động). Khi đã ghimL2_MODEL/L3_MODEL, gateway giữ phiên bản đã ghim. - Phiên bản classifier mới: để thử trước khi chuyển, giữ
L2_MODELđã ghim và đặtSHADOW_L2_MODEL=guardspec-classifier@<new>. Nó chấm điểm cùng lưu lượng nhưng không ra quyết định; so sánh trong giao diện quản trị (Models). Sau đó chuyển mà không cần khởi động lại bằngPOST /admin/models/reloadvới{"l2_model":"guardspec-classifier@<new>","shadow_l2_model":"off"}(GATEWAY_ADMIN_TOKEN), và đặtL2_MODELtrong.envcho lần khởi động sau (hoặc đặt nó rồi chạyup -d gateway, lệnh này sẽ khởi động lại). Một lần reload kiểm tra SHA-256 của các file và giữ model đang chạy nếu có gì lỗi; xem README, Shadow mode and model reload. - Kiểm tra sau khi nâng cấp:
/readyzliệt kê đúng các lớp bạn mong đợi, giao diện quản trị tải được, một injection đã biết bị chặn (Bắt đầu nhanh trong README). - Với image từ 0.2.0, chạy thêm
doctorbên trong gateway:docker compose [-f ...] exec gateway /app/doctor. Nó kiểm tra database, phiên bản migration có khớp vớimigrations/của image hay không, các file model so với SHA-256 trong manifest, những lớp nào sẽ được nạp, upstream và các thiết lập bảo mật; exit code 1 nghĩa là có một bước kiểm tra lỗi (-strictcoi cả cảnh báo là lỗi,-jsondùng cho script). Xem README, Kubernetes.
Rollback
Image, không đổi schema
Khi release bạn rời khỏi không thêm migration nào (so sánh migrations/ của
hai tag, hoặc phiên bản migration trong MANIFEST với phiên bản mới):
git checkout v<old-version>
# .env: GUARDSPEC_VERSION=<old-version>
docker compose [-f ...] up -d --wait
Image và schema
Schema mới hơn với code cũ hơn không được hỗ trợ, và các migration
*.down.sql xóa những gì phiên bản mới đã thêm, kể cả dữ liệu; đó không phải
đường đi đã được kiểm thử. Thay vào đó, hãy khôi phục bản backup tạo trước khi
nâng cấp:
docker compose [-f ...] down -v # removes the upgraded database: keep the backup safe first
git checkout v<old-version>
# .env: GUARDSPEC_VERSION=<old-version> (restore.sh keeps an existing .env)
scripts/restore.sh [-f ...] backups/guardspec-<before-upgrade>
Các dòng audit ghi giữa lúc backup và lúc rollback sẽ bị mất. Muốn giữ chúng,
hãy export trước (GET /v1/organizations/{id}/requests, hoặc
pg_dump -t requests).
down -v cũng xóa volume model của compose production (sẽ được tải lại) và
dữ liệu của Caddy (được khôi phục từ bản backup).
Chỉ model
Không đổi image hay schema: tải phiên bản cũ và ghim nó.
docker compose [-f ...] --profile models run --rm models-pull guardspec-classifier@<old>
# .env: L2_MODEL=guardspec-classifier@<old>
docker compose [-f ...] up -d gateway
curl -s localhost:8080/readyz | jq .detector.l2_model
Không cần khởi động lại: giữ phần ghim trong .env cho lần khởi động sau, và
nạp lại gateway đang chạy bằng POST /admin/models/reload với
{"l2_model":"guardspec-classifier@<old>"} (cần GATEWAY_ADMIN_TOKEN).
SIGHUP nạp lại các model mà gateway đang nhắm tới, chứ không đọc .env đã
thay đổi.
Chi tiết, embedder L3 và cài đặt air-gapped: docs/models.md.
Nâng cấp thất bại
migratethoát với mã khác 0: các service không khởi động (chúng chờ nó).docker compose logs migratecho biết migration nào. Một migration lỗi để lạischema_migrations.dirty = true; hãy sửa nguyên nhân, rồi khôi phục bản backup thay vì ép phiên bản.models-initlỗi: đang offline, hoặc mirror thiếu phiên bản mới. ĐặtMODELS_MIRROR, hoặc ghimL2_MODEL/L3_MODELtrước đó, rồiuplại.- Gateway không healthy: xem
docker compose logs gateway; vớiDETECTOR_REQUIRE_ML=true, thiếu model sẽ làm gateway dừng ngay khi khởi động, đây là chủ ý thiết kế.
Nguồn: docs/upgrade.vi.md @ f26302340bf1