Grass 官方其實有 Linux 版本,所以不需要逆向 Windows 安裝檔。真正的工作是把那個桌面程式變成「沒有畫面、可以掛在伺服器上跑」的容器。本文記錄實際做法與量測結果:每台節點在關掉網頁層之後只要約 58 MB 記憶體。
先釐清三件事
- 官方有 Linux 版:Grass 的更新清單裡就有
linux-x86_64的 deb 安裝檔,桌面版本身是 Tauri 應用(Rust 主程式加上 GTK/WebKit 介面)。 - 沒有 noVNC:容器裡不需要遠端畫面服務,只靠一個虛擬顯示(Xvfb)讓 GTK 能初始化,對外不開任何連接埠。
- 登入只需要一次:第一次用 email 收驗證碼登入之後,把權杖放進環境變數,之後每一台容器都直接沿用,不需要再收驗證碼。
運作原理
Grass 桌面版實際上分成兩層:Rust 主程式負責真正對外的加密通道與帶寬共享,GTK/WebKit 那一層只負責畫介面。既然介面只是殼,把登入狀態先用檔案準備好、再把介面層關掉,共享照樣跑得動。這也是後面能省下大量記憶體的原因。
步驟一:取得權杖(做一次就好)
- 在虛擬顯示上啟動官方桌面程式。
- 用 email 登入,會收到六位數驗證碼(記得先通過人機驗證)。
- 登入成功後,程式的狀態檔會存下 access token、refresh token 與裝置編號。
- 把這三項寫進主機上的 env 檔(權限 600),之後就不再需要互動。
步驟二:建置容器映像
映像刻意「不包含」官方程式的二進位檔:第一次啟動時才向官方網址下載最新安裝檔並解開,這樣映像可以公開分享,也不會因為官方改版而失效。
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
libwebkit2gtk-4.1-0 libgtk-3-0 libappindicator3-1 \
xvfb ca-certificates curl dpkg \
&& rm -rf /var/lib/apt/lists/*
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
VOLUME ["/data"]
ENTRYPOINT ["/entrypoint.sh"]
進入點負責四件事:下載並解開官方安裝檔、把環境變數裡的權杖寫成狀態檔、啟動虛擬顯示、最後啟動主程式。
步驟三:啟動節點
docker run -d --name grass-1 \
--restart unless-stopped \
--env-file /root/grass.env \
-e GRASS_DISPLAY=99 \
-v grass-1:/data \
grass-headless:8.1.0
| 環境變數 | 用途 |
|---|---|
GRASS_ACCESS_TOKEN |
登入權杖,必填 |
GRASS_REFRESH_TOKEN |
換發權杖用,建議一起給 |
GRASS_USER_ID |
帳號編號,建議一起給 |
GRASS_DEVICE_ID |
裝置編號,不給會自動沿用或產生 |
GRASS_DISPLAY |
虛擬顯示編號,同一台主機的多個容器要給不同值 |
GRASS_LITE |
預設 1,啟動後關掉只負責畫介面的網頁層 |
實測數字
| 狀態 | 記憶體 | 說明 |
|---|---|---|
| 預設(含網頁層) | 約 170 到 182 MB | 介面層佔了將近三分之二 |
| 關掉網頁層後 | 約 58 MB | 加密通道與共享完全正常 |
關掉之後仍要保留虛擬顯示:直接砍掉 Xvfb 會讓程式崩潰重啟。程式如果之後需要重新登入,介面層會自己長回來,進入點每隔 30 秒會再關一次,形成自動循環。
怎麼確認有在跑
docker logs grass-1 | grep -E "device registered|opening bridge tunnel"
看到裝置註冊成功與通道開啟就代表上線。之後日誌會定期回報登入狀態;若出現 check-in failed 或持續 503,那是出口線路的問題,換一條出口通常就會恢復。
網路的兩個坑
- 有些主機的 Docker 預設 bridge 網路沒有對外 NAT,容器連 DNS 都查不到。這時要改用 host 網路,或把容器接到有 NAT 的自訂網路。
- 同一台主機跑多個容器時,虛擬顯示的編號必須錯開,否則第二個容器會搶不到顯示資源而互相影響。
常見問題
每一台容器都要重新收驗證碼嗎?
不用。驗證碼只在第一次登入取得權杖時使用,之後所有容器都沿用同一組權杖,各自產生自己的裝置編號。
帳號會不會因為多裝置被判定異常?
同一組帳號可以對應多個住宅 IP,但同一個出口 IP 掛太多裝置風險會上升。實務上建議一台主機一到兩台,其餘分散到不同線路。
可以完全不用介面層嗎?
要做到「連虛擬顯示都不需要」,等於自己實作一個驅動官方 SDK 的主程式。官方沒有公開這套 SDK,需要大量逆向工作且每次改版都得重做,實務上不划算。
映像與相關文章
映像位址:hub.docker.com/r/power14345/grass-headless。
想看其他可以在 Linux 上掛機的項目與實測,可以參考〈掛機項目〉分類。
開始使用(邀請連結)
如果你還沒有帳號,用下面的邀請連結註冊:
https://app.grass.io/register?referralCode=4QMEld52GTf4qEd
註冊後先完成一次 email 驗證碼登入,把權杖放進 env 檔,之後所有容器都直接沿用。
