跳轉至

Homepage

Overview

Homepage 係一套開源、現代化嘅自建服務儀表板,主要用嚟將分散喺唔同主機、容器同 SaaS 嘅服務整合到同一個入口。喺 wiki.benhoweb.com 嘅架構入面,Homepage 部署喺 oracle-cloud 嘅虛擬機,並以 docker 容器方式運行,對外網址係 homepage.benhoweb.com。佢唔單止係一個靜態書籤頁,仲支援即時 widget、服務狀態、系統資源、Docker 容器狀態、書籤分類同自訂主題。管理員可以透過 YAML 設定檔定義服務卡片,例如 litellm、Uptime Kuma、Portainer 等,令日常運維唔需要記住大量 IP 同埠。由於 Homepage 只喺內部 cf_network 同 cloudflare-tunnel 溝通,所以主機唔需要將 3000 埠暴露到公網,安全性同可維護性都較高。

Architecture

Homepage 嘅架構可以分為四層:

  1. 邊緣層:Cloudflare DNS 將 homepage.benhoweb.com 指向 Cloudflare Tunnel,唔需要喺 Oracle Cloud 開放入站 80/443 或 3000。
  2. 隧道層:cloudflare-tunnel 容器同 Homepage 容器一齊接入外部 Docker 網絡 cf_network。Tunnel 將公網請求轉去 http://172.21.0.26:3000。
  3. 應用層:Homepage 容器監聽內部 3000 埠,讀取 /app/config 入面嘅 YAML 設定,並產生儀表板。
  4. 資料層:設定檔持久化喺主機 /home/opc/homepage/config,容器重啟或升級都唔會遺失。

呢種設計嘅關鍵係 cf_network 係 external: true,即係由外部預先建立,通常同其他反向代理或 Tunnel 服務共用。Homepage 獲派固定 IP 172.21.0.26,好處係 Tunnel 設定可以寫死目標,唔怕容器重啟後 IP 改變。由於 ports 已被註解,Host 主機嘅防火牆同 Oracle Cloud Security List 都唔需要開放 3000,減少攻擊面。若果冇 HOMEPAGE_ALLOWED_HOSTS,Homepage 會因為 Host Header 唔匹配而回傳 403,所以呢個環境變數係對外網址能否正常運作嘅核心。

Deployment

部署前要準備:Oracle Cloud 實例、已安裝 docker 同 docker-compose、以及一個有 subnet 嘅 cf_network。如果 cf_network 未存在,可以用以下指令建立;若果已經由 Tunnel 建立,就唔好重複建立,並確認 subnet 包含 172.21.0.26。

docker network create --driver bridge --subnet 172.21.0.0/16 cf_network
mkdir -p /home/opc/homepage/config

跟住喺合適目錄建立 docker-compose.yml,內容如下:

version: '3'

networks:
  cf_network:
     external: true

services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    environment:
      - TZ=Asia/Hong_Kong
      # ⚠️ 終極關鍵:補上呢行,放行你嘅新網址!
      - HOMEPAGE_ALLOWED_HOSTS=homepage.benhoweb.com
    volumes:
      - /usr/share/zoneinfo:/usr/share/zoneinfo:ro
      - /home/opc/homepage/config:/app/config  # 掛載剛剛建立的資料夾
    # ports:
    #   - "3000:3000" # 走 Tunnel 內部網路,甚至可以不需要把 3000 埠暴露給公網
    restart: unless-stopped
    networks:
     cf_network:
       ipv4_address: 172.21.0.26

之後執行 docker compose up -d,再用 docker ps 確認 homepage 狀態。最後喺 Cloudflare Tunnel 嘅 Public Hostname 設定,將 homepage.benhoweb.com 指向 http://172.21.0.26:3000。如果 Tunnel 同 Homepage 唔喺同一個 cf_network,就會連唔到;如果 static IP 同網絡 subnet 唔一致,Compose 亦會報錯。

Configuration

Homepage 嘅主要設定檔通常包括 settings.yaml、services.yaml、widgets.yaml、bookmarks.yaml、docker.yaml 等,全部放喺 /home/opc/homepage/config。settings.yaml 控制標題、主題、語言、佈局;services.yaml 定義服務群組同卡片;widgets.yaml 放系統資源、天氣、搜尋等 widget;bookmarks.yaml 管理常用連結。

環境變數方面,TZ=Asia/Hong_Kong 確保日誌同 widget 時間正確;HOMEPAGE_ALLOWED_HOSTS 必須填寫實際對外域名,多個域名用逗號分隔。若果經 proxy 或其他反向代理,亦要將該 Host 加入允許清單。

例如要加入 litellm 服務卡,可以喺 services.yaml 寫:

- LLM:
    - LiteLLM:
        icon: litellm.png
        href: https://litellm.benhoweb.com
        description: LLM Gateway

敏感資訊建議用 HOMEPAGE_VAR_ 開頭嘅環境變數或 .env 檔,唔好直接寫入 YAML。/usr/share/zoneinfo 以唯讀方式掛載,係為咗令容器內時區資料同主機一致,避免 Asia/Hong_Kong 解析出錯。改完設定後,重新整理頁面或 docker compose restart homepage 令新設定生效。

Operations

日常運維包括更新、備份、監控同故障排查。更新映像檔可用:

docker compose pull
docker compose up -d

因為使用 latest,建議先睇 release note,必要時 pin 版本。備份就係將 /home/opc/homepage/config 同 docker-compose.yml 打包;還原時放返原位再 up -d 即可。排查問題先用 docker logs -f homepage,再檢查 cf_network、Tunnel 狀態同 DNS。健康檢查可以用 docker exec homepage wget -qO- http://localhost:3000。

安全方面,唔好開放 3000 到公網,SSH 只限管理 IP,Cloudflare 可加 Access 政策。若果要加 Watchtower 自動更新,要小心 latest 可能帶嚟兼容問題。資源方面,Homepage 本身佔用唔高,但要留意 widget 查詢頻率同外部 API 限額。

FAQ

點解瀏覽器顯示 403 Invalid Host Header?
通常係 HOMEPAGE_ALLOWED_HOSTS 未設定,或者域名串錯。要填 homepage.benhoweb.com,唔要加 https:// 或尾斜線。

點解唔使 ports: 3000:3000?
因為 cloudflare-tunnel 同 Homepage 都喺 cf_network,Tunnel 可以直接用 172.21.0.26:3000 連入,唔需要經主機公網埠。

點解要指定 ipv4_address?
固定 IP 令 Tunnel 設定穩定,唔會因容器重建而改變目標。但前提係 cf_network 有正確 subnet。

可唔可以用 Nginx 代替 Tunnel?
可以,但要自行處理 TLS、反向代理標頭同 HOMEPAGE_ALLOWED_HOSTS,亦可能要開放 443。

設定檔放喺邊?
主機路徑係 /home/opc/homepage/config,容器路徑係 /app/config。

點加新服務?
改 services.yaml,加 href、icon、description,需要 widget 就補 widget 區塊,然後重新載入。

點解要掛載 zoneinfo?
確保容器內時區資料完整,配合 TZ=Asia/Hong_Kong 顯示香港時間。

點備份?
備份 config 資料夾同 compose 檔已經足夠;資料庫類服務要另外備份。

Source

Coverage auto (container scan)