--- title: Metrix Offline Deployment & Sub‑module Migration Guide type: curated permalink: main/projects/d5a7f581-c442-4554-87b9-ee723b8b0258/curated/development/metrix-offline-deployment-sub-module-migration-guide stable_id: bb1539bd-c7f2-4d57-9257-8e4b2b4672cb scope: project project_id: d5a7f581-c442-4554-87b9-ee723b8b0258 workspace_type: development usage_profile_id: null preference_context: development document_type: deployment revision: 1 source_memory_ids: [] source_checkpoint_ids: [] source_file_ids: [] source_git_commit: e660bc7bb4fc5ccda47decb4d514874a148ed9b2 source_git_commits: - e660bc7bb4fc5ccda47decb4d514874a148ed9b2 source_agent_sync_ids: [] model_connection: Sub2API model_name: git-restore source_count: 29 source_revisions: memory:6c4cbc6d-a59b-4128-9d6a-cb9652cff00e: '1' memory:a3896ad9-d30c-4963-9232-a7d1ab571d19: '2' memory:bc21af00-1127-44f8-93b7-aa484a7041c2: '1' memory:5924806e-b234-49f7-b971-3c844fd07cf3: '3' source_dispositions: processed: 29 unchanged: 0 unsupported: 0 skipped: 0 cited_source_ids: - memory:6c4cbc6d-a59b-4128-9d6a-cb9652cff00e - memory:a3896ad9-d30c-4963-9232-a7d1ab571d19 - memory:bc21af00-1127-44f8-93b7-aa484a7041c2 - memory:5924806e-b234-49f7-b971-3c844fd07cf3 job_cited_source_ids: [] conflicts: [] supersedes: [] preferences: [] source_cursor: 162 source_hash: e2fcea7c8a9e0df7a91925fb2a9beabd922058868310effc908f95df2d78b218 prompt_version: 2026-08-12.3 schema_version: '3' curation_job_id: null created_at: '2026-08-19T02:32:32.719008+00:00' updated_at: '2026-09-23T15:09:24.136251+00:00' tags: - deployment - docker - fastapi - vue - ci - offline - security restored_from_commit: 6a6a895eafcca6052e81a14fca103a42635dd1c2 --- ## Overview The **Metrix** platform is a modular FastAPI + Vue 3 system deployed via Docker. The architecture consists of an API gateway, core modules (containers, database, scripts, storage, internal PyPI), and a SPA front‑end built with Vite and Naïve‑UI. All modules are auto‑registered through `APP_MODULE` and use an action‑based RBAC model. | Layer | Component | Key notes | |------|-----------|-----------| | API Gateway / FastAPI Core | `git:server/app/main.py` | FastAPI factory, OpenAPI, CORS, SPA fallback | | Module Registry | `git:server/app/modules/registry.py` | Discovers `APP_MODULE` objects, validates keys & deps | | Permission Framework | `git:server/app/core/permissions.py` | Action‑based RBAC; `action:* → read` | | Security Utils | `git:server/app/core/security.py` | PBKDF2‑SHA256 hashing, `mtx_` API‑tokens, Fernet secrets | | Database Sub‑system | ORM models, `git:server/app/db/init.py`, migrations | SQLAlchemy sessions, alembic‑style registry | | Containers Module | Docker client, WS xterm.js terminal | `modules/containers/...` | | Storage API | FTP/SFTP adapters, file‑tree service (depth/size caps) | | Offline Docker Deployment | `scripts/build_docker.py` → `metrix‑app‑latest.tar` (+ optional MySQL & internal PyPI) | | Front‑End SPA | Vue 3 + TypeScript + Vite + Naïve‑UI; i18n (EN/ZH), dark/light themes, Monaco + Shiki, Playwright tests | | CI / Regression | Playwright end‑to‑end suite (`tests/regression/framework.spec.ts`) | ## Current Deployment State (as of 2026‑08‑26) - **Backend**: FastAPI fully running; all core modules (`containers`, `database`, `scripts`, `storage`, internal PyPI) registered via `APP_MODULE`. Action‑based RBAC active; Vaultwarden is the source of credentials (`global_guidance_memory:105b328f‑…`). - **Frontend**: Vue 3 SPA stable, English/Chinese toggle, dark/light theme sync (Shiki pending). The new **DatabasePanel** supports keyword search (`POST /api/database/table/query`) with pagination and filter persistence. - **Instances**: A second instance `capacityrepost‑web:113ff5c` is live; health‑check (`/health`) returns **200** and the image SHA‑256 matches the offline bundle. - **Validation**: Example `sector` table queries return expected row counts; UI renders correctly at both 1440 px and 720 px widths. - **Conclusion**: The system is **stable**; only high‑priority open items remain (Shiki theme sync, fine‑grained API‑token permissions). ## Deployment Artifacts - **Docker images** are built with `scripts/build_docker.py`, producing `metrix‑app‑latest.tar`. The tar contains the FastAPI image, the Vue SPA static assets, and an optional MySQL image for air‑gapped environments. - **Compose files** define the primary service (`metrix‑app`) and the secondary `capacityrepost‑web` with its own MySQL container. - **Internal PyPI server** (`pypiserver` container) provides offline wheels; the UI is exposed at `/pypi`. - **Offline bundle** supports deployments without Internet access. ## Key Deployment Decisions | Decision ID | Summary | Rationale | Status | |------------|----------|-----------|--------| | `e71d9113‑be70‑4792‑8a7d‑81df157ea9a0` | Keep **CapacityReport** as independent sub‑module + Docker image | Isolated UI & historic data handling | Implemented | | `52d53ae2‑ce5b‑4207‑9813‑0c9d3de029ce` | Switch editor highlighting to **Shiki** | Monaco mis‑highlights multiline f‑strings | Integrated (theme sync pending) | | `761650df‑f1df‑4e5a‑b23a‑adf2d01d5c9f` | Adopt **action‑based permission model** | Simplify checks, avoid page rule duplication | All modules migrated | | `34271d12‑a706‑491b‑a06b‑f561e81f7346` | Consolidate script‑run retention to `{max_count, max_days}` | Remove overlapping policies | Unified | | `cf3e85fe‑dcf3‑4af3‑9a17‑edfe63b2f56c` | Freeze local `docs/project_context.md`; **MemRelay only** stores memory | Avoid bidirectional sync, per user request | File read‑only, MemRelay source of truth | | `5924806e‑b234‑49f7‑b971‑3c844fd07cf3` | Formalise **workflow**: Chinese‑first, KISS/YAGNI, ordered steps (implement→clean→memory→docs→commit) | Standardise practice | Documented, tooling enforced | | *Docker‑socket mount* | Mount host Docker socket into `metrix‑app` | Enables host‑level container management for scripts | Documented, admin‑only | | *Offline bundle* | Tarred images + compose files for air‑gapped deployment | Offline environments cannot pull from Docker Hub | `scripts/build_docker.py` creates bundle | | *Internal PyPI server* | Run `pypiserver` container, serve wheels offline | Remove external PyPI dependency | Implemented, UI `/pypi` added | ## Deployment‑Related Preferences (scenario level, development workspace) 1. **Language** – Daily communication in **中文** unless otherwise requested. (source: `global_guidance_memory:7429c22e-...`, `global_guidance_document:6973450e-...`) 2. **Credential Handling** – All secrets must be fetched from **Vaultwarden**; only the credential name is stored in memory. (source: `global_guidance_memory:105b328f-...`, `global_guidance_document:2b47472d-...`) 3. **FastAPI Async Pitfall** – Avoid blocking I/O inside `async def`; move to `def` or thread‑pool. (source: `global_guidance_document:e4fc35f2-...`) 4. **Docker Exec Timeout** – Disable default 3 s timeout via `socket.settimeout(None)`. (source: `global_guidance_document:e4fc35f2-...`) 5. **KISS & YAGNI** – Keep implementations minimal, no speculative dependencies. (source: `global_guidance_memory:bf88c265-...`, `global_guidance_document:2b47472d-...`) These preferences are recorded as **scenario‑level** because the output scope is *project* and cannot promote them to global. ## Tags `[deployment]` `[docker]` `[fastapi]` `[vue]` `[ci]` `[offline]` `[security]`