Operations¶
Tài liệu này là runbook cho rendering runtime của Code To UML trên local và VPS. Các ứng dụng VS Code, GitLab browser extension và Confluence gọi Gateway qua HTTPS nhưng không chạy trong rendering container.
1. Artifact triển khai¶
Dockerfile.render tạo image gồm:
- Java 21 core được build từ
server/; - Node.js Gateway;
- Mermaid, BPMN, Excalidraw và diagrams.net companions;
- shared Google Chrome;
- native renderer từ base image Kroki;
tinivà process supervisor entrypoint.
Playground web assets nằm trong Java JAR và được Gateway phục vụ tại
/playground. Pydia dùng image riêng từ Dockerfile.pydia và giao tiếp với
rendering container qua Unix socket trong named volume.
2. Compose profiles¶
| Profile | File | Mục đích |
|---|---|---|
| Local | compose.code-to-uml.yml |
Build runtime và expose localhost:8000 |
| Production VPS | compose.vps.yml |
Đọc .env, bind loopback và đặt production resource/log limits |
Local map container port 10000 sang host port 8000. Production bind
127.0.0.1:${PORT:-10000}:10000 để TLS ingress trên VPS chuyển tiếp request tới
Gateway mà không public trực tiếp application port.
Local dùng .env.example; Production VPS dùng deploy/vps.env.example. Hai
template khác nhau ở port mapping, proxy trust, JVM limits và release image tag.
3. Yêu cầu và secret¶
- Docker Engine hỗ trợ multi-stage build;
- Docker Compose;
- đủ RAM và disk cho Java, Node dependencies, Chrome và renderer;
- shared rendering token ngẫu nhiên.
Tạo cấu hình local từ repository root:
Copy-Item .env.example .env
Đặt RENDER_API_KEYS thành một hoặc nhiều token phân cách bằng dấu phẩy. Không
commit .env, ghi token vào URL/log hoặc dùng token mẫu. Trên Linux, giới hạn
quyền đọc file hoặc dùng secret manager của môi trường triển khai.
4. Cấu hình runtime chính¶
Các biến runtime được chia theo lớp tiếp nhận request và lớp thực thi để thuận tiện đối chiếu giữa môi trường local với Production VPS.
Gateway¶
| Biến | Local | Production VPS | Ý nghĩa |
|---|---|---|---|
PORT |
Container 10000, host 8000 |
Container và loopback host 10000 |
Gateway port |
RENDER_API_KEYS |
Bắt buộc | Bắt buộc | Danh sách shared token |
TRUST_PROXY |
0 |
1 |
Express trust proxy |
KROKI_TRUST_PROXY |
false |
true |
Core trust proxy |
POST_RATE_LIMIT |
120/phút |
120/phút |
POST limit theo IP |
GET_RATE_LIMIT |
20/phút |
20/phút |
Encoded GET limit theo IP |
CACHE_TTL_MS |
86400000 |
86400000 |
Result cache TTL |
CACHE_MAX_ENTRIES |
500 |
500 |
Số cache entry |
CACHE_MAX_BYTES |
16777216 |
16777216 |
Tổng dung lượng cache |
CACHE_MAX_ENTRY_BYTES |
2097152 |
2097152 |
Dung lượng tối đa mỗi entry |
MAX_RESPONSE_BYTES |
20971520 |
20971520 |
Response cap từ core |
UPSTREAM_TIMEOUT_MS |
35000 |
35000 |
Timeout gọi core |
Đặt CACHE_MAX_BYTES=0 để tắt lưu result cache; request coalescing vẫn hoạt
động. Chỉ bật TRUST_PROXY và KROKI_TRUST_PROXY khi request đi qua proxy tin
cậy. Production template bật hai biến này vì Gateway chỉ nhận traffic từ TLS
ingress qua loopback; deployment có topology khác phải đặt theo trust boundary
thực tế.
Core và universal pipeline¶
| Biến | Local | Production VPS | Ý nghĩa |
|---|---|---|---|
KROKI_BODY_LIMIT |
2097152 |
2097152 |
Request body limit |
KROKI_SAFE_MODE |
secure |
secure |
Renderer safe mode |
KROKI_ENABLE_PYDIA |
false |
false |
Đăng ký Pydia renderer |
KROKI_UNIVERSAL_UNSUPPORTED_MODE |
warn |
warn |
ignore, warn hoặc error |
KROKI_UNIVERSAL_POLICY_MODE |
preferred |
preferred |
preferred hoặc enforced |
KROKI_UNIVERSAL_MAX_PIXELS |
8000000 |
8000000 |
Raster pixel limit |
KROKI_UNIVERSAL_MAX_OUTPUT_BYTES |
20971520 |
20971520 |
Universal output cap |
KROKI_UNIVERSAL_DEFAULT_OPTIONS và KROKI_UNIVERSAL_POLICY_OPTIONS nhận JSON
object. JSON không hợp lệ làm startup thất bại.
5. Pydia sandbox¶
Pydia mặc định không được đăng ký. Sandbox chạy trong container riêng với
network_mode: none, root filesystem read-only, giới hạn CPU, memory, PID,
timeout, source và output. Rendering container chỉ gọi sidecar qua Unix socket;
Pydia container không nhận .env hoặc RENDER_API_KEYS.
Để bật Pydia:
- Xác nhận
pydia-sandboxhealthy và Unix socket tồn tại. - Đặt
KROKI_ENABLE_PYDIA=true. - Recreate rendering container.
- Kiểm tra catalog, authenticated POST và encoded GET bằng source không nhạy cảm.
- Xác nhận sandbox không có IP network.
/healthz không thay thế smoke test Pydia.
6. Build và chạy local¶
docker compose -f compose.code-to-uml.yml config
docker compose -f compose.code-to-uml.yml up -d --build
docker compose -f compose.code-to-uml.yml ps
Invoke-RestMethod http://localhost:8000/healthz
Invoke-WebRequest http://localhost:8000/metrics
Dừng local profile:
docker compose -f compose.code-to-uml.yml down
7. Deploy production VPS¶
- Checkout đúng release hoặc tag.
- Tạo
.envtừ production template:
cp deploy/vps.env.example .env
chmod 600 .env
- Đặt
IMAGE_TAGvàRENDER_API_KEYS; giữPORT=10000với Compose manifest hiện tại và đặt proxy trust theo topology của VPS. - Chạy
docker compose -f compose.vps.yml config. - Chạy
docker compose -f compose.vps.yml up -d --build. - Kiểm tra trạng thái rendering container và Pydia sidecar.
- Smoke test health, authenticated POST và encoded GET qua HTTPS Gateway URL.
- Nếu bật Pydia, chạy thêm Pydia smoke test và kiểm tra network isolation.
Entrypoint khởi động Chrome, companions, core rồi Gateway. Khi nhận TERM hoặc
INT, supervisor chuyển signal đến các child process; production rendering
container có stop grace period 45 giây.
8. Health, metrics và logs¶
/healthztrảokkhi Gateway kết nối được core, nếu không trả503;/healthvà/v1/healthtrả health cùng version thành phần của core;/metricsgộp Prometheus metrics của Gateway và core;- Pydia image kiểm tra Unix socket bằng healthcheck riêng.
Theo dõi Gateway RSS/heap, cache bytes/entries, hit/miss/eviction, in-flight và coalesced requests, upstream count, render failure/timeout/duration, output size, worker queue và Pydia limits khi bật.
Không log token hoặc diagram source. Dùng X-Request-Id để correlate request.
Production Compose rotate Docker JSON logs theo giới hạn đã khai báo.
9. Xử lý sự cố¶
| Hiện tượng | Kiểm tra | Hành động |
|---|---|---|
Health 503 |
Core process và loopback health | Xem container log, để supervisor restart |
Gateway 502 |
Core connection và response cap | Kiểm tra core và upstream log |
Gateway 504 |
Renderer duration và timeout | Kiểm tra renderer/Chrome, tránh retry storm |
Nhiều 429 |
Rate-limit metrics và client | Giảm tần suất trước khi tăng limit |
| Cache memory tăng | Bytes, entries, eviction | Giảm cache limit hoặc đặt bytes về 0 |
| Mermaid queue đầy | Queue, pool và latency | Giảm tải hoặc tăng pool khi đủ RAM |
| Chrome crash | Supervisor log, shared memory | Xác nhận restart và memory limit |
| Pydia vắng trong catalog | Opt-in và socket health | Xác nhận sidecar trước khi bật lại core |
| OOM | Docker events và RSS | Rollback config, giảm cache/JVM/concurrency |
| Output quá lớn | Scale và dimension | Giảm option thay vì nới limit ngay |
10. Rotation, rollback và CI¶
Token rotation:
- Thêm token mới bên cạnh token cũ trong
RENDER_API_KEYS. - Recreate container và chuyển client sang token mới.
- Xác nhận các client đã chuyển.
- Xóa token cũ và recreate container.
Rollback image tag và environment cùng nhau, sau đó chạy health và render smoke test. Cache nằm trong RAM nên không cần migration. Lưu an toàn secret, image tag/digest và deployment manifest.
Workflow deploy-vps hand off tới GitHub environment production-vps. Các biến
bắt buộc là VPS_HOST, VPS_PORT, VPS_USER, VPS_RENDER_URL; secrets bắt
buộc là VPS_SSH_PRIVATE_KEY, VPS_KNOWN_HOSTS. Job triển khai đúng commit SHA
và kiểm tra {VPS_RENDER_URL}/healthz sau deploy.