webRcade 內網全本地化離線部署指南

打造私有化內網主機遊戲復刻平台:從容器編排、資料結構本地化到安全上下文配置。


一、 架構運作原理簡述

webRcade 是一個現代化的純前端模擬器平台。它的核心設計將「運行程式(Frontend + WebAssembly Cores)」與「遊戲庫資產(Feed JSON + ROMs + Images)」完全解耦。其運作邏輯如下:

  • 前端與內核: 瀏覽器加載 webRcade 網頁後,會下載對應遊戲平台的 WebAssembly 核心(例如 NES, SNES, Genesis, PlayStation 1 等)。這部分完全在用戶終端瀏覽器中執行。
  • 組態驅動(Feed): 平台透過讀取一個結構化的 JSON 配置文件(稱為 Feed)來動態渲染遊戲選單、封面、背景圖並獲取 ROM 下載位址。

要在純內網或離線環境(Air-gapped)順暢玩轉 webRcade,我們必須建構一個本地的 Web 伺服器,同時託管 webRcade 主程式Feed 配置文件ROM 檔案 以及 圖資產,並解決現代瀏覽器對安全上下文(Secure Context)的嚴格規範。


二、 環境準備與目錄規劃

本指南以獨立 Linux 主機(如 Ubuntu Server)搭配 Docker / Docker Compose 為基礎環境進行配置。首先,我們需在宿主機建立清晰的目錄架構,以便將遊戲檔案與組態持久化掛載。

1. 建立系統目錄

執行以下指令建立專案專用目錄:

sudo mkdir -p /opt/webrcade/content/roms
sudo mkdir -p /opt/webrcade/content/images
sudo mkdir -p /opt/webrcade/ssl
sudo chown -R $USER:$USER /opt/webrcade

2. 目錄結構說明

路徑 掛載/用途 說明
/opt/webrcade/ 專案根目錄 放置 docker-compose.yml 與主要設定。
.../content/ /var/www/html/content 對外暴露的靜態資產根目錄。
.../content/roms/ 本地 ROM 儲存點 依主機分類放置遊戲檔(如 nes/, snes/)。
.../content/images/ 本地圖資儲存點 放置遊戲封面(Thumbnails)與背景圖(Backgrounds)。
.../ssl/ 憑證目錄 放置自簽憑證或本地憑證機構(CA)發行的證書。

⚠️ 重要限制:CORS 跨來源資源共享 若將 ROM 檔與 webRcade 前端分開部署在不同的伺服器或不同的連接埠上,瀏覽器會觸發 CORS 封鎖。官方 Docker 映像檔內建已配置好 Apache 的 CORS Headers,因此強烈建議將所有 ROM 檔與 JSON 設定檔放置於同一個容器的 /content 目錄中掛載,可完美避開跨網域權限問題。


三、 Docker Compose 服務編排

webRcade 官方提供了整合 Apache 的 Docker 映像檔。以下為 docker-compose.yml 完整組態,配置了自簽憑證以啟動安全上下文所需之 HTTPS 服務。

/opt/webrcade/docker-compose.yml 寫入以下內容:

version: '3.8'

services:
  webrcade:
    image: webrcade/webrcade:latest
    container_name: webrcade_local
    restart: unless-stopped
    ports:
      - "8080:80"    # HTTP 埠(可用於本地測試)
      - "8443:443"   # HTTPS 埠(內網跨設備遊玩必備)
    volumes:
      - /opt/webrcade/content:/var/www/html/content
      # 如果有自備內網證書,可取消下方註釋將其掛載至容器內 Apache 預設證書路徑
      # - /opt/webrcade/ssl/server.crt:/etc/ssl/certs/ssl-cert-snakeoil.pem:ro
      # - /opt/webrcade/ssl/server.key:/etc/ssl/private/ssl-cert-snakeoil.key:ro
    environment:
      - TZ=Asia/Taipei

networks:
  default:
    name: webrcade_net

💡 提示:關於官方 Image 的證書機制 webrcade/webrcade 映像檔在啟動時,若未偵測到自訂證書,Apache 會自動啟用作業系統內建的自簽憑證(Snakeoil Cert)。這意味著你無需額外設定即可直接透過 https://<伺服器IP>:8443 建立加密連線。


四、 Feed 配置文件本地化(核心步驟)

這是離線部署最關鍵的一步。webRcade 預設會讀取官方雲端的 Feed,我們必須建立一份完全指向內網 IP 或內網網域的本地 JSON 檔案。

/opt/webrcade/content/local-feed.json 建立以下結構的設定檔(以任天堂 NES 遊戲《超級馬利歐兄弟》為例,假設伺服器內網 IP 為 192.168.1.100):

{
  "title": "我的內網全本地化遊戲庫",
  "description": "家庭內網離線 webRcade 伺服器",
  "thumbnail": "[https://192.168.1.100:8443/content/images/home-thumb.png](https://192.168.1.100:8443/content/images/home-thumb.png)",
  "background": "[https://192.168.1.100:8443/content/images/home-bg.jpg](https://192.168.1.100:8443/content/images/home-bg.jpg)",
  "categories": [
    {
      "title": "任天堂紅白機 (NES)",
      "description": "Nintendo Entertainment System 經典遊戲",
      "thumbnail": "[https://192.168.1.100:8443/content/images/nes-cat-thumb.png](https://192.168.1.100:8443/content/images/nes-cat-thumb.png)",
      "background": "[https://192.168.1.100:8443/content/images/nes-cat-bg.jpg](https://192.168.1.100:8443/content/images/nes-cat-bg.jpg)",
      "applications": [
        {
          "title": "Super Mario Bros.",
          "type": "nes",
          "description": "超級馬利歐兄弟 (1985)",
          "thumbnail": "[https://192.168.1.100:8443/content/images/mario-thumb.png](https://192.168.1.100:8443/content/images/mario-thumb.png)",
          "background": "[https://192.168.1.100:8443/content/images/mario-bg.jpg](https://192.168.1.100:8443/content/images/mario-bg.jpg)",
          "props": {
            "rom": "[https://192.168.1.100:8443/content/roms/nes/mario.nes](https://192.168.1.100:8443/content/roms/nes/mario.nes)"
          }
        }
      ]
    }
  ]
}

⚠️ 注意事項:精確的絕對路徑 webRcade 的模擬器內核在解析 Feed 時,對於 props.rom 等資產欄位,高度建議使用包含 https:// 的完整絕對 URL。請確保將上述範例中的 192.168.1.100:8443 修改為您家裡伺服器的實際內網靜態 IP。


五、 瀏覽器安全上下文(Secure Context)配置

許多人在部署本地 webRcade 時,常遇到「網頁可以打開,但點擊遊戲卻卡死在載入畫面(或黑畫面)」的問題。這通常與 SharedArrayBuffer 機制有關。

1. 為什麼一定要 HTTPS?

為了在高畫質與高複雜度的主機模擬(如 GBA, DOSBox, PS1)中達到 60 FPS 滿速,webRcade 內核採用了多執行緒架構,而這在前端高度依賴 JavaScript 的 SharedArrayBuffer。現代瀏覽器(Chrome, Safari, Edge)基於防範 Spectre 等晶片級安全漏洞,實施了以下硬性限制:

SharedArrayBuffer 僅允許在「安全上下文 (Secure Context)」中啟用。

所謂的安全上下文,指的是存取路徑必須為 localhost127.0.0.1,或者具備有效加密的 HTTPS:// 連線。若僅使用 http://192.168.x.x:8080 跨設備存取,該機制會被強制停用,導致部分內核直接崩潰。

2. 內網 HTTPS 最佳實踐方案

針對家庭 Homelab 環境,有以下三種方案來滿足 HTTPS 需求:

  1. 方案 A:直接信任自簽憑證(最快速) 直接透過 https://192.168.1.100:8443 存取。首次連線時瀏覽器會彈出「您的連線不是安全連線」警告。點選「進階」並選擇「繼續前往 / 信任此網站」。只要手動授權信任,瀏覽器即會將此連線視為安全上下文,SharedArrayBuffer 隨之正常運作。
  2. 方案 B:搭配 mkcert 建立本地信任 CA(最優雅) 在開發機使用 mkcert 工具生成針對內網 IP(如 192.168.1.100)的證書,將 .crt.key 掛載至本專案的 ssl/ 目錄中並對照至 Docker Compose 的 Volume。並在客戶端裝置安裝 mkcert 的根證書,即可實現內網完全不報警的綠色 HTTPS 安全連線。
  3. 方案 C:逆向代理(Reverse Proxy)與自動憑證 若家中已有 Nginx Proxy Manager、Traefik 或 Caddy,且有註冊公網域名並透過內網 DNS(如 AdGuard Home / Pi-hole)實施 DNS Rewrite。可由逆向代理統一配置由 Let’s Encrypt 簽發的正規 SSL 憑證,並將流量導向 webRcade 容器的 8080 埠。

六、 啟動與載入自訂庫步驟

完成上述目錄、容器組態與 Feed JSON 的配置後,即可正式啟動服務:

Step 1. 啟動 Docker 容器

cd /opt/webrcade
docker compose up -d

確認容器狀態正常:docker compose ps

Step 2. 存取 webRcade 前端介面

開啟瀏覽器,輸入您配置好的安全位址: https://<伺服器內網IP>:8443/

Step 3. 載入本地 Feed 設定檔

  1. 進入 webRcade 主介面後,點選畫面中的 「+」號(Add Feed) 按鈕。
  2. 在彈出的 URL 輸入欄位中,精確填入您的本地設定檔網址: https://<伺服器內網IP>:8443/content/local-feed.json
  3. 點選 Add。此時,系統會經由本地 Apache 靜態解析該 JSON,並將您歸檔的遊戲、封面圖資漂亮地渲染在畫面上。點擊遊戲即可開始暢玩!

七、 運維、存檔與完全離線最佳化指南

1. 遊戲存檔(Save States)的內網留存特性

webRcade 官方架構在連網狀態下首選 Dropbox 做為跨端存檔同步媒介。在純內網離線狀態下,雲端同步功能會自動失效。此時所有的遊戲進度、記憶卡存檔與即時存檔(Save States)將會全數保存在當前瀏覽器的 IndexedDB 資料庫 中。

  • 相容性: 只要不更換瀏覽器、不開啟隱私瀏覽(無痕模式),存檔將永久留存。
  • ⚠️ 警告: 請勿輕易執行「清除瀏覽器快取與網站資料」,否則 IndexedDB 內的本機遊戲進度將會被一併抹除。

2. 離線環境下如何編輯 / 擴充遊戲庫?

官方的 Feed 編輯器(editor.webrcade.com)是託管在公網上的 Web App。當遭遇完全無法連通外網的環境時,若要擴充 local-feed.json,有以下兩種因應策略:

  • 策略一:外網預編譯(推薦):在外網環境點擊進入官方編輯器,在完全不連動 Dropbox 的狀態下本地建立好節點,將對應的 ROM URL 寫死為內網格式(例如 https://192.168.1.100/...),接著在編輯器選單點擊 “Export” 匯出 JSON 檔,將該檔案拷貝進內網伺服器的 content 目錄中更換。
  • 策略二:文字編輯器直接操作:因為 Feed JSON 結構高度規律,熟悉 JSON 格式的工程人員可直接使用 VS CodeVim,對 applications 陣列進行複製、貼上並修改標題與檔名,是最有效率的擴充管道。

```