2026-08-15 收案。本文由
FR-063-LOG.md全 16 blocks 濃縮而成(事實以 LOG/STATE 為準;LOG Block 14 作廢之 http2 誤診相關敘述已排除)。 母案 Notion CM-1187(Done);設計文件design.md(D1–D11+§5);部署環境變數deployment-env.md。
產品進入落地版(on-premise)交付階段,客戶主機上不可再出現一行可讀業務原始碼。本案把 BE 整包用 Nuitka standalone 編成機器碼 binary(業務 .py=0),統一入口單 binary 雙模式(RUN_MODE=api/socketio),建立可重複的三段 build 管線(rebuild wheel → 編譯 → 打 image +七項探針),最終產出並推上 Harbor:guidant-ai/guidant-ai-be:1.14.0=latest(digest sha256:bba0449d…,壓縮 0.55GB),產物 commit bake cc7714d2。與 FR-062 license 執法構成雙保險;為三階段戰線第一棒(後續 FR-064 防竄改 → FR-065 Installer)。全程 13 工作卡+2 子需求卡+母案全 Done,場外衍生 CM-1206(socket 共編存檔 bug)一併修復收 Done。
| Commit | 內容(對應卡) |
|---|---|
b053c765 |
design.md 定稿(設計棒) |
18ef3142 |
.1a DI 靜態模組清單(CM-1194) |
78937428 |
.1b 資源路徑 resource_path(CM-1195) |
5acedd9b |
.1g config 三層重整+runtime_config seed(CM-1200) |
b40a5710 |
.1c+.1d 統一入口 main.py+.env 平鋪(CM-1196/1197) |
cb830d09 |
config-migration-mapping.md §6 STG/POC 上版 checklist |
aa760c50、8a83fa98 |
.1e version bake+fail-fast(CM-1198) |
d510ed79 |
.2a+.2b build 機環境+私房 wheel rebuild(CM-1201/1202) |
8a697d85 |
.2c Nuitka build script(CM-1203) |
02146e9d |
jedi 發版收官後 BE push 齊點(pin 還原、poetry.lock 入版控、TURNSTILE 平鋪、ENV 四值新慣例) |
381acf76 → f449f939(共 5 筆) |
.2d 編譯加速:公開套件排除+dev group 搬遷+三道自動把關(CM-1205) |
78debb6c、e8104ef6 |
.4 socketio namespace 集中註冊+Flask-SocketIO 5.6.1 升版(CM-1193) |
6de7ffd8 |
CM-1206 socket auth context 修復(BE 側) |
29c4013f → cc7714d2(共 3 筆) |
.3 production image:Dockerfile.production/entrypoint/探針(CM-1192);cc7714d2 即最終產物 bake |
0dcabc8d |
build_image 產出(合流輪) |
f921ed39 |
build script i18n 加 --statistics+.mo 現場重編語意註明 |
2834cf4c |
i18n 死條目 non_existent_key 清除,兩 locale 回 100% |
| Commit | 內容 |
|---|---|
967e67b |
CM-1206 socket 修復 FE 側配合 |
| Commit / 版本 | 內容 |
|---|---|
57e8a41 |
.1f LibreOffice 路徑解析共用 helper(LIBREOFFICE_CMD env override+PATH fallback,CM-1199) |
file-upload 0.0.21、captcha 0.0.14 |
發版推 Nexus(收官日,pin 還原一併完成) |
.1「程式整理」(7 卡 CM-1194~1200)——讓 codebase 具備可編譯性:
gen_di_modules_static.py 產 138 模組靜態清單取代 runtime 目錄掃描(Nuitka 下無檔案系統可掃);--check 走 AST parse 防清單漂移,static 模式缺檔 fail-fast 不靜默退回動態。main.py 以 RUN_MODE 切模式;scheduler 只在 api 模式起(解排程雙跑老問題);.env 由 JSON 包裝改平鋪(向後相容),逐 key 審計 49 項清 6 死項。resource 死模組 19 次靜默 warning 的陳年漏拔)。config_loader 集中驗證(缺項一次列全);營運參數遷 DB system_config(缺列 fail-open 回內建預設);清 SQLALCHEMY_/APISPEC_ 等死定義。.2 Build 管線(4 卡 CM-1201/1202/1203/1205):
.py=0、資源在位、binary 親起驗證 .1 全部機制在真產物內活著;修兩個「開發環境看不出、正式承載才死」的陰險 bug(gunicorn 動態載入模組顯式 include+升健檢項)。--nofollow 排除原樣附帶、測試依賴搬 dev group;冷編 56m42s → 穩態 12m11s(省 78%);三個靜默複製 bug 全修+三道自動把關(完整性斷言/功能探針 9 項/dry-run 預檢)。jedi-*+業務碼照舊全編譯。.3 Production image(CM-1192):Dockerfile.production(glibc 對齊、非 root uid1000、entrypoint chown-then-setpriv、apt 清單+fc-match 斷言確保 NotoSansCJK)+volume 佈局(design §5.5)+probe_container.sh 七項探針(§5.6,末輪 PASS=11 FAIL=0);合流輪 rebuild bake cc7714d2(含 CM-1206 修復)→ build_image → push Harbor 並 API 端複驗。
.4 eventlet × Nuitka 驗證(CM-1193):本卡目的=驗證 eventlet monkey_patch 在編譯產物下是否存活。過程中揪出 .1c 模式裁剪誤刪 socketio namespace 註冊的真回歸(healthz 級探針測不到的層)→ 修法=namespace 抽離至集中清單 config/socketio_namespaces.py(比照 REGISTERED_APPS)統一註冊;Flask-SocketIO 5.3.6→5.6.1 升版根治 session 問題(留「不可退版」警語)。產物探針 4/4 PASS——eventlet × Nuitka 命題閉環,D1 保底方案(換 gevent)不需啟用。
場外 CM-1206:user 實測 .4 時現形的既存獨立 bug(2026-07-07 起,先前被「連不上」蓋住)——socket 路徑無 auth context 導致共編自動存檔 AttributeError。修法:connect 驗 JWT 建 auth context、FR-048 守門不降級、錯誤不再靜默(handler emit 錯誤事件+log)、fail-closed 全路徑。BE 6de7ffd8+FE 967e67b。
| 面向 | 舊 | 新 |
|---|---|---|
| 啟動方式 | main_app.py(8000)/main_socketio.py(8002)兩支入口 |
單一 python main.py=API(8000,日常唯一指令);RUN_MODE=socketio python main.py=通知服務(8002)。api 模式 DEBUG=true 走 Flask dev server、否則內嵌 gunicorn |
| Scheduler | 兩入口各起一份(雙跑) | 只有 api 模式起(4 jobs);socketio 模式 0 份,log 明示 disabled |
| Config | 六套環境 class(Development/Staging/…×2 雲別) | 一套 class+ENV 降級為顯示標籤(新慣例四值 DEV/STG/POC/PRD;變數本身不退,保護既有部署腳本);config_loader 啟動期集中驗證,缺項一次列全 |
| Secret env | DB_SECRET/JWT_SECRET/REDIS_SECRET JSON 包裝 |
平鋪 key(向後相容舊 JSON 填法);TURNSTILE 同步平鋪化 |
| 營運參數 | 散在 config class 常數 | 遷 DB system_config(migration seed 7 列、冪等);JWT 效期改 DB 後需重啟、登入政策/MFA 即時生效 |
| socketio namespace | 藏在各 module create_module() 內註冊 |
集中清單 config/socketio_namespaces.py(封閉集合 2 個:notification/fill-survey),app_factory 統一註冊 |
| 交付形態 | 原始碼部署 | Nuitka standalone binary in Docker image(業務 .py=0;公開第三方套件原樣附帶) |
| 退役物 | — | main_app.py/main_socketio.py 刪除;六套環境 class 刪除;死 env 項清 6 支(REDIS_DB、通知四項、DRIVE_WEBHOOK_PUBLIC_BASE_URL)+SQLALCHEMY_/APISPEC_/TOKEN_TTL/WEBSITE_URL 死定義 |
| 依賴管理 | poetry.lock 不入版控(歷史誤排除) | poetry.lock 入版控(build 機 lock 不同步事故後拍板) |
RUN_MODE 切模式,build ×2 變 ×1,順帶解 scheduler 雙跑。--dry-run 被舊版無視、誤觸真編譯)。跑新功能前先驗目標機 code 版本。bash -n 0.01s → dry-run 0.3s → 小探針 10s → 全量 19m,先快後慢(runner 名言:「拿最慢的迴圈去測最快能測的東西」)。pgrep 查同類進程:兩份 build 互撞的 linker crash(undefined reference)像 code 問題,實為共用 nuitka-out 汙染。ssh -T 戳破「188 無 gitlab 金鑰」誤判,誤信就多養一條 rsync 歧路(user 同日立 memory:部署機程式碼一律 git pull)。--statistics 一行參數,首輪即抓到潛伏死條目。checkout-index -f -a 抹掉跨棒未 commit 檔案(STATE/LOG+pyproject override)——恢復只准 stash pop;交接檔寫完盡快 commit。| 項目 | 說明 |
|---|---|
| FR-064 防竄改(CM-1188) | 決策者親做中,非派工項 |
| CM-1207(FR-065.0 DB 初始化基線) | 卡已開、盤點棒 prompt 已交 user(唯讀可先行);實作棒等 FR-064 完成後派 |
| FR-065 Installer(CM-1189) | 前置=FR-064+CM-1207;FE image/產品 compose 明確劃入此案(compose 形狀由 installer 決定,不提早做) |
| CM-1204(手冊下載死碼端點) | 場外待排程,不掛任何 FR |
| STG 188 舊產物去留 | 8000/8002 兩服務跑的是舊產物 36708b35(非最終版),去留/換新 image 由決策者定 |
| Swagger 待補 | docs.init_app 從未啟用(本案盤查發現,APISPEC_* 死項已清);復原時掛 DEBUG 開關 |
| analysis 文件 | 「公開套件不需編譯保護」推理(已允諾 user)+常數表連坐與驗證金字塔可併寫 |
192.168.50.171(=harbor.jedicogy.com.tw:8081,188 /etc/hosts 有映射),專案 guidant-ai:docker pull …/guidant-ai/guidant-ai-be:1.14.0(=latest,digest sha256:bba0449d…)。起服務:docker run … guidant-ai-be:1.14.0,RUN_MODE=api→8000/RUN_MODE=socketio→8002,單 image 雙模式。docs/features/FR-063-2608-nuitka-packaging/deployment-env.md(必填/一般/功能模組+jedi-* 16 項+volume 掛載表+交付前 checklist)。STG/POC 上版另見 config-migration-mapping.md §6 的 13 項 checklist(含 CORS 補實際站台網址)。/opt/guidant_ai,程式碼同步一律 git pull):
build_release.sh — wheel rebuild(含 dependency-injector 私房 wheel)+Nuitka 編譯,穩態 ~12m;dry-run 預檢+完整性斷言+i18n --statisticsbuild_image.sh — 產 production image(Dockerfile.production)probe_container.sh — 七項探針健檢(design §5.6)Noto Sans CJK TC;非 root uid1000 執行。