
Day 5 的 Jellyfin 與 Roon 皆具備獨立的網頁設定介面,套件管理員只要將儲存路徑掛載妥當、硬體加速與網路架構正確指派,其餘設定皆可在軟體介面內完成。今天的兩個案例則呈現截然不同的架構典型。changedetection.io 的行為完全由環境變數決定,監控清單直接儲存於內建的 datastore 資料庫中,完全不需要套件由外部掛入任何實體設定檔。Homepage 則恰恰相反,它本身沒有圖形化管理後台,整個儀表板全依賴七個 YAML 設定檔定義,套件必須在啟動前將一份立即可用的骨架設定精準送入容器,後續還得確保管理者能在不破壞容器狀態的前提下自由修改。
這兩個專案在整體地端維運場域中扮演著核心角色。changedetection.io 負責承擔資安監控與變更感測,原廠設備的安全公告頁、容器與維運平台軟體的新版本發布頁,以及 Day 3 所鎖定的每一個上游映像檔 release 頁面,皆能讓它持續追蹤。Homepage 則是整個維運體系的單一整合入口,從 Day 2 打造的各個 QPKG 狀態頁、Day 20 的 Grafana 儀表板,到 Day 22 的防火牆日誌檢視器,最終都會收斂成首頁上的一張張狀態卡片。
本次體檢基準依據 changedetection-qpkg v0.60.3(commit 527ee3e)與 homepage-qpkg v1.0.7(commit b95f75a)撰寫,兩者皆已在實體 QNAP NAS 完成實裝驗證,兩個專案共通需要的「選用附屬容器」架構,則正式納入 qpkg-template v0.2.0 核心。本篇探討的核心工程技術聚焦於二方面,單一 QPKG 統籌多個容器時的主從依賴設計,以及設定檔如何在套件升級週期中安全派送且不覆蓋使用者的客製化修改。
| 檢查項目 | changedetection-qpkg v0.60.3 | homepage-qpkg v1.0.7 |
|---|---|---|
QPKG_NAME |
ChangeDetection |
Homepage,上游裸名稱 |
QPKG_VER |
0.0.0,CI 從 git tag 覆寫為 0.60.3 |
1.0.7,人工維護 |
| 版本號語意 | 上游版本加打包修訂,v0.55.7-3 代表 changedetection.io 0.55.7 的第三次打包修訂 |
純管理腳本版本,與上游映像檔版本脫鉤 |
| 服務腳本 | changedetection.sh,POSIX sh,234 行 |
homepage.sh,POSIX sh,589 行 |
| 容器數量 | 單一容器,可掛接外部 Playwright 瀏覽器實例 | 雙容器架構,Homepage 主體搭配 Filebrowser 檔案編輯器(可依需求關閉) |
| 映像檔參考 | dgtlmoon/changedetection.io:<tag>,tag 由 CI 注入 .image_tag |
ghcr.io/gethomepage/homepage:latest 與 filebrowser/filebrowser:latest |
| 啟動流程 | 每次啟動強制 docker rm -f 再 docker run,採前景下載映像檔 |
具備冪等啟動特性與背景下載,但尚未引入設定指紋校驗 |
| 狀態頁面 | 無狀態頁 | 提供獨立狀態頁,於服務就緒後動態回傳監聽埠 |
| 設定儲存來源 | 透過環境變數傳遞,datastore 存放於 <預設磁碟區>/.changedetection.io |
由套件內建 skeleton/ 首次播種七個 YAML 至 <預設磁碟區>/Homepage/config |
| 使用者設定檔 | changedetection.conf 實際上從未被正確建立(原因詳見下文分析) |
homepage.conf,於首次安裝時自動由範本複製產生 |
診斷工具 diag |
未提供 | 具備診斷指令,輸出詳細容器與網路狀態 |
| Release 校驗碼 | 未提供校驗雜湊,Release 附件額外夾帶一份儲存庫原始碼壓縮檔 | 附帶 .md5,但校驗內容包含 build/ 相對路徑,導致 md5sum -c 直接報錯 |
| 安裝檔案擁有權 | 歸屬於 uid 1001 | 歸屬於 uid 1001 |
| 軟體授權聲明 | 採用 Apache-2.0,與 qpkg.cfg 定義相符 |
標記為 v1.0.7 時缺少 LICENSE 檔,main 分支補齊之 Apache-2.0 與 qpkg.cfg 標註的 MIT 衝突 |
| 上游專案宣告 | 未提供 | 未提供 |
這兩個專案若依 Day 2 所建立的標準骨架檢驗,各自存在功能缺口。changedetection-qpkg 具備 Container Station 開機競爭處理機制,實作了守護行程連續確認與 setsid 行程分離,卻缺乏狀態頁、冪等容器啟動機制與 diag 診斷工具。homepage-qpkg 則是由早期 open-webui-ollama-qpkg 分支複製而來,具備狀態頁與診斷機能,但因複製時間點早於「設定狀態指紋」的引進,一旦使用者在 .conf 中變更服務埠或掛載路徑,現存容器完全無法感知變更。
在版本管理語意方面,changedetection-qpkg 的設計有其參考價值。其 CI 流程會在推送 tag 時將 v0.60.3 拆解,將核心版號 0.60.3 寫入 qpkg.cfg 的 QPKG_VER,同時寫入 shared/.image_tag 供服務腳本在 pull 映像檔時取用。當僅有封裝腳本修正時,則追加 -N 後綴,例如 v0.55.7-3 代表以 changedetection.io 0.55.7 為核心的第三次封裝修正。這能讓系統 App Center 直觀呈現上游軟體版本,大幅提升使用者的識別效率。儘管此作法鎖定的是 tag 而非 digest,但相較於使用 latest,已在實務穩定性上往前邁進了一大步。
changedetection.io 的網址監看清單、事件通知管道與排程規則皆集中儲存於內建的 /datastore 路徑,操作完全依賴瀏覽器介面完成。在 QPKG 套件封裝層級,能夠定義與控制的參數僅限於服務通訊埠、datastore 實體存放目錄、系統時區,以及是否串接外部 Playwright 渲染引擎。檢視 v0.60.3 的 changedetection.conf.sample,僅包含四組基礎環境變數。
#PORT=5000
#DATA_DIR="/share/CACHEDEV1_DATA/.changedetection.io"
#PLAYWRIGHT_DRIVER_URL=""
#EXTRA_DOCKER_OPTS=""
依照原始設計,datastore 預設會放置於系統預設磁碟區根目錄下的隱藏目錄 .changedetection.io,刻意排除在 QPKG 自身的安裝根目錄之外。這項決策延續了套件移除時保留核心資料的原則。由於 App Center 執行套件解除安裝時會逕行將整個套件安裝目錄完全刪除,將資料存放於外部路徑即可免除在 PKG_PRE_REMOVE 中撰寫複雜保護邏輯的負擔。然而這項設計亦包含潛在風險,一旦服務腳本無法正確取得預設磁碟區路徑,便會強制退回 $QPKG_ROOT/data,導致資料重新曝險於解除安裝的清除範圍內。此外,隱藏目錄設計會導致管理者無法直接從 File Station 檢視或取用備份檔案,必須在整機備份架構中明確納入保護清單。
範例中預設寫死的 CACHEDEV1_DATA 存在環境相容性問題。以採用 ZFS 檔案系統的 QuTS hero 實機為例,各服務實體路徑高度分散:Container Station 位於 ZFS530_DATA,套件安裝路徑落在 ZFS2_DATA,而預設共用資料夾則座落於 ZFS1_DATA。因此,任何腳本與環境設定皆嚴禁寫死路徑,必須統一透過系統工具 getcfg 進行動態推導。
將設定架構遷移至標準範本後,相關參數皆納入 app_defaults 初始化,並全面參與狀態指紋計算。
app_defaults() {
APP_CONTAINER_NAME="${APP_CONTAINER_NAME:-changedetection-io}"
WEB_PORT="${WEB_PORT:-5000}"
APP_DATA_PATH="${APP_DATA_PATH:-$(default_volume)/.changedetection.io}"
PLAYWRIGHT_DRIVER_URL="${PLAYWRIGHT_DRIVER_URL:-}"
APP_EXTRA_ARGS="${APP_EXTRA_ARGS:-}"
}
app_fingerprint_app() {
printf '%s\n' "$WEB_PORT" "$APP_DATA_PATH" "$PLAYWRIGHT_DRIVER_URL" "$APP_EXTRA_ARGS"
}
app_run_app() {
"$DOCKER" run -d \
--name "$APP_CONTAINER_NAME" \
--network "$NETWORK_NAME" \
--restart unless-stopped \
-p "$WEB_PORT":5000 \
-e TZ="$TZ" \
${PLAYWRIGHT_DRIVER_URL:+-e PLAYWRIGHT_DRIVER_URL="$PLAYWRIGHT_DRIVER_URL"} \
-v "$APP_DATA_PATH":/datastore \
$APP_EXTRA_ARGS \
"$APP_IMAGE"
}
在舊版 v0.60.3 中,每次呼叫 start 都會強制執行 docker rm -f 再接續 docker run,註解說明此舉是為了確保版本升級時能立即套用最新映像檔。在早期缺乏狀態感知能力的架構下,這是確保設定生效的直接手段,但缺點是每次重開機都會強迫重建容器,導致本機日誌與暫存狀態完全遺失,對維運日誌集中管理造成困擾。改採狀態指紋機制後,唯有當核心映像檔版本或設定參數發生變更時才會觸發容器重建,一般啟動情境則保持純粹的 docker start。
changedetection.io 抓取靜態 HTML 網頁時無須依賴額外元件,但面對 QNAP 官方安全公告或多數軟體廠商採用動態 JavaScript 渲染的 Release 頁面時,就必須串接 sockpuppetbrowser 或相容於 Playwright 的瀏覽器執行個體。v0.60.3 僅提供 PLAYWRIGHT_DRIVER_URL 參數讓使用者自行指向外部既有服務,套件本身並不負擔該容器的生命週期管理。
若利用範本的 CONTAINERS 機制將瀏覽器收斂為套件內的附屬容器,並透過設定開關交由管理者彈性啟用,在早期範本中唯一的應急做法是在關閉開關時讓啟動函式直接 return 0。實機驗證顯示此種權宜設計會引發多項非預期問題,核心偵測到容器不存在,便會誤判映像檔尚未就緒而無端觸發 Chromium 下載,狀態頁面會出現永久處於非執行狀態的異常項目。
為解決附屬元件的管理問題,qpkg-template v0.2.0 核心擴充了專屬的啟用判定鉤子與選用清單定義。
CONTAINERS="browser app"
OPTIONAL_CONTAINERS="browser"
WEB_ID="app"
HEALTH_PATH="/"
app_defaults() {
ENABLE_BROWSER="${ENABLE_BROWSER:-false}"
BROWSER_CONTAINER_NAME="${BROWSER_CONTAINER_NAME:-changedetection-browser}"
if [ "$ENABLE_BROWSER" = "true" ] && [ -z "$PLAYWRIGHT_DRIVER_URL" ]
then
PLAYWRIGHT_DRIVER_URL="ws://$BROWSER_CONTAINER_NAME:3000"
fi
}
app_enabled_browser() {
[ "$ENABLE_BROWSER" = "true" ]
}
app_run_browser() {
"$DOCKER" run -d \
--name "$BROWSER_CONTAINER_NAME" \
--network "$NETWORK_NAME" \
--restart unless-stopped \
--shm-size 1g \
"$BROWSER_IMAGE"
}
當 app_enabled_browser 回傳非零狀態碼時,核心管理邏輯將主動忽略映像檔拉取、略過容器建立,且不將其納入健康檢查與整體狀態回報。若該容器原已處於運作狀態,系統會安全予以停止但保留實體,待管理者日後重新啟用時直接復原。登錄於 OPTIONAL_CONTAINERS 中的非核心容器若啟動失敗,僅會記錄 Warning 等級警告,不阻斷主體服務運作,狀態頁面則精確標註為「選用,未執行」。此設計亦完全相容於 check-pins.sh 的映像檔鎖定原則,關閉的附屬服務依然必須在 images.lock 完成版本鎖定。
這項雙容器架構在生命週期自動化測試中,針對停用、通訊埠衝突失敗、衝突排除後復原以及再度停用等情境進行了嚴格驗證。舊版核心在 57 項測試指標中有 7 項失敗,而升級至 v0.2.0 後已全數通過測試驗證。
在硬體資源配置上,該瀏覽器容器完全不對實體網路暴露任何外部連接埠,僅在私有容器網路中以服務名稱供 changedetection.io 調用。由於 Chromium 極為消耗記憶體資源,其內建 /dev/shm 預設的 64 MB 容易在高負載渲染時耗盡崩潰,因此啟動參數必須明確配置 --shm-size 1g。在映像檔版本控制層面,sockpuppetbrowser 官方於 Docker Hub 釋出的最後一個實體版本標籤為 0.0.3(2025 年 8 月),其後更新皆僅覆寫 latest,因此在 lockfile 中必須精準鎖定 digest 雜湊值以確保環境再現性。
依據基礎設施規劃與映像檔鎖定清單,此維運場域的核心監看目標與連動流程彙整如下。
| 監控類別 | 監控目標 | 觸發之後續變更與維運處置 |
|---|---|---|
| NAS 韌體與系統安全 | QNAP 官方資安通報專區、QTS 與 QuTS hero 發行版本更新紀錄 | 觸發系統變更工單建立與升級評估 |
| Container Station 核心 | App Center 官方發布之 Container Station 軟體版本更新頁面 | 防範底層 Docker Daemon 行為變更,預先於測試環境安排驗證 |
| 鎖定之上游核心服務 | changedetection.io、Homepage、Filebrowser、Jellyfin、Ollama 與 Open WebUI 之 GitHub 官方發行頁面 | 觸發 pin-images.sh 換版作業,啟動 CI 自動化建置並釋出修訂版 QPKG |
| GPU 運算節點環境 | DGX OS 最新發行紀錄、NVIDIA 官方顯示卡驅動程式資安通報 | 觸發運算節點基線定義更新與相容性檢驗 |
| 邊界網路設備防護 | FortiOS 官方 PSIRT 資安通報頁面 | 評估漏洞風險等級並安排防火牆韌體升級維護時程 |
上述監控清單與 Day 3 的 update --check 形成了互補防線。update --check 是由本地端向 registry 主動驗證「已鎖定的版本標籤背後的實體映像檔是否遭竄改」,防範既有版本的非預期變更,changedetection.io 則是向軟體發布源頭追蹤「上游是否釋出全新版本標籤」,及時掌握架構演進。兩者結合才能構成完整的供應鏈防禦。
以現況為例,舊版 homepage-qpkg 因直接相依於 :latest,在無感知的狀況下自動拉取了 Homepage v2.4.0 與 Filebrowser 2.63.23,導致兩者皆在封裝未調整的情況下跨越主版本號,進而引發了後續 Filebrowser 資料庫結構與路徑變更的問題。
目前事件告警由 changedetection.io 內建的 Apprise 模組派送,現階段優先以安全電子郵件發報,後續將無縫介接至 Day 20 規劃的專屬告警管道。監控資料本體存放於 datastore 中,屬於基礎架構的動態維運資產,除了必須完整涵蓋於日常備份策略中,亦將作為變更稽核時判定漏洞知悉時間點的數位佐證。
Homepage 啟動時會主動讀取掛載於 /app/config 目錄下的 settings.yaml、services.yaml、widgets.yaml、bookmarks.yaml、docker.yaml、custom.css 與 custom.js。若目標路徑為空目錄,Homepage 雖然會自動產生一組預設檔案,但該設定內容完全脫離當前 NAS 的網路環境。因此,homepage-qpkg 在套件內部隨附了一套預先定義好的 skeleton 範本目錄,並於服務首次啟動時複製至資料儲存路徑。
seed_config() {
mkdir -p "$HOMEPAGE_CONFIG_PATH"
if [ ! -f "$HOMEPAGE_CONFIG_PATH/settings.yaml" ]; then
cp -R "$QPKG_ROOT/skeleton/"* "$HOMEPAGE_CONFIG_PATH/" 2>/dev/null
NAS_IP=$(/sbin/getcfg Network "IP Address" -f /etc/config/uLinux.conf 2>/dev/null)
[ -z "$NAS_IP" ] && NAS_IP=""
sed -i "s/{{NAS_IP}}/$NAS_IP/g" "$HOMEPAGE_CONFIG_PATH/services.yaml" 2>/dev/null
chmod -R 777 "$HOMEPAGE_CONFIG_PATH" 2>/dev/null
fi
}
原有的邏輯是以 settings.yaml 是否存在作為初次初始化的判斷依據。只要檔案已存在便完全略過複製,這確保了套件升級時不會覆蓋使用者已自訂的 YAML 內容。這項原則方向正確,但在實作層面存在三大關鍵問題需要修正。
在設定檔同步問題上,原架構使得新版套件追加的範本功能完全無法傳遞給既有使用者。當新版 QPKG 新增了預設卡片或更新了微型儀表元件語法時,只有全新安裝的環境才能受惠。重構時改為在每次服務啟動階段,自動將套件內建的最新範本同步至設定目錄底下的隱藏資料夾 .skeleton/,作為唯讀對照參考,並透過 diag 指令精確比對現役設定與官方最新範本的檔案差異,交由管理者自主決定是否合併變更。
在網路位址推導方面,原本於播種階段直接使用 sed 將 NAS IP 寫死進 services.yaml 的做法不適合,畢竟企業級 NAS 環境通常具備多張網卡或切分 VLAN,透過 getcfg Network "IP Address" 抓取的位址往往無法對應到正確的存取介面,且一旦 NAS IP 變更,靜態寫入的設定將立即失效。實務上,Homepage 自 v0.6.11 起即原生支援在 YAML 檔案中採用 {{HOMEPAGE_VAR_XXX}} 語法,由系統在執行時期動態以同名環境變數替換內容。經實機驗證,在骨架設定檔中保留 {{HOMEPAGE_VAR_NAS_IP}} 佔位符,並於啟動容器時透過 -e HOMEPAGE_VAR_NAS_IP=... 注入動態推導的實體 IP,即可在不污染設定檔實體檔案的前提下完成動態解析,同時將該 IP 納入狀態指紋,當主機網路環境改變時自動重啟容器更新。
由於 Homepage 本身不提供任何 Web 端編輯介面,調整設定檔往往必須透過 SSH 終端機或 SMB 檔案分享。homepage-qpkg 自 v1.0.3 起附帶了一個獨立的 Filebrowser 容器,將 Homepage 的設定檔目錄直接掛載為根路徑,並對外監聽 3009 埠,提供直觀的線上檔案管理功能。此服務被定位為選用元件,可透過 HOMEPAGE_ENABLE_EDITOR=false 自主關閉。
重構方案利用套件的 app_status_fields 擴充機制,在首次啟動時由腳本自動擷取容器日誌中的初始密碼,直接呈現於區網專屬的狀態頁面上,並明確提醒使用者登入後立即修改,兼顧了便利性與安全性。
v1.0.7 的設定中將 HOMEPAGE_MOUNT_DOCKER_SOCKET 預設為 true,導致主容器啟動時自動掛載了主機的 /var/run/docker.sock:/var/run/docker.sock:ro。此項配置原意是為了讓儀表板能即時讀取並呈現其他容器的執行資料。
然而,這項預設配置在資安架構上完全無法成立。經實機進行滲透驗證,在 Homepage 容器內部直接向掛載的 docker.sock 發送 POST /containers/create API,請求建立一個具備 host 特權且將主機實體 /etc 目錄以讀寫權限掛載的逃逸容器,Container Station 底層守護行程即時回傳了 HTTP 201 狀態碼,證實容器已在主機端成功建立。Homepage 官方文件亦明確指出直接掛載 socket 屬於高風險整合模式,官方更傾向推薦安全的架構設計。
因此在 v1.0.8 版本中,該預設值已被強制切換為 false。若管理者確實需要整合 Docker 狀態監控,標準的解法是引入專門的 docker-socket-proxy 容器。該代理服務能對 Docker API 進行細部權限過濾,僅開放如 CONTAINERS=1 等純狀態讀取端點,Homepage 僅需將 docker.yaml 指向代理的 2375 連接埠即可安全取用資料。此架構已被規劃為套件的第三個選用容器,於管理者明確設定 ENABLE_DOCKER_PROXY=true 時自動啟動。在進行版本鎖定時須特別注意,Tecnativa 官方在 Docker Hub 上釋出的映像檔多為未標註穩定版本的滾動標籤,維運時必須追溯至其 GitHub Releases 頁面鎖定特定發行版號與 digest。
HOMEPAGE_ALLOWED_HOSTS 預設萬用字元的取捨Homepage 自 v1.0 起強制要求定義 HOMEPAGE_ALLOWED_HOSTS 參數,用以抵禦 DNS Rebinding 攻擊,當 HTTP 請求標頭中的 Host 不在信任白名單內時一律拒絕連線。在 v1.0.2 的封裝中,為了降低使用門檻,暫時將該預設值設定為 *。這是因為在實際應用中,使用者可能透過內部 IP、NAS 本地主機名稱或是 myQNAPcloud 動態網域進行連線,預設若過度嚴格將導致一般管理者無法順利登入。
官方文件指出,將允許清單設為 * 屬於非建議的過渡狀態,內建的主機標頭防護主要作為內部網路環境的最低基準,若要對外發布服務,必須在前端架設正規的反向代理伺服器完成過濾。在純區網維運場域中,暫時接受 * 設定是可以接受的妥協,但必須在設定檔註解中充分告知風險,並在狀態頁面明確標註該防禦目前處於寬鬆模式,引導具備專屬網域的管理者主動填入精確的信任清單。
| 實務架構需求 | 需求來源專案 | 核心框架整合方式 | 實作狀態 |
|---|---|---|---|
| 選用附屬容器架構,未啟用時完全略過、啟動失敗不中斷主程式 | changedetection 的渲染瀏覽器、Homepage 的檔案編輯器與 API 安全代理 | 於核心引入 app_enabled_<id> 條件式鉤子與 OPTIONAL_CONTAINERS 白名單變數 |
已於 v0.2.0 正式完成 |
| 安裝目錄權限修正,防止 CI UID 洩漏造成本機提權 | 兩專案在實機安裝後皆殘留 GitHub Actions 的 UID 1001 檔案屬性 | 於 pkg_post_install 鉤子開頭強制執行 chown -R 0:0 歸正權限 |
已於 v0.2.0 正式完成 |
| 主機層動態網路資訊注入容器環境變數並納入狀態校驗 | Homepage 需要取得 NAS 的當前實體介面 IP | 無須擴充核心,於應用層 app_defaults 完成偵測,並於 app_fingerprint 列入指紋計算 |
於遷移至範本時實作 |
| 設定目錄之初次播種與範本對照機制 | Homepage 所依賴的完整 YAML 初始骨架 | 無須擴充核心,由應用層於啟動前安全處理,並在範本文件補充「設定檔驅動型應用」實作章節 | 於遷移至範本時實作 |
| 由容器執行日誌即時擷取初始化機敏資訊至狀態面板 | Filebrowser 首次運作時所自動派發的隨機管理者密碼 | 沿用既有之 app_status_fields 介面,於應用層調用 docker logs 萃取目標字串 |
於遷移至範本時實作 |
| 於 App Center 套件介面直接呈現上游映像檔實體版本 | changedetection 原先採用的 -N 複合版本編號命名規範 |
經評估維持範本規範,不併入核心機制,架構原因詳見下述說明 | 於遷移至範本時實作 |
針對最後一項版本號設計的評估,代表了封裝設計上的哲學分歧。範本的核心規範認為,QPKG_VER 應當純粹指涉該 QPKG 管理腳本與封裝架構自身的版本演進,至於所封裝之上游軟體版本,應完整登錄於 images.lock 並動態反饋於狀態頁面中。changedetection-qpkg 原先的做法則是將 QPKG_VER 與上游版本強制綁定,再以 -N 代表打包修訂。後者雖能讓一般使用者在系統清單中一眼看出上游軟體版本,但會破壞 CI 自動化檢查機制中「Git Tag 必須完全等於 QPKG_VER」的對等性驗證,且一旦封裝腳本自身進行重大重構,將難以透過標準語意化版本表達演進歷程。
經權衡後,後續的正式遷移將全面回歸範本標準原則。App Center 統一呈現 QPKG 套件自身的版本歷程,而上游軟體的精確版號則完整標註於服務狀態頁、隨附的 images.lock,以及由 CI 工作流自動組合的 Release 發布標題中(例如標註為 ChangeDetection 1.0.0 (changedetection.io 0.60.3)),兼顧工程規範與使用者的辨識體驗。
針對無須大幅重構即可排除的安全性與結構問題,已於現有程式庫完成原地修正,並於實體 NAS 環境完成升級測試。
| 釋出版本 | 核心修正項目說明 |
|---|---|
| qpkg-template v0.2.0 | 實作選用容器機制(提供 app_enabled_<id> 與 OPTIONAL_CONTAINERS 介面),於安裝鉤子加入 chown -R 0:0 修正檔案權限,調整 _bg_start 機制使其優先等待第一個實際啟用的容器 |
| changedetection-qpkg v0.60.3-1 | 移除無效的 release.yml,修正安裝鉤子為標準 pkg_post_install() 函式,使 changedetection.conf 能正常初始化,修正安裝目錄檔案權限為 0:0 |
| homepage-qpkg v1.0.8 | 移除冗餘之 release.yml,將 QPKG_LICENSE 正式更正為 Apache-2.0,將 Docker Socket 掛載預設值切換為 false 並於升級時強制卸除,廢除 chmod -R 777 並全面回收目錄權限,編輯器改以 root 執行並將儲存路徑重導至 /database,修正文件之初始密碼檢索語法,修正安裝檔案權限為 0:0 |
從 homepage-qpkg v1.0.7 跨版本升級至 v1.0.8 時,由於舊版 Filebrowser 資料庫原先遺留在匿名 Volume 中無法直接平移,升級後編輯器會重新派發一組隨機密碼。此變更已於發布說明中詳盡公告,後續容器重建作業將不再觸發密碼重設問題。
changedetection-qpkg 由 0.60.3-1 進階至 1.0.0,代表版本定義正式回歸管理架構本體,homepage-qpkg 由 1.0.8 跨越至 2.0.0,則標誌著內部識別名稱的規範化更動。
Day 7 將探討 ComfyUI 的打包架構。這項應用與前述案例截然不同,其映像檔無法直接自公開 Registry 取得,而必須在 NAS 本機端透過 Dockerfile 現場編譯構建,初次部署往往耗時十五至三十分鐘。延續 Day 3 所提及該專案目前僅鎖定 Git 參照點而非實體映像檔的問題,將深入剖析本地構建映像檔的版本鎖定實踐、Container Station 中實作 GPU 穿透的兩種宣告語法,以及自訂擴充節點與大型模型目錄如何妥善掛載,以確保在套件升級時無須承受重複下載與建置的系統負擔。
本系列所有研究紀錄與實作原始碼同步維護於 GitHub 儲存庫 onprem-ops-30days。
今日驗證之各專案版本原始碼:changedetection-qpkg v0.60.3 與修補版 v0.60.3-1,homepage-qpkg v1.0.7 與修補版 v1.0.8,以及底層架構核心 qpkg-template v0.2.0。
參考資料
HOMEPAGE_ALLOWED_HOSTS 的說明與 v1.0 的變更PUID/PGID、HOMEPAGE_VAR_ 代入,以及對直接掛 socket 的立場shared/template/package_routines 安裝與移除 hook 的寫法